Comments (4)
Hi @itineric The project has not verified with native compilation yet, any contribution on this field is welcome.
from resteasy-spring-boot.
I got something that works based on your servlet/resteasy-servlet-spring-boot-sample-app.
Hope it helps you to add your lib to the graalvm supported ones: https://www.graalvm.org/native-image/libraries-and-frameworks/
Bean double registration
First you need to declare a BeanRegistrationExcludeFilter because of this code in your library:
https://github.com/resteasy/resteasy-spring-boot/blob/main/servlet/resteasy-servlet-spring-boot-starter/src/main/java/org/jboss/resteasy/springboot/ResteasyBeanProcessorTomcat.java#L57
Why ? the bean registered there is added once during Spring AOT process, then again during the runtime. The error is then The bean 'com.sample.app.configuration.JaxrsApplication' could not be registered. A bean with that name has already been defined and overriding is disabled.
The implementation of the BeanRegistrationExcludeFilter looks like this:
class ServletRegistrationBeanExcludeFilter implements BeanRegistrationExcludeFilter
{
@Override
public boolean isExcludedFromAotProcessing(final RegisteredBean registeredBean)
{
return registeredBean.getBeanClass().equals(ServletRegistrationBean.class);
}
}
Maybe in more complex applications filtering needs to be more specific (not excluding every ServletRegistrationBean from AOT process). But for applications built like the sample, it works.
Another solution may be to keep AOT for that bean registration (thats the point of AOT after all) but then the registration code in https://github.com/resteasy/resteasy-spring-boot/blob/main/servlet/resteasy-servlet-spring-boot-starter/src/main/java/org/jboss/resteasy/springboot/ResteasyBeanProcessorTomcat.java must be excluded from native deliverable (since already done during AOT).
In order for the BeanRegistrationExcludeFilter to be triggered it must be declared in a file named META-INF/spring/aot.factories using the following key: org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter=com.sample.app.configuration.ServletRegistrationBeanExcludeFilter
Reflection hints
When thats done, you then get reflection errors.
Such errors can to be addressed using hints or reflect-config.json files.
I have done it using hints (which spring native will use to generation reflect-config.json).
The class with comments:
import static org.springframework.aot.hint.ExecutableMode.INVOKE;
import java.io.OutputStream;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
@Configuration
@ImportRuntimeHints(NativeImageHints.class)
public class NativeImageHints implements RuntimeHintsRegistrar
{
@Override
public void registerHints(final RuntimeHints hints, final ClassLoader classLoader)
{
try
{
hints.reflection()
// resteasy hints (yous should add them to your lib for now since resteasy is not (yet) a supported graalvm lib)
.registerConstructor(org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages_$logger.class.getConstructor(org.jboss.logging.Logger.class),
INVOKE)
.registerConstructor(org.jboss.resteasy.plugins.validation.i18n.LogMessages_$logger.class.getConstructor(org.jboss.logging.Logger.class),
INVOKE)
.registerField(org.jboss.resteasy.resteasy_jaxrs.i18n.Messages_$bundle.class.getField("INSTANCE"))
.registerField(org.jboss.resteasy.plugins.validation.i18n.Messages_$bundle.class.getField("INSTANCE"))
.registerConstructor(classLoader.loadClass("org.jboss.resteasy.core.ContextServletOutputStream").getDeclaredConstructor(classLoader.loadClass("org.jboss.resteasy.core.ContextParameterInjector"),
OutputStream.class),
ExecutableMode.INVOKE)
// this lib hint
.registerType(classLoader.loadClass("org.jboss.resteasy.springboot.ResteasyApplicationBuilder"),
MemberCategory.INTROSPECT_PUBLIC_METHODS,
MemberCategory.INVOKE_PUBLIC_METHODS)
// app hints (thats only here to make the sample work, must not be included in your lib)
.registerType(JaxrsApplication.class,
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS)
.registerType(org.jboss.resteasy.springboot.common.sample.resources.Echo.class,
MemberCategory.INVOKE_PUBLIC_METHODS)
.registerType(org.jboss.resteasy.springboot.common.sample.resources.Foo.class,
MemberCategory.INVOKE_PUBLIC_METHODS)
.registerType(org.jboss.resteasy.springboot.common.sample.resources.EchoMessage.class,
MemberCategory.INTROSPECT_PUBLIC_METHODS,
MemberCategory.INVOKE_PUBLIC_METHODS);
}
catch (final ClassNotFoundException | NoSuchMethodException | NoSuchFieldException | SecurityException exception)
{
throw new RuntimeHintsException(exception);
}
}
private static class RuntimeHintsException extends RuntimeException
{
private static final long serialVersionUID = 1L;
RuntimeHintsException(final Throwable cause)
{
super(cause);
}
}
}
The build
To build all that natively, thats the profile I added to the pom.xml
<build>
...
...
...
<pluginManagement>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.9.25</version>
<extensions>true</extensions>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<metadataRepository>
<enabled>true</enabled>
</metadataRepository>
<requiredVersion>22.3</requiredVersion>
</configuration>
<executions>
<execution>
<id>add-reachability-metadata</id>
<goals>
<goal>add-reachability-metadata</goal>
</goals>
</execution>
<execution>
<id>build-native</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
<phase>package</phase>
<configuration>
<fallback>false</fallback>
<buildArgs>
<arg>--install-exit-handlers</arg>
</buildArgs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
And the command line: mvn -f servlet/resteasy-servlet-spring-boot-sample-app -Pnative package
that will produce some ./servlet/resteasy-servlet-spring-boot-sample-app/target/resteasy-servlet-spring-boot-sample-app
executable
Resources:
Setup graalvm: https://www.graalvm.org/jdk17/docs/getting-started/
The graalvm manual to understand what I am talking about: https://www.graalvm.org/latest/reference-manual/native-image/metadata/
from resteasy-spring-boot.
@itineric Thanks for sharing the information! I've talked with @jamezp on this topic, who is the leader of the RESTEasy project, and the conclusion is that currently the RESTEasy project hasn't supported native build formally.(In Quarkus it uses resteasy-reactive which officially supports native build). So the native build of RESTEasy projects are not formally supported yet (except the resteasy-reactive
for Quarkus). But any contribution in this field is welcome :D
from resteasy-spring-boot.
Close as answered.
from resteasy-spring-boot.
Related Issues (20)
- unify the license file HOT 1
- update resteasy to `6.2.3.Final`
- add `resteasy-spring-boot-bom` module to manage the dependency versions
- update `springboot` to `3.0.4`
- Spring-boot-starter releases not pushed to maven central repository HOT 5
- ResteasyEmbeddedServletInitializer is not triggered and the app does not get deployed HOT 2
- upgrade wildfly version to `28.0.1.Final`
- update `wildfly.maven.plugin` to `4.1.0.Final`
- Update `springboot` to `3.1.0`
- Update `springframework` to `6.0.10`
- Update `resteasy-spring` to `3.0.3.Final`
- update `spring-boot` to `3.1.3`
- Update Spring to `6.0.11`
- fix the random `InvalidClassTest` failure
- Upgrade `spring-boot` to `3.2.0-M3`
- Upgrade `spring` to `6.1.0-M5`
- Upgrade `resteasy-spring` to `3.1.0.Final`
- Upgrade `spring-boot` to `3.2.1`
- Error booting up with spring boot 3.2.2 RESTEASY013015: could not find the type for bean named HOT 11
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from resteasy-spring-boot.