-
Notifications
You must be signed in to change notification settings - Fork 38.2k
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
Improve GraalVM native support #22968
Comments
Spring Framework can work in GraalVM mode will be excited. And Which spring framework release version do we plan to support GraalVM with native image? 5.X Or ? Thanks |
@guanchao-yang Thanks for your interest but Spring Framework bug tracker is not expected to be used for asking question about the roadmap, this issue is in the 5.x backlog for now, we will share more information when that will be possible. Feel free to show your interest by adding your 👍 to this issue. |
@sdeleuze Thank you very much. |
The focus is now on supporting GraalVM native image out of the box, see #146 and spring-projects/spring-framework#22968 for more details. Closes #198
…ecurity * commit '056b2351a066b1741f7ce50e173c3d667dbf9357': Polishing Polishing Remove manual GraalVM native image configuration Focus GraalVM native image support on spring-projects/spring-framework#22968 Avoid exposing AbstractDsl#initialize in public API Add tests for the R2DBC mapping to simple types Fix documentation Avoid specifying reactor-kotlin-extensions version Fix R2DBC transitive dependencies
More notes. The original comments were written based on the graal commit #818cccb852ec - and the spring boot sample referenced works against that level. Things have moved around in the GA release of graal and it needs updating, that is a work in progress right now (for example delay initialization is now flipped to specify what should be put through build time initialization instead). |
GraalVM has an issue resolving "directory" resources on the classpath (oracle/graal#1108). This may be a blocker for a large class of Spring apps (anything with a component scan, including entity scan). There are also issues with third party tools that do directory traversal in classpath resources (e.g. the issue above was raised by flyway). We are working around it in the @aclement feature jar for now by synthesising |
Thank you everyone for the effort, would be amazing to be able to scale down already working applications into micro-service level applications! |
Perhaps you can tell me if there is a chance to make it working. I'm trying to create a native image for a spring boot application (spring boot 2.1.7 and spring 5.1.9), but got the following exception:
Any idea or workaround ? Do you think it may be a graal issue more than a spring issue ? Thanks, |
@yaakov-berkovitch I have same problem (with |
@yaakov-berkovitch I will shortly be making available the version that works with Boot 2.2.0.M5 and the relevant framework 5.2. (this is with the recent Graal 19.2). I will then keep that up to date through the boot 2.2.0 release. That are changes in Spring I am relying on so I'm not sure I'd be expecting 2.1.7 to be working at the moment. The issue you are showing is a Graal configuration issue. (So not graal, more that the config data being passed to graal for your spring app is not right - exactly what the spring-boot-graal-feature is designed to help with). |
With
The bonus side effect of these changes is to remove as much substitution we can from Similar improvements could potentially be done at Spring Boot and Spring Data level (see for example spring-projects/spring-data-r2dbc#229). The GraalVM feature and documentation will continue to mature on |
This commit also: - Remove Spring Framework substitutions (see spring-projects/spring-framework#22968 (comment) for more details) - Remove web-issue122 sample which seems not relevant anymore - Remove Unnecessary classes and resource configuration from spring-petclinic-jdbc sample - Upgrade to spring Fu 0.4.0-SNAPSHOT - Migrate remaining tests to JUnit 5 - Remove java.lang.management.* from hints - Rename OnlyPresent to OnlyIfPresent See spring-atticgh-138
This commit also: - Remove Spring Framework substitutions (see spring-projects/spring-framework#22968 (comment) for more details) - Remove web-issue122 sample which seems not relevant anymore - Remove Unnecessary classes and resource configuration from spring-petclinic-jdbc sample - Upgrade to spring Fu 0.4.0-SNAPSHOT - Migrate remaining tests to JUnit 5 - Remove java.lang.management.* from hints - Rename OnlyPresent to OnlyIfPresent See gh-138
This commit also: - Remove Spring Framework substitutions (see spring-projects/spring-framework#22968 (comment) for more details) - Remove web-issue122 sample which seems not relevant anymore - Remove Unnecessary classes and resource configuration from spring-petclinic-jdbc sample - Upgrade to spring Fu 0.4.0-SNAPSHOT - Migrate remaining tests to JUnit 5 - Remove java.lang.management.* from hints - Rename OnlyPresent to OnlyIfPresent See gh-138
This commit also: - Remove Spring Framework substitutions (see spring-projects/spring-framework#22968 (comment) for more details) - Remove web-issue122 sample which seems not relevant anymore - Remove Unnecessary classes and resource configuration from spring-petclinic-jdbc sample - Upgrade to spring Fu 0.4.0-SNAPSHOT - Migrate remaining tests to JUnit 5 - Remove java.lang.management.* from hints - Rename OnlyPresent to OnlyIfPresent See spring-atticgh-138
This commit also: - Remove Spring Framework substitutions (see spring-projects/spring-framework#22968 (comment) for more details) - Remove web-issue122 sample which seems not relevant anymore - Remove Unnecessary classes and resource configuration from spring-petclinic-jdbc sample - Upgrade to spring Fu 0.4.0-SNAPSHOT - Migrate remaining tests to JUnit 5 - Remove java.lang.management.* from hints - Rename OnlyPresent to OnlyIfPresent See spring-atticgh-138
native-image
is the command that compiles an application (in our case a Spring application) into a native executable. Configuration of the command can be done via command line options (passed directly or via static side files) or by building aFeature
. In some cases command line options is fine but aFeature
gives maximum flexibility as it is code that participates in thenative-image
execution process and can make dynamic decisions based on the proposed content of the executable.There is a prototype of Spring Boot Feature in this project: https://github.com/spring-projects-experimental/spring-graalvm-native
The prototype is crude and currently uses a lot of fixed information which needs computing but the project proves that once that information is collected (and if we workaround that remaining Graal issue),
native-image
is happy to build Spring projects.There are four kinds of data that are passed by the
Feature
as thenative-image
command executes:spring.factories
spring.components
but also if the system is going to load the bytecode to run asm over it to find something, those class files also need to be available as resources.DirectByteBuffer
. We need to compute any types that need to be delayed for runtime initialization and tell the compiler about them.Some of this data can be computed easily - some types are already annotated (or meta-annotated) with something that indicates we'll need to add them to the reflection/resource lists. (
@Configuration
). The current prototype Feature doesn't do much computation (yet) but you can see the kind of data it is passing (and so needs computing) for all these four kinds of data here: https://github.com/aclement/spring-boot-graal-feature/tree/master/src/main/resources(That is not the minimal set of data, it is just a set that works!)
JDK Proxy usage is allowed in applications being compiled but not dynamic class definition via CGLIB. To avoid the need to do that you can use the new
proxyBeanMethods=false
option. You can see@SpringBootApplication(proxyBeanMethods = false)
in the sample demo app mentioned above. There are other ways we can handle this (annotation processor that generates the proxy at build time).The sample project above is using the
spring-content-indexer
maven plugin to create aspring.components
file for some processing. Not entirely clear this is necessary yet.There is a challenge in drawing the line between framework and boot. A basic version of a feature for framework might scan for
spring.factories
and simply add any listed classes to the reflect/resource lists. The problem is whether that goes far enough to make something work. For example ifspring.factories
is being used to specify bootsEnableAutoConfiguration
then just adding the referred auto-configuration classes isn't enough. If those configuration classes use aConditionalOnClass
check, the types referred to in those conditions also need adding in order for the configuration to behave and framework has no knowledge of that need (only boot does).Going further, and that is what the sample feature above does (as an experiment and to keep the size of the manually maintained json files): What if the
ConditionalOnClass
check was going to fail because at image build time we know the classpath and it isn't there? There is no need to add the auto configuration to the system because it will fail immediately. You can tweak resource files as the image is built (remove unnecessary entries in spring.factories for example). This would reduce image size and make the compiled result even faster. (As an example, boot 2.2 lists ~120 autoconfigurations in spring.factories, 100 of them are immediately going to fail ConditionalOnClass checks). Can both boot and framework have a feature? Sure, but how would you handle this case above when there are two?Maybe keep it dumb initially and measure the impact (framework feature simply adds types referred to in
spring.factories
where the boot feature takes another pass and adds the deeper set of types, no smart exclusion).Dependencies are likely to add their own features over time. For example the sample project above includes its own configuration for
netty
butnetty
now ships their own that we should simply rely on.Also need to decide how to recommend users run
native-image
. It can be run as part of a maven build but you probably want it attached to a separate target because it takes a while (you probably wouldn't want to run it all the time). The sample project above unpacks the boot far jar before running it, that may not be necessary with a more sophisticated feature.Having said all the above... taking a step back there is an alternative to a feature if we wish to go down the compiler plugin route. Annotation processors can produce the more static kind of data (the
json
flat files) that native-image can then pickup. Possibly slightly more advanced than your standard annotation processor as may need to dig deeply through some types to track down some things that need to be included in those files. In this situation we'd build spring itself with these processors and include thejson
files in each built artifact. The files would look a bit like those I linked above but be split up by jar that introduces those entries. The users application would also need to be built with the processor to produce the side files. What all this wouldn't allow is the more dynamic behaviour (excluding certain things as the image is built because you know the complete classpath for the system that is going to run).The text was updated successfully, but these errors were encountered: