Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace build-time initialization by constant field evaluation at build-time #28624

Closed
sdeleuze opened this issue Jun 14, 2022 · 5 comments
Closed
Assignees
Labels
theme: aot An issue related to Ahead-of-time processing type: enhancement A general enhancement
Milestone

Comments

@sdeleuze
Copy link
Contributor

sdeleuze commented Jun 14, 2022

In order to compile to native images and to provide a reasonable footprint, we are currently forced to initialize classes containing ClassUtils#isPresent checks at build time. A meaningful concrete example of that requirement is provided by Spring MVC support that does not compile unless a few classes are initialized at build time, see 2b76a12.

The drawback is that this build time init of WebMvcConfigurationSupport and RestTemplate forces to initialize transitively all classes used in static fields/blocks at build time as well : ClassUtils, SpringProperties, ConcurrentReferenceHashMap. Worse : for other classes with similar pattern, if they contain a static loggers, this will force to initialize Logback at build time which is a dead end in term of compatibility as shown multiple times in Spring Native.

We are working on a middle-long term solution with GraalVM to replace build time init by another mechanism, less viral, with less compatibility issues. But for time being, we need to find a solution to this issue.

A pragmatic solution would be isolate classpath checks in a per module (spring-core, spring-web) class that would be itself init at build time but with no other purpose, removing the risk of viral expension of the classes init at build time. If we take the WebMvcConfigurationSupport use case, we would have something like:

public abstract class ClasspathUtils {

    private static final boolean romePresent;
    private static final boolean jaxb2Present;
    private static final boolean jackson2Present;

    static {
        // ...
    }

    public static boolean isRomePresent() { ... }
    public static boolean isJaxb2Present() { ... }
    public static boolean isJackson2Present() { ... }
    // ...
}

Bonus point, I think I like the fact that we provide reusable methods for classpath checks without arbitrary String parameter.
Implementation would potentially even not use ClassUtils to limit the classes init at build time (not sure what is would use instead, to be discussed, not a blocking point).

Any thoughts @jhoeller @snicoll @bclozel?

@sdeleuze sdeleuze added type: enhancement A general enhancement theme: aot An issue related to Ahead-of-time processing labels Jun 14, 2022
@sdeleuze sdeleuze added this to the 6.0.0-M5 milestone Jun 14, 2022
@sdeleuze sdeleuze self-assigned this Jun 14, 2022
@philwebb
Copy link
Member

Perhaps the @Constant annotation from this branch that we discussed in the past might help? https://github.com/philwebb/scratch-graal-conditions/tree/annotations

@sdeleuze
Copy link
Contributor Author

@philwebb Could you please confirm that this build time initialization of classes is just required for class level @Constant not for field level ones?

@philwebb
Copy link
Member

@sdeleuze correct, that's just for class-level use.

sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Jun 22, 2022
Leverage a subset of @philwebb
https://github.com/philwebb/scratch-graal-conditions/tree/annotations
to set the value of some boolean static field at build time for native
images without leveraging class build-time initialization in order
to avoid related compatibility issues.

See spring-projectsgh-28624
@sdeleuze
Copy link
Contributor Author

sdeleuze commented Jun 22, 2022

Good news, I have been able to leverage the updated @Constant experiment to remove totally build time initialization from Spring Framework 6 (can be used for portfolio projects and Boot as well) while keeping the same benefits in term of build time code removal, see this related WIP branch. Thanks a lot @philwebb!

As soon as GraalVM team provides a builtin solution via the working group @bclozel and I have joined, it would replace this GraalVM feature. That's why I have preferred not introducing a new annotation like @Constant but just target a set of patterns. Since we don't have a real idea of the timeframe, I think the GraalVM feature provide a reasonable path for this transition period.

@sdeleuze sdeleuze changed the title Avoid too much transitive class build time initializations Replace build-time initialization by constant field evaluation at build-time Jun 24, 2022
@sdeleuze
Copy link
Contributor Author

https://github.com/sdeleuze/build-time-constant-fields allows to test it works as expected. Not sure yet if/how we should integrate that in the CI, but probably good enough for this milestone to have such side repository to test the behavior.

Logs printed during the native build allow to identify which fields are set to a constant value at build time.

sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Jun 24, 2022
Leverage a subset of @philwebb
https://github.com/philwebb/scratch-graal-conditions/tree/annotations
to set the value of some boolean static field at build time for native
images without leveraging class build-time initialization in order
to avoid related compatibility issues.

Closes spring-projectsgh-28624
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Jun 27, 2022
As spring-projectsgh-28624 supports only static boolean fields, we still
need a few classes to be initialized at build time.

Such explicit configuration should be in theory avoidable,
so we will work with the GraalVM team to see if this can be
fixed, see for example
oracle/graal#4673
for HttpStatus.

See spring-projectsgh-28624
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Jun 27, 2022
After this commit, KotlinDetector#kotlinPresent is
computed at build time.

See spring-projectsgh-28624
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Jun 27, 2022
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Jun 29, 2022
sdeleuze pushed a commit to sdeleuze/spring-framework that referenced this issue Jun 30, 2022
This is needed as GraalVM 22.2 enabled the module system when building
native-images and all plugins have to participate in it.

See spring-projectsgh-28624
Closes spring-projectsgh-28732
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Jul 4, 2022
This commit makes ConstantFieldFeature
compatible with GraalVM 22.2 while retaining
GraalVM 22.1 compatibility.

See spring-projectsgh-28624
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Jul 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: aot An issue related to Ahead-of-time processing type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants