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

Missing proxy hint when using a simple Spring Data JpaRepository #31050

Closed
mawabokasper opened this issue Aug 15, 2023 · 3 comments
Closed

Missing proxy hint when using a simple Spring Data JpaRepository #31050

mawabokasper opened this issue Aug 15, 2023 · 3 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) theme: aot An issue related to Ahead-of-time processing type: enhancement A general enhancement
Milestone

Comments

@mawabokasper
Copy link

Affects: 6.0.11

I get the com.oracle.svm.core.jdk.UnsupportedFeatureError when using a simple repository.

@Repository
public interface VoucherRepository extends CrudRepository<Voucher, Integer> {
    List<Voucher> findByMsisdn(String msisdn);
}

The only workaround I've found so far is to run the native-image command with an agent, then rebuild my image

$JAVA_HOME/bin/java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image -jar target/graalvm-springdata-jpa-issue-0.0.1-SNAPSHOT.jar

I have a git hub project to reproduce the issue on https://github.com/mawabokasper/graalvm-springdata-jpa-issue
, it's

Stacktrace

15-08-2023 07:28:00.022 [batch-file-1] ERROR o.s.a.i.SimpleAsyncUncaughtExceptionHandler.handleUncaughtException - Unexpected exception occurred invoking async method: public void com.vouchermanagement.thissales.batch.sales.event.SalesBatchFileEventListener.processFile(com.vouchermanagement.thissales.batch.sales.event.SalesBatchFileEvent)
com.oracle.svm.core.jdk.UnsupportedFeatureError: Proxy class defined by interfaces [interface org.hibernate.query.hql.spi.SqmQueryImplementor, interface org.hibernate.query.sqm.internal.SqmInterpretationsKey$InterpretationsKeySource, interface org.hibernate.query.spi.DomainQueryExecutionContext, interface org.hibernate.query.SelectionQuery, interface org.hibernate.query.CommonQueryContract] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:92)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.proxy.DynamicProxySupport.getProxyClass(DynamicProxySupport.java:171)
        at java.base@20.0.2/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:47)
        at java.base@20.0.2/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1034)
        at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:316)
        at jdk.proxy4/jdk.proxy4.$Proxy70.createQuery(Unknown Source)
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:297)
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:242)
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:113)
        at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:234)
        at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:223)
        at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
        at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:148)
        at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:136)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
        at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:72)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
        at jdk.proxy4/jdk.proxy4.$Proxy59.findTop1ByMeterNumberAndStatusIsOrderByDateCreatedAsc(Unknown Source)
        at com.vouchermanagement.thissales.batch.sales.AbstractSalesFileHandler.lambda$processLines$0(AbstractSalesFileHandler.java:74)
        at java.base@20.0.2/java.util.ArrayList.forEach(ArrayList.java:1511)
        at com.vouchermanagement.thissales.batch.sales.AbstractSalesFileHandler.processLines(AbstractSalesFileHandler.java:49)
        at com.vouchermanagement.thissales.batch.sales.AbstractSalesFileHandler.process(AbstractSalesFileHandler.java:40)
        at com.vouchermanagement.thissales.batch.sales.event.SalesBatchFileEventListener.processFile(SalesBatchFileEventListener.java:29)
        at java.base@20.0.2/java.lang.reflect.Method.invoke(Method.java:578)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:756)
        at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
        at java.base@20.0.2/java.util.concurrent.FutureTask.run(FutureTask.java:317)
        at java.base@20.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
        at java.base@20.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
        at java.base@20.0.2/java.lang.Thread.runWith(Thread.java:1636)
        at java.base@20.0.2/java.lang.Thread.run(Thread.java:1623)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:807)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:210)

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Aug 15, 2023
@sdeleuze sdeleuze self-assigned this Aug 15, 2023
@sdeleuze sdeleuze added the theme: aot An issue related to Ahead-of-time processing label Aug 15, 2023
@sdeleuze
Copy link
Contributor

A bit surprised that such sample project fails, but I can indeed reproduce with the project provided.

Adding a META-INF/native-image/proxy-config.json resource file (or the equivalent hint with RuntimeHintsRegistrar) with the following content fixes the issue:

[
  {
    "interfaces":[
      "org.hibernate.query.hql.spi.SqmQueryImplementor",
      "org.hibernate.query.sqm.internal.SqmInterpretationsKey$InterpretationsKeySource",
      "org.hibernate.query.spi.DomainQueryExecutionContext",
      "org.hibernate.query.SelectionQuery",
      "org.hibernate.query.CommonQueryContract"
    ]
  }
]

Since we have only Hibernate interfaces here, it should be provided on https://github.com/oracle/graalvm-reachability-metadata side. @mawabokasper Could you please create an issue (with your existing repro) on the reachability metadata repository?

@sdeleuze sdeleuze closed this as not planned Won't fix, can't repro, duplicate, stale Aug 15, 2023
@sdeleuze sdeleuze added status: declined A suggestion or change that we don't feel we should currently apply for: external-project Needs a fix in external project and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Aug 15, 2023
@mawabokasper
Copy link
Author

Thanx Sébastien

The fix works for me too, appreciate the feedback.

I've opened an issue on the graalvm-reachability-metadata side, oracle/graalvm-reachability-metadata#368

Regards

@sdeleuze
Copy link
Contributor

After a second look, those proxies are created on Spring side by SharedEntityManagerCreator and should be handled on Spring side, so I reopen this issue.

One tricky point is that we get that error because Hibernate reachability metadata for 6.2.0.Final do not contain a proxy-config.json file (here on purpose) while 6.1.1.Final does, hence why this was previous hidden.

@sdeleuze sdeleuze reopened this Aug 16, 2023
@sdeleuze sdeleuze added in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement and removed status: declined A suggestion or change that we don't feel we should currently apply for: external-project Needs a fix in external project labels Aug 16, 2023
@sdeleuze sdeleuze added this to the 6.0.12 milestone Aug 16, 2023
@sdeleuze sdeleuze changed the title com.oracle.svm.core.jdk.UnsupportedFeatureError when using a simple JPARepository Missing proxy hint when using a simple JPARepository Aug 16, 2023
sdeleuze added a commit to sdeleuze/spring-aot-smoke-tests that referenced this issue Aug 16, 2023
The related error happen with Hibernate 6.2 with
custom find methods on non-transactional use cases.
philwebb added a commit to philwebb/upgrading-to-spring-boot-3 that referenced this issue Aug 21, 2023
hinyinlam pushed a commit to hinyinlam/upgrading-to-spring-boot-3 that referenced this issue Sep 14, 2023
hinyinlam pushed a commit to hinyinlam/upgrading-to-spring-boot-3 that referenced this issue Sep 18, 2023
hinyinlam pushed a commit to hinyinlam/upgrading-to-spring-boot-3 that referenced this issue Sep 18, 2023
hinyinlam pushed a commit to hinyinlam/upgrading-to-spring-boot-3 that referenced this issue Sep 18, 2023
hinyinlam pushed a commit to hinyinlam/upgrading-to-spring-boot-3 that referenced this issue Sep 18, 2023
wilkinsona pushed a commit to spring-projects/spring-aot-smoke-tests that referenced this issue Sep 21, 2023
The related error happen with Hibernate 6.2 with
custom find methods on non-transactional use cases.

See gh-188
wilkinsona added a commit to spring-projects/spring-aot-smoke-tests that referenced this issue Sep 21, 2023
@sbrannen sbrannen changed the title Missing proxy hint when using a simple JPARepository Missing proxy hint when using a simple Spring Data JpaRepository Sep 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) theme: aot An issue related to Ahead-of-time processing type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants