helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.49k stars 566 forks source link

[4.x] Sample MP database app fails to compile w/JDK 22 (Native Image) #8863

Open lprimak opened 3 months ago

lprimak commented 3 months ago

Continuation of #8096 JDK 21 works, but JDK 22 doesn't Great progress, but not quite there (yet)

Environment Details


Steps to reproduce

Problem Description

Graal compilaion fails: See https://github.com/helidon-io/helidon/issues/8096#issuecomment-2156813627

lprimak commented 3 months ago

Tested with Helidon 4.0.10 and it still doesn't work

tomas-langer commented 3 months ago

Hello, Helidon 4.x supports GraalVM for Java 21 only. For each major version of Helidon, we choose one version of GraalVM to support for native image (there are no restriction for hotspot mode, of course).

The reason is that with each newer version of GraalVM, there are usually some changes we need to do to our code base, and we currently cannot support multiple versions in parallel.

Although Helidon 4.x supports Java 21+ (i.e. version 21 or higher), we do not claim this support for GraalVM native image, where it must be GraalVM for Java 21 specifically

tomas-langer commented 3 months ago

List of prerequisites: https://helidon.io/docs/v4/about/prerequisites

And the mention of GraalVM version (just in a guide, we need to improve this): https://helidon.io/docs/v4/mp/guides/graalnative

lprimak commented 3 months ago

Understood. However, it would be nice to have some sort of a workaround to get it to work. Also, since there was an issue about running with GraalVM 23-ea I thought that 22 would for sure work :)

tomas-langer commented 2 months ago

We are slowly moving forward, fixing issues where we can. Can you please share the exact error you have with JDK 22? I am currently fixing another (related) issue for Java 22: #8726

Maybe we should try again once that is merged into main.

lprimak commented 2 months ago

I have looked at #8726 however, the failures are different. I'll paste the exact errors when I can

lprimak commented 2 months ago

Please remove "wontfix" label. Thank you

lprimak commented 2 months ago

Just FYI my ultimate goal is to get this to work with native image: https://github.com/flowlogix/native-java/tree/main/helidon/helidon-greeter Compile with mvn package -Phelidon-jpa,native -Djava.preview.release=22

Have been trying over a year with Helidon with no success. Quarkus, plain Weld-SE and Payara Micro (not native image) all work.

lprimak commented 2 months ago
[1/8] Initializing...                                                                                    (5.8s @ 0.17GB)
 Java version: 22.0.2+9, vendor version: GraalVM CE 22.0.2+9.1
 Graal compiler: optimization level: 2, target machine: native
 C compiler: cc (apple, arm64, 15.0.0)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
 4 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
 - io.helidon.integrations.graal.mp.nativeimage.extension.HelidonMpFeature
 - io.helidon.integrations.graal.nativeimage.extension.HelidonReflectionFeature
 - org.eclipse.angus.activation.nativeimage.AngusActivationFeature
------------------------------------------------------------------------------------------------------------------------
 1 experimental option(s) unlocked:
 - '-H:IncludeResourceBundles' (origin(s): 'META-INF/native-image/org.eclipse/yasson/native-image.properties' in 'file:///Users/lprimak/.m2/repository/org/eclipse/yasson/3.0.3/yasson-3.0.3.jar')
------------------------------------------------------------------------------------------------------------------------
Build resources:
 - 12.09GB of memory (75.6% of 16.00GB system memory, determined at start)
 - 8 thread(s) (100.0% of 8 available processor(s), determined at start)
2024.07.25 10:53:58 WARNING io.helidon.common.features.HelidonFeatures Thread[#1,main,5,main]: Feature 'Hibernate' for path 'JPA/Hibernate' has limited support in native image: Experimental support, tested on limited use cases
2024.07.25 10:53:58 WARNING io.helidon.common.features.HelidonFeatures Thread[#1,main,5,main]: Feature 'JTA' for path 'JTA' has limited support in native image: Experimental support, tested on limited use cases
[2/8] Performing analysis...  [*****]                                                                   (65.7s @ 2.49GB)
   25,653 reachable types   (91.1% of   28,158 total)
   37,005 reachable fields  (60.4% of   61,216 total)
  124,888 reachable methods (60.6% of  206,237 total)
    8,401 types,   771 fields, and 13,488 methods registered for reflection
       63 types,    66 fields, and    55 methods registered for JNI access
        5 native libraries: -framework CoreServices, -framework Foundation, dl, pthread, z

Error: Unsupported features in 46 methods
Detailed message:
Error: An object of type 'com.zaxxer.hikari.HikariDataSource$Proxy$_$$_WeldClientProxy' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'com.zaxxer.hikari.HikariDataSource$Proxy$_$$_WeldClientProxy' are persisted in the image heap, add 

    '--initialize-at-build-time=com.zaxxer.hikari.HikariDataSource$Proxy$_$$_WeldClientProxy'

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of 'com.zaxxer.hikari.HikariDataSource$Proxy$_$$_WeldClientProxy' to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.

2) If these objects should not be stored in the image heap, you can use 

    '--trace-object-instantiation=com.zaxxer.hikari.HikariDataSource$Proxy$_$$_WeldClientProxy'

to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 

    '--initialize-at-run-time=<culprit>'

to prevent the instantiation of the object.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=com.zaxxer.hikari.HikariDataSource$Proxy$_$$_WeldClientProxy' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Trace: Object was reached by
  reading field org.jboss.weld.util.LazyValueHolder.value of constant 
    org.jboss.weld.util.LazyValueHolder$1@46aaa0c9: org.jboss.weld.util.LazyValueHolder$1@46aaa0c9
  reading field java.util.concurrent.ConcurrentHashMap$Node.val of constant 
    java.util.concurrent.ConcurrentHashMap$Node@36d4ad4f: Configurator Bean [class com.zaxxer.hikari.HikariDataSource, types: HikariConfig...
  indexing into array java.util.concurrent.ConcurrentHashMap$Node[]@2ca2f3f9: [Ljava.util.concurrent.ConcurrentHashMap$Node;@2ca2f3f9 at index 90
  reading field java.util.concurrent.ConcurrentHashMap.table of constant 
    java.util.concurrent.ConcurrentHashMap@456816ff: {Built-in Bean [jakarta.enterprise.inject.spi.BeanManager] with qualifiers [@Def...
  reading field org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.map of constant 
    org.jboss.weld.util.cache.ReentrantMapBackedComputingCache@3897e4af: {Built-in Bean [jakarta.enterprise.inject.spi.BeanManager] with qualifiers [@Def...
  reading field org.jboss.weld.bean.proxy.ClientProxyProvider.beanTypeClosureProxyPool of constant 
    org.jboss.weld.bean.proxy.ClientProxyProvider@2585729d: Proxy pool with 56 bean type proxies and 0injection point type proxies.
  reading field org.jboss.weld.manager.BeanManagerImpl.clientProxyProvider of constant 
    null
  parsing method org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:693) reachable via the parsing context
    at org.jboss.weld.bean.builtin.InstanceImpl.getBeanInstance(InstanceImpl.java:267)
    at org.jboss.weld.bean.builtin.InstanceImpl$InstanceImplIterator.next(InstanceImpl.java:340)
    at org.jboss.weld.util.collections.WeldCollections.toMultiRowString(WeldCollections.java:102)
    at org.jboss.weld.bean.builtin.InstanceImpl.checkBeanResolved(InstanceImpl.java:259)
    at org.jboss.weld.bean.builtin.InstanceImpl.getHandle(InstanceImpl.java:204)
    at org.jboss.weld.bean.builtin.InstanceImpl.getHandler(InstanceImpl.java:210)
    at root method.(Unknown Source)

Error: An object of type 'jakarta.transaction.Transactional$TxType' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'jakarta.transaction.Transactional$TxType' are persisted in the image heap, add 

    '--initialize-at-build-time=jakarta.transaction.Transactional$TxType'

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of 'jakarta.transaction.Transactional$TxType' to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.

2) If these objects should not be stored in the image heap, you can use 

    '--trace-object-instantiation=jakarta.transaction.Transactional$TxType'

to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 

    '--initialize-at-run-time=<culprit>'

to prevent the instantiation of the object.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=jakarta.transaction.Transactional$TxType' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Trace: Object was reached by
  reading field org.jboss.weld.util.collections.ImmutableMapEntry.value of constant 
    org.jboss.weld.util.collections.ImmutableMapEntry@7d63a16: value=REQUIRED}
  reading field org.jboss.weld.resolution.QualifierInstance.values of constant 
    org.jboss.weld.resolution.QualifierInstance@11886d5: QualifierInstance {annotationClass=interface jakarta.transaction.Transactional, ...
  reading field java.util.HashMap$Node.key of constant 
    java.util.HashMap$Node@72ba81: QualifierInstance {annotationClass=interface jakarta.transaction.Transactional, ...
  indexing into array java.util.HashMap$Node[]@a52a1da: [Ljava.util.HashMap$Node;@a52a1da at index 14
  reading field java.util.HashMap.table of constant 
    java.util.HashMap@4068c404: {QualifierInstance {annotationClass=interface jakarta.transaction.Transactional,...
  reading field java.util.HashSet.map of constant 
    java.util.HashSet@4d0046ff: [QualifierInstance {annotationClass=interface jakarta.transaction.Transactional,...
  reading field org.jboss.weld.resolution.ResolvableBuilder$ResolvableImpl.qualifierInstances of constant 
    org.jboss.weld.resolution.InterceptorResolvableBuilder$InterceptorResolvableImpl@6fd78f04: Types: [class java.lang.Object]; Bindings: [QualifierInstance {annotationClass=i...
  reading field java.util.concurrent.ConcurrentHashMap$Node.key of constant 
    java.util.concurrent.ConcurrentHashMap$Node@1c551ee2: Types: [class java.lang.Object]; Bindings: [QualifierInstance {annotationClass=i...
  indexing into array java.util.concurrent.ConcurrentHashMap$Node[]@49a176a5: [Ljava.util.concurrent.ConcurrentHashMap$Node;@49a176a5 at index 5
  reading field java.util.concurrent.ConcurrentHashMap.table of constant 
    java.util.concurrent.ConcurrentHashMap@73c54ca2: {Types: [class java.lang.Object]; Bindings: [QualifierInstance {annotationClass=...
  reading field org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.map of constant 
    org.jboss.weld.util.cache.ReentrantMapBackedComputingCache@5b6da745: {Types: [class java.lang.Object]; Bindings: [QualifierInstance {annotationClass=...
  reading field org.jboss.weld.resolution.TypeSafeResolver.resolved of constant 
    org.jboss.weld.resolution.TypeSafeInterceptorResolver@61d1d479: ResolverResolved injection points: 2
  reading field org.jboss.weld.manager.BeanManagerImpl.interceptorResolver of constant 
    null
  parsing method org.jboss.weld.manager.BeanManagerImpl.resolveInterceptors(BeanManagerImpl.java:905) reachable via the parsing context
    at root method.(Unknown Source)

Error: An object of type 'jakarta.transaction.Transactional$TxType' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'jakarta.transaction.Transactional$TxType' are persisted in the image heap, add 

    '--initialize-at-build-time=jakarta.transaction.Transactional$TxType'

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of 'jakarta.transaction.Transactional$TxType' to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.

2) If these objects should not be stored in the image heap, you can use 

    '--trace-object-instantiation=jakarta.transaction.Transactional$TxType'

to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 

    '--initialize-at-run-time=<culprit>'

to prevent the instantiation of the object.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=jakarta.transaction.Transactional$TxType' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Trace: Object was reached by
  reading field org.jboss.weld.util.collections.ImmutableMapEntry.value of constant 
    org.jboss.weld.util.collections.ImmutableMapEntry@72d2a759: value=REQUIRED}
  reading field org.jboss.weld.resolution.QualifierInstance.values of constant 
    org.jboss.weld.resolution.QualifierInstance@42fed248: QualifierInstance {annotationClass=interface jakarta.transaction.Transactional, ...
  reading field java.util.HashMap$Node.key of constant 
    java.util.HashMap$Node@7fed0819: QualifierInstance {annotationClass=interface jakarta.transaction.Transactional, ...
  indexing into array java.util.HashMap$Node[]@1b48d04f: [Ljava.util.HashMap$Node;@1b48d04f at index 14
  reading field java.util.HashMap.table of constant 
    java.util.HashMap@38d109bf: {QualifierInstance {annotationClass=interface jakarta.transaction.Transactional,...
  reading field java.util.HashSet.map of constant 
    java.util.HashSet@4ee28b0b: [QualifierInstance {annotationClass=interface jakarta.transaction.Transactional,...
  reading field org.jboss.weld.resolution.ResolvableBuilder$ResolvableImpl.qualifierInstances of constant 
    org.jboss.weld.resolution.InterceptorResolvableBuilder$InterceptorResolvableImpl@da60066: Types: [class java.lang.Object]; Bindings: [QualifierInstance {annotationClass=i...
  reading field java.util.concurrent.ConcurrentHashMap$Node.key of constant 
    java.util.concurrent.ConcurrentHashMap$Node@1058936f: Types: [class java.lang.Object]; Bindings: [QualifierInstance {annotationClass=i...
  indexing into array java.util.concurrent.ConcurrentHashMap$Node[]@49a176a5: [Ljava.util.concurrent.ConcurrentHashMap$Node;@49a176a5 at index 0
  reading field java.util.concurrent.ConcurrentHashMap.table of constant 
    java.util.concurrent.ConcurrentHashMap@73c54ca2: {Types: [class java.lang.Object]; Bindings: [QualifierInstance {annotationClass=...
  reading field org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.map of constant 
    org.jboss.weld.util.cache.ReentrantMapBackedComputingCache@5b6da745: {Types: [class java.lang.Object]; Bindings: [QualifierInstance {annotationClass=...
  reading field org.jboss.weld.resolution.TypeSafeResolver.resolved of constant 
    org.jboss.weld.resolution.TypeSafeInterceptorResolver@61d1d479: ResolverResolved injection points: 2
  reading field org.jboss.weld.manager.BeanManagerImpl.interceptorResolver of constant 
    null
  parsing method org.jboss.weld.manager.BeanManagerImpl.resolveInterceptors(BeanManagerImpl.java:905) reachable via the parsing context
    at root method.(Unknown Source)

Error: An object of type 'jdk.proxy2.$Proxy47' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'jdk.proxy2.$Proxy47' are persisted in the image heap, add 

    '--initialize-at-build-time=java.sql.Connection,java.sql.Wrapper,java.lang.AutoCloseable'

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of [java.sql.Connection, java.sql.Wrapper, java.lang.AutoCloseable] to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.

2) If these objects should not be stored in the image heap, please try to infer from the source code how the culprit object got instantiated.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=java.sql.Connection,java.sql.Wrapper,java.lang.AutoCloseable' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Trace: Object was reached by
  reading static field com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection.CLOSED_CONNECTION
    at <unknown-location>
  registered as read because: null
Error: An object of type 'jdk.proxy4.$Proxy142' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'jdk.proxy4.$Proxy142' are persisted in the image heap, add 

    '--initialize-at-build-time=jakarta.transaction.Transactional,java.lang.annotation.Annotation'

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of [jakarta.transaction.Transactional, java.lang.annotation.Annotation] to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.

2) If these objects should not be stored in the image heap, please try to infer from the source code how the culprit object got instantiated.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=jakarta.transaction.Transactional,java.lang.annotation.Annotation' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Trace: Object was reached by
  reading field org.jboss.weld.util.collections.ImmutableTinySet$Tripleton.element2 of constant 
    org.jboss.weld.util.collections.ImmutableTinySet$Tripleton@42bf0146: [@jakarta.interceptor.Interceptor(), @jakarta.transaction.Transactional(value=SU...
  reading field org.jboss.weld.annotated.slim.unbacked.UnbackedAnnotated.annotations of constant 
    org.jboss.weld.annotated.slim.unbacked.UnbackedAnnotatedType@718ea20e: [UnbackedAnnotatedType] public @Interceptor @Transactional @Priority class com.a...
  reading field org.jboss.weld.injection.producer.BasicInjectionTarget.type of constant 
    org.jboss.weld.injection.producer.BeanInjectionTarget@60207925: InjectionTarget for Interceptor [class com.arjuna.ats.jta.cdi.transactional.Tran...
  reading field io.helidon.integrations.cdi.delegates.DelegatingInjectionTarget.delegate of constant 
    io.helidon.integrations.cdi.delegates.DelegatingInjectionTarget@13e9ea9d: io.helidon.integrations.cdi.delegates.DelegatingInjectionTarget@13e9ea9d
  reading field org.jboss.weld.bean.AbstractClassBean.producer of constant 
    org.jboss.weld.bean.InterceptorImpl@4cf2c3ff: Interceptor [class com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptor...
  reading field java.util.concurrent.ConcurrentHashMap$Node.val of constant 
    java.util.concurrent.ConcurrentHashMap$Node@6969766a: WELD%InterceptorImpl%STATIC_INSTANCE|org.jboss.weld.environment.deployment.WeldD...
  indexing into array java.util.concurrent.ConcurrentHashMap$Node[]@3d3d865f: [Ljava.util.concurrent.ConcurrentHashMap$Node;@3d3d865f at index 361
  reading field java.util.concurrent.ConcurrentHashMap.table of constant 
    java.util.concurrent.ConcurrentHashMap@2088c671: {WELD%InterceptorImpl%STATIC_INSTANCE|org.jboss.weld.environment.deployment.Weld...
  reading field org.jboss.weld.serialization.ContextualStoreImpl.passivationCapableContextuals of constant 
    null
  parsing method org.jboss.weld.serialization.ContextualStoreImpl.putIfAbsent(ContextualStoreImpl.java:107) reachable via the parsing context
    at org.jboss.weld.util.Beans.getIdentifier(Beans.java:715)
    at org.jboss.weld.contexts.SerializableContextualFactory$SerializableContextualHolder.<init>(SerializableContextualFactory.java:100)
    at org.jboss.weld.contexts.SerializableContextualFactory$AbstractSerializableBean.<init>(SerializableContextualFactory.java:167)
    at org.jboss.weld.contexts.SerializableContextualFactory.create(SerializableContextualFactory.java:54)
    at org.jboss.weld.serialization.ContextualStoreImpl.getSerializableContextual(ContextualStoreImpl.java:143)
    at org.jboss.weld.contexts.SerializableContextualInstanceImpl.<init>(SerializableContextualInstanceImpl.java:36)
    at org.jboss.weld.contexts.unbound.DependentContextImpl.addDependentInstance(DependentContextImpl.java:107)
    at org.jboss.weld.contexts.unbound.DependentContextImpl.get(DependentContextImpl.java:66)
    at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:104)
    at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
    at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:706)
    at org.jboss.weld.bean.builtin.InstanceImpl.getBeanInstance(InstanceImpl.java:267)
    at org.jboss.weld.bean.builtin.InstanceImpl$InstanceImplIterator.next(InstanceImpl.java:340)
    at org.jboss.weld.util.collections.WeldCollections.toMultiRowString(WeldCollections.java:102)
    at org.jboss.weld.bean.builtin.InstanceImpl.checkBeanResolved(InstanceImpl.java:259)
    at org.jboss.weld.bean.builtin.InstanceImpl.getHandle(InstanceImpl.java:204)
    at org.jboss.weld.bean.builtin.InstanceImpl.getHandler(InstanceImpl.java:210)
    at root method.(Unknown Source)
lprimak commented 2 months ago

The ultimate goal I have is to have something that does not use Helidon maven parent pom. I have not yet able to get anything to run in native image that uses a database and doesn't use helidon parent

romain-grecourt commented 2 months ago

The ultimate goal I have is to have something that does not use Helidon maven parent pom. I have not yet able to get anything to run in native image that uses a database and doesn't use helidon parent

This shouldn't be a challenge.