Skip to content
This repository has been archived by the owner on Feb 23, 2023. It is now read-only.

Introduce a spring-data-mongodb sample #25

Closed
olivierboudet opened this issue Dec 7, 2019 · 6 comments
Closed

Introduce a spring-data-mongodb sample #25

olivierboudet opened this issue Dec 7, 2019 · 6 comments
Assignees
Labels
type: compatibility Native image compatibility issue
Milestone

Comments

@olivierboudet
Copy link
Contributor

Hi,

I am trying to build a minimal sample with spring-data-mongodb. The project is here : https://github.com/olivierboudet/spring-graal-native/tree/master/spring-graal-native-samples/spring-data-mongodb

I encounter this error when running native-image :

Unpacking spring-data-mongodb-0.0.1-SNAPSHOT.jar

Compile
[clr:6070]    classlist:   7,894.53 ms
 ____             _               _____          _                  
/ ___| _ __  _ __(_)_ __   __ _  |  ___|__  __ _| |_ _   _ _ __ ___ 
\___ \| '_ \| '__| | '_ \ / _` | | |_ / _ \/ _` | __| | | | '__/ _ \
 ___) | |_) | |  | | | | | (_| | |  _|  __/ (_| | |_| |_| | | |  __/
|____/| .__/|_|  |_|_| |_|\__, | |_|  \___|\__,_|\__|\__,_|_|  \___|
      |_|                 |___/                                     

Use -Dverbose=true on native-image call to see more detailed information from the feature
Remove unused config = true
[clr:6070]        (cap):     831.52 ms
Found #312 types in static reflection list to register
Skipping #232 types not on the classpath
Attempting proxy registration of #24 proxies
Skipped registration of #18 proxies - relevant types not on classpath
[clr:6070]        setup:   1,994.43 ms
Registering resources - #61 patterns
Processing META-INF/spring.factories files...
Adding all the classes for this key: org.springframework.data.repository.core.support.RepositoryFactorySupport
Fatal error: java.lang.IllegalStateException: java.lang.IllegalStateException: Problem registering member <init> for reflective access on type class org.springframework.data.mongodb.repository.support.MongoRepositoryFactory
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:600)
	at java.base/java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1006)
	at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:462)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:315)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:454)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:115)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:479)
Caused by: java.lang.IllegalStateException: Problem registering member <init> for reflective access on type class org.springframework.data.mongodb.repository.support.MongoRepositoryFactory
	at org.springframework.graal.support.ReflectionHandler.addAccess(ReflectionHandler.java:361)
	at org.springframework.graal.support.ResourcesHandler.registerTypeReferencedBySpringFactoriesKey(ResourcesHandler.java:399)
	at org.springframework.graal.support.ResourcesHandler.processSpringFactory(ResourcesHandler.java:425)
	at org.springframework.graal.support.ResourcesHandler.processSpringFactories(ResourcesHandler.java:326)
	at org.springframework.graal.support.ResourcesHandler.register(ResourcesHandler.java:109)
	at org.springframework.graal.support.SpringFeature.beforeAnalysis(SpringFeature.java:84)
	at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$7(NativeImageGenerator.java:669)
	at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:63)
	at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:669)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:530)
	at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:445)
	at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
Caused by: java.lang.NoSuchMethodException: org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.<init>()
	at java.base/java.lang.Class.getConstructor0(Class.java:3349)
	at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2553)
	at com.oracle.svm.hosted.config.ReflectionRegistryAdapter.registerConstructor(ReflectionRegistryAdapter.java:137)
	at org.springframework.graal.support.ReflectionHandler.addAccess(ReflectionHandler.java:356)
	... 16 more
Error: Image build request failed with exit status 1

I tried to add some reflection hint to reflect.json like this :

{
		"name": "org.springframework.data.mongodb.repository.support.MongoRepositoryFactory",
		"allDeclaredConstructors": true,
		"allDeclaredMethods": true,
		"methods": [
			{
				"name": "<init>",
				"parameterTypes": [
					"org.springframework.data.mongodb.core.MongoOperations"
				]
			}
		]
	}

I modified the class Type.java of the feature to add some logs and I am surprised to see that the parameters of the constructor is not detected.
This is the change I did :

+++ b/spring-graal-native-feature/src/main/java/org/springframework/graal/type/Type.java
@@ -1308,9 +1308,15 @@ public class Type {
 
        public boolean hasOnlySimpleConstructor() {
                boolean hasCtor = false;
+               SpringFeature.log("type " + node.name);
                List<MethodNode> methods = node.methods;
                for (MethodNode mn: methods) {
+                       SpringFeature.log("method " + mn.name);
+                       if (mn.parameters!=null) {
+                               SpringFeature.log("method params " + mn.parameters.size());
+                       }
                        if (mn.name.equals("<init>")) {
+
                                if (mn.parameters!=null && mn.parameters.size()!=0) {
                                        return false;
                                } else {
@@ -1318,6 +1324,9 @@ public class Type {
                                }
                        }
                }
+
+               SpringFeature.log("hasOnlySimpleConstructor " + hasCtor);
+
                return hasCtor;
        }

And this is the log when running native-image : the parameters are always null and hasOnlySimpleConstructor is always true for all classes.

type org/springframework/data/mongodb/repository/support/MongoRepositoryFactory
method <init>
method getRepositoryBaseClass
method getRepositoryFragments
method getTargetRepository
method getQueryLookupStrategy
method getEntityInformation
method getEntityInformation
method getEntityInformation
method access$000
method <clinit>
hasOnlySimpleConstructor true

@sdeleuze sdeleuze added status: waiting-for-triage An issue we've not yet triaged or decided on type: compatibility Native image compatibility issue labels Dec 7, 2019
@aclement
Copy link
Contributor

aclement commented Jan 8, 2020

I suspect you are trying this on master of the project? The 19.3 branch includes fixes for some of this I think, I'm going to try your sample with the current branch.

@aclement aclement removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 8, 2020
@aclement aclement self-assigned this Jan 8, 2020
@sdeleuze sdeleuze added this to the v0.7.0 milestone Jan 20, 2020
@olivierboudet
Copy link
Contributor Author

I updated my sample using graal 19.3.1 (olivierboudet@56045f9). It's a littler better, I managed to get a native image.
But :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
Feb 04, 2020 11:07:56 PM org.springframework.boot.SpringApplication reportFailure
SEVERE: Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.example.springdatamongodb.SpringDataMongodbApplication]; nested exception is java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.autoconfigure.data.RepositoryType]
	at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:814)
	at java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:801)
	at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:771)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:188)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:325)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:242)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
	at com.example.springdatamongodb.SpringDataMongodbApplication.main(SpringDataMongodbApplication.java:10)
Caused by: java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.autoconfigure.data.RepositoryType]
	at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:327)
	at org.springframework.core.type.classreading.MergedAnnotationReadingVisitor.visitEnum(MergedAnnotationReadingVisitor.java:104)
	at org.springframework.core.type.classreading.MergedAnnotationReadingVisitor.visitEnum(MergedAnnotationReadingVisitor.java:80)
	at org.springframework.asm.ClassReader.readElementValue(ClassReader.java:2846)
	at org.springframework.asm.ClassReader.readElementValues(ClassReader.java:2765)
	at org.springframework.asm.ClassReader.accept(ClassReader.java:572)
	at org.springframework.asm.ClassReader.accept(ClassReader.java:400)
	at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:50)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:86)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:73)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81)
	at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:686)
	at org.springframework.context.annotation.ConfigurationClassParser.asSourceClasses(ConfigurationClassParser.java:662)
	at org.springframework.context.annotation.ConfigurationClassParser.access$800(ConfigurationClassParser.java:109)
	at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:806)
	... 16 more
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.autoconfigure.data.RepositoryType
	at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:60)
	at java.lang.Class.forName(DynamicHub.java:1197)
	at org.springframework.util.ClassUtils.forName(ClassUtils.java:277)
	at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:317)
	... 31 more

@aclement
Copy link
Contributor

aclement commented Feb 5, 2020

How should I check the app is working? I see no controller to ping or command line output indicating success - is it just by virtue of starting without error? By adding RepositoryType to the manual configuration (just to test if it was computed, things would behave), the image seems ok but I don't know whether it is doing what it is supposed to:

12:47:16.899 [main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate - Bootstrapping Spring Data repositories in DEFAULT mode.
12:47:16.899 [main] DEBUG org.springframework.data.repository.config.RepositoryConfigurationDelegate - Scanning for repositories in packages com.example.springdatamongodb.
12:47:16.899 [main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 0ms. Found 0 repository interfaces.
12:47:16.918 [main] INFO org.mongodb.driver.cluster - Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
12:47:16.918 [main] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING}]
Feb 05, 2020 12:47:16 PM org.springframework.boot.StartupInfoLogger logStarted
INFO: Started SpringDataMongodbApplication in 0.336 seconds (JVM running for 0.376)

@olivierboudet
Copy link
Contributor Author

Thanks. Yes, for the first try, I limited the test to just a startup without error.
I will add some repositories and controllers to test the read/write in mongodb.

Please, can you show me changes you did to add the RepositoryType to the manual configuration ?

@aclement
Copy link
Contributor

aclement commented Feb 5, 2020

I created a simple reflect-config.json:

[
	{
		"name": "org.springframework.boot.autoconfigure.data.RepositoryType",
		"allDeclaredConstructors": true,
		"allDeclaredMethods": true
	}
]

then i specified that in the compile.sh script:

-H:ReflectionConfigurationFiles=/blahblah/spring-graal-native/spring-graal-native-samples/spring-data-mongodb/reflect-config.json \

@sdeleuze sdeleuze modified the milestones: v0.7.0, v0.8.0 May 15, 2020
@sdeleuze sdeleuze modified the milestones: v0.8.0, v0.7.1 May 26, 2020
@sdeleuze sdeleuze assigned christophstrobl and sdeleuze and unassigned aclement May 26, 2020
@sdeleuze sdeleuze modified the milestones: v0.7.1, v0.7.0 May 26, 2020
@sdeleuze sdeleuze changed the title Trying to build a sample with spring-data-mongodb Introduce a spring-data-mongodb sample May 26, 2020
sdeleuze pushed a commit to sdeleuze/spring-native that referenced this issue May 26, 2020
sdeleuze added a commit to sdeleuze/spring-native that referenced this issue May 26, 2020
This commmit also switches the sample to a regular Boot application
and renames the sample to spring-data-mongodb.

See spring-atticgh-25
sdeleuze added a commit to sdeleuze/spring-native that referenced this issue May 26, 2020
sdeleuze added a commit to sdeleuze/spring-native that referenced this issue May 26, 2020
This commit also switches the sample to a regular Boot application
and renames the sample to spring-data-mongodb.

See spring-atticgh-25
sdeleuze pushed a commit to sdeleuze/spring-native that referenced this issue May 26, 2020
sdeleuze added a commit to sdeleuze/spring-native that referenced this issue May 26, 2020
This commit also switches the sample to a regular Boot application.

See spring-atticgh-25
@aclement
Copy link
Contributor

The spring-data-mongodb sample is now live and working ( https://github.com/spring-projects-experimental/spring-graalvm-native/tree/master/spring-graalvm-native-samples/spring-data-mongodb) . I tried the current state of the feature against Oliviers original project and it did start cleanly for me (simple project with just the mongo dependency - that wasn't working before). So I think we're in much better shape. Will every feature work? Perhaps not but we have a good starting point to work from.

dsyer pushed a commit to scratches/spring-graalvm-native that referenced this issue Sep 23, 2020
dsyer pushed a commit to scratches/spring-graalvm-native that referenced this issue Sep 23, 2020
This commit also switches the sample to a regular Boot application.

See spring-atticgh-25
dsyer pushed a commit to scratches/spring-graalvm-native that referenced this issue Sep 23, 2020
dsyer pushed a commit to scratches/spring-graalvm-native that referenced this issue Sep 23, 2020
This commit also switches the sample to a regular Boot application.

See spring-atticgh-25
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: compatibility Native image compatibility issue
Development

No branches or pull requests

4 participants