After using the implementation of amazon sdk to interact with amazon rekognition and amazon comprehend tools, works very well on dev (mvn compile quarkus:dev), but crashes trying to make the native compilation of REST Web Service, developed using the following technologies;
GraalVM CE 22.0.0.2.
Quarkus Framework (quarkus-bom. io.quarkus.platform) 2.8.0.Final.
O.S.: Windows 10 Enterprise LTSC.
MAVEN: 3.8.4.
AWS SDK: 1.12.198.
POM file:
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lum</groupId>
<artifactId>casccb</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.release>11</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>2.8.0.Final</quarkus.platform.version>
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-bom</artifactId>
<version>1.12.198</version>
<!-- <version>1.11.1000</version> -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<!-- -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<!-- -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<!-- Hibernate ORM Panache -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<!-- JDBC Driver -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
<!-- <artifactId>quarkus-jdbc-oracle</artifactId> -->
</dependency>
<!-- IO Commons -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- AWS sdk core -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
</dependency>
<!-- AWS s3 client -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
<!-- AWS rekognition client -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-rekognition</artifactId>
</dependency>
<!-- AWS comprehend client-->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-comprehend</artifactId>
</dependency>
<!-- quarkus -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-apache-httpclient</artifactId>
</dependency>
<!-- OpenAPI -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-mockito</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
This is the output shown by the recommended x64 Native Tools Command Prompt for VS 2022. Executing "mvn package -Pnative -DskipTests=true"
Error: Unsupported features in 2 methods
Detailed message:
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. To see how this object got instantiated use --trace-object-instantiation=java.util.Random. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Trace: Object was reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$EqualJitterBackoffStrategy.random of
constant com.amazonaws.retry.PredefinedBackoffStrategies$EqualJitterBackoffStrategy@2ab7cc8 reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy.equalJitterBackoffStrategy of
constant com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy@6a24d5e3 reached by
reading field com.amazonaws.retry.RetryPolicy.backoffStrategy of
constant com.amazonaws.retry.RetryPolicy@5dc90142 reached by
scanning method com.amazonaws.ClientConfiguration.<init>(ClientConfiguration.java:155)
Call path from entry point to com.amazonaws.ClientConfiguration.<init>(ClientConfiguration):
no path found from entry point to target method
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. To see how this object got instantiated use --trace-object-instantiation=java.util.Random. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Trace: Object was reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$FullJitterBackoffStrategy.random of
constant com.amazonaws.retry.PredefinedBackoffStrategies$FullJitterBackoffStrategy@2aa3a8a2 reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy.fullJitterBackoffStrategy of
constant com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy@6a24d5e3 reached by
reading field com.amazonaws.retry.RetryPolicy.backoffStrategy of
constant com.amazonaws.retry.RetryPolicy@5dc90142 reached by
scanning method com.amazonaws.ClientConfiguration.<init>(ClientConfiguration.java:155)
Call path from entry point to com.amazonaws.ClientConfiguration.<init>(ClientConfiguration):
no path found from entry point to target method
com.oracle.svm.core.util.UserError$UserException: Unsupported features in 2 methods
Detailed message:
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. To see how this object got instantiated use --trace-object-instantiation=java.util.Random. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Trace: Object was reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$EqualJitterBackoffStrategy.random of
constant com.amazonaws.retry.PredefinedBackoffStrategies$EqualJitterBackoffStrategy@2ab7cc8 reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy.equalJitterBackoffStrategy of
constant com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy@6a24d5e3 reached by
reading field com.amazonaws.retry.RetryPolicy.backoffStrategy of
constant com.amazonaws.retry.RetryPolicy@5dc90142 reached by
scanning method com.amazonaws.ClientConfiguration.<init>(ClientConfiguration.java:155)
Call path from entry point to com.amazonaws.ClientConfiguration.<init>(ClientConfiguration):
no path found from entry point to target method
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. To see how this object got instantiated use --trace-object-instantiation=java.util.Random. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Trace: Object was reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$FullJitterBackoffStrategy.random of
constant com.amazonaws.retry.PredefinedBackoffStrategies$FullJitterBackoffStrategy@2aa3a8a2 reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy.fullJitterBackoffStrategy of
constant com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy@6a24d5e3 reached by
reading field com.amazonaws.retry.RetryPolicy.backoffStrategy of
constant com.amazonaws.retry.RetryPolicy@5dc90142 reached by
scanning method com.amazonaws.ClientConfiguration.<init>(ClientConfiguration.java:155)
Call path from entry point to com.amazonaws.ClientConfiguration.<init>(ClientConfiguration):
no path found from entry point to target method
at com.oracle.svm.core.util.UserError.abort(UserError.java:87)
at com.oracle.svm.hosted.FallbackFeature.reportAsFallback(FallbackFeature.java:233)
at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:759)
at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:529)
at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:488)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:403)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:569)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:122)
at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:599)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: Unsupported features in 2 methods
Detailed message:
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. To see how this object got instantiated use --trace-object-instantiation=java.util.Random. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Trace: Object was reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$EqualJitterBackoffStrategy.random of
constant com.amazonaws.retry.PredefinedBackoffStrategies$EqualJitterBackoffStrategy@2ab7cc8 reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy.equalJitterBackoffStrategy of
constant com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy@6a24d5e3 reached by
reading field com.amazonaws.retry.RetryPolicy.backoffStrategy of
constant com.amazonaws.retry.RetryPolicy@5dc90142 reached by
scanning method com.amazonaws.ClientConfiguration.<init>(ClientConfiguration.java:155)
Call path from entry point to com.amazonaws.ClientConfiguration.<init>(ClientConfiguration):
no path found from entry point to target method
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. To see how this object got instantiated use --trace-object-instantiation=java.util.Random. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Trace: Object was reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$FullJitterBackoffStrategy.random of
constant com.amazonaws.retry.PredefinedBackoffStrategies$FullJitterBackoffStrategy@2aa3a8a2 reached by
reading field com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy.fullJitterBackoffStrategy of
constant com.amazonaws.retry.PredefinedBackoffStrategies$SDKDefaultBackoffStrategy@6a24d5e3 reached by
reading field com.amazonaws.retry.RetryPolicy.backoffStrategy of
constant com.amazonaws.retry.RetryPolicy@5dc90142 reached by
scanning method com.amazonaws.ClientConfiguration.<init>(ClientConfiguration.java:155)
Call path from entry point to com.amazonaws.ClientConfiguration.<init>(ClientConfiguration):
no path found from entry point to target method
at com.oracle.graal.pointsto.constraints.UnsupportedFeatures.report(UnsupportedFeatures.java:129)
at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:756).
P.S.: Few minutes ago applying this;
<properties>
<quarkus.package.type>native</quarkus.package.type>
<quarkus.native.additional-build-args>
--initialize-at-run-time=com.amazonaws.ClientConfiguration\
com.amazonaws.retry.PredefinedBackoffStrategies$EqualJitterBackoffStrategy\
com.amazonaws.retry.PredefinedBackoffStrategies$FullJitterBackoffStrategy
</quarkus.native.additional-build-args>
</properties>
It avoids several Exceptions... But it still complaining as follows;
[ERROR] Failed to execute goal io.quarkus.platform:quarkus-maven-plugin:2.8.0.Final:build (default) on project casccb: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR] [error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: io.quarkus.deployment.pkg.steps.NativeImageBuildStep$ImageGenerationFailureException: Image generation failed. Exit code: 1
[ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.imageGenerationFailed(NativeImageBuildStep.java:396)
[ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build(NativeImageBuildStep.java:237)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR] at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:925)
[ERROR] at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
[ERROR] at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
[ERROR] at java.base/java.lang.Thread.run(Thread.java:829)
[ERROR] at org.jboss.threads.JBossThread.run(JBossThread.java:501).
Hope you can help me to figure out how to solve this situation.
Thanks in advance.
JJ
This is one of the case where you need a Quarkus extension to get things working in native.
We have extensions for Amazon Services in the Quarkiverse: https://github.com/quarkiverse/quarkus-amazon-services .
Once you have the extensions around, you can either use its config infrastructure and inject CDI beans or you can also do things all by yourself.
And you can find the documentation about these extensions here: https://quarkiverse.github.io/quarkiverse-docs/quarkus-amazon-services/dev/index.html .