Closed jhiemer closed 9 years ago
So the fundamental issue seems to be that the Spring Cloud Connector documentation strongly suggest to inherit from a base class, which in Johannes' case created an insufficient MongoDB infrastructure setup in turn leading to assumed bugs in Spring Data REST.
After a bit of discussion we came to quite a few observations:
DataSource
or MongoDbFactory
then drags attention away form other infrastructure parts that might be set up from the library specific configuration. The basic conflict arises is "Should I extend AbstractMongoConfiguration
or AbstractCloudConfig
?". Shouldn't the cloud components rather be simply injectable, so that users can use the injected artifacts to customize the library specific hooks?ServiceConnectionFactory
feels wird at is pulls together quite unrelated libraries (JDBC, MongoDB, Redis). Whenever a user decides to work with AbstractCloudConfiguration
she will be required to have both Spring Data MongoDB and Spring Data Redis on the classpath, whether you use MongoDB or Redis or not.A quick comment:
Whenever a user decides to work with AbstractCloudConfiguration she will be required to have both Spring Data MongoDB and Spring Data Redis on the classpath, whether you use MongoDB or Redis or not.
Not really. Even though the class refers to all connector types, all those types have optional dependency. Specifically, an user app won't need to put Spring Data Redis unless it is using Redis. See Spring Sendgrid for example; it doesn't have dependency on Spring Data or Spring AMQP.
@ramnivas are you sure about that? If I remember correctly, I had to include the Redis dependencies of Spring, because of a ClassNotFoundException during application startup. The project is using Mongo, RabbitMq and Postgres, so these dependencies were use anyway.
I just did the following:
spring-cloud-spring-service-connector
as dependencyAbstractCloudConfig
main
-method of the Application
classI get this exception startup:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.2.1.RELEASE)
2015-01-26 09:54:51.163 INFO 35248 --- [ main] demo.ClassLoadingApplication : Starting ClassLoadingApplication on Serendipity-6.local with PID 35248 (/Users/olivergierke/Documents/workspace/class-loading/target/classes started by olivergierke in /Users/olivergierke/Documents/workspace/class-loading)
2015-01-26 09:54:51.195 INFO 35248 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@480bdb19: startup date [Mon Jan 26 09:54:51 CET 2015]; root of context hierarchy
2015-01-26 09:54:51.223 INFO 35248 --- [ main] .b.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: [file:/Users/olivergierke/Documents/workspace/class-loading/target/classes/, file:/Users/olivergierke/.m2/repository/org/springframework/cloud/spring-cloud-spring-service-connector/1.1.0.RELEASE/spring-cloud-spring-service-connector-1.1.0.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/springframework/cloud/spring-cloud-core/1.1.0.RELEASE/spring-cloud-core-1.1.0.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/springframework/spring-context/4.1.4.RELEASE/spring-context-4.1.4.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/springframework/spring-aop/4.1.4.RELEASE/spring-aop-4.1.4.RELEASE.jar, file:/Users/olivergierke/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar, file:/Users/olivergierke/.m2/repository/org/springframework/spring-beans/4.1.4.RELEASE/spring-beans-4.1.4.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/springframework/spring-expression/4.1.4.RELEASE/spring-expression-4.1.4.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/springframework/boot/spring-boot-starter/1.2.1.RELEASE/spring-boot-starter-1.2.1.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/springframework/boot/spring-boot/1.2.1.RELEASE/spring-boot-1.2.1.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.2.1.RELEASE/spring-boot-autoconfigure-1.2.1.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/springframework/boot/spring-boot-starter-logging/1.2.1.RELEASE/spring-boot-starter-logging-1.2.1.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.8/jcl-over-slf4j-1.7.8.jar, file:/Users/olivergierke/.m2/repository/org/slf4j/slf4j-api/1.7.8/slf4j-api-1.7.8.jar, file:/Users/olivergierke/.m2/repository/org/slf4j/jul-to-slf4j/1.7.8/jul-to-slf4j-1.7.8.jar, file:/Users/olivergierke/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.8/log4j-over-slf4j-1.7.8.jar, file:/Users/olivergierke/.m2/repository/ch/qos/logback/logback-classic/1.1.2/logback-classic-1.1.2.jar, file:/Users/olivergierke/.m2/repository/ch/qos/logback/logback-core/1.1.2/logback-core-1.1.2.jar, file:/Users/olivergierke/.m2/repository/org/springframework/spring-core/4.1.4.RELEASE/spring-core-4.1.4.RELEASE.jar, file:/Users/olivergierke/.m2/repository/org/yaml/snakeyaml/1.14/snakeyaml-1.14.jar]
2015-01-26 09:54:51.231 ERROR 35248 --- [ main] o.s.boot.SpringApplication : Application startup failed
java.lang.NoClassDefFoundError: org/springframework/data/mongodb/MongoDbFactory
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2688)
at java.lang.Class.getDeclaredMethods(Class.java:1962)
at org.springframework.core.type.StandardAnnotationMetadata.hasAnnotatedMethods(StandardAnnotationMetadata.java:129)
at org.springframework.context.annotation.ConfigurationClassUtils.isLiteConfigurationCandidate(ConfigurationClassUtils.java:157)
at org.springframework.context.annotation.ConfigurationClassUtils.isConfigurationCandidate(ConfigurationClassUtils.java:125)
at org.springframework.context.annotation.ConfigurationClassParser.processMemberClasses(ConfigurationClassParser.java:312)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:243)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:226)
at org.springframework.context.annotation.ConfigurationClassParser.processMemberClasses(ConfigurationClassParser.java:314)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:243)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:226)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:193)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:163)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:306)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:239)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:606)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:462)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
at demo.ClassLoadingApplication.main(ClassLoadingApplication.java:17)
Caused by: java.lang.ClassNotFoundException: org.springframework.data.mongodb.MongoDbFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 25 common frames omitted
If I add MongoDB, the exception changes to complain about Spring AMQP's ConnectionFactory
missing. So it's not really the JVM causing the issue but Spring trying to analyze the configuration class.
Could it be that the issue just doesn't appear on CF environments as it implicitly has the relevant libraries on the classpath anyway?
Exactly the same I had with Redis support.
Which JDK version are you using? I have been reported some sighting of this issue with specific version(s) of JDK (older version of Java 8), but could never reproduce with the latest. It could be how eagerly each JDK's classloader demands types. In fact the reason for AbstractCloudConfig
containing ServiceConnectionFactory
and thus requiring users to to use connectionFactory().mongoDbFactory()
instead of a more convenient mongoDbFactory()
is Spring's proxy creation required me to add an extra level of indirection to avoid loading classes other than that app needs.
Could one of you try to compile Spring Music and Spring Sendgrid? I had discussed an alternative possibilities with @scottfrederick should the issue arise again. So knowing a reproducible project + JDK version will help.
See #88
Newly deployed application java.lang.NoClassDefFoundError: org/springframework/amqp/rabbit/connection/ConnectionFactory
this is definitely an issue.
I'm also seeing this with Oracle JDK 1.8.0_25 and spring-cloud 1.0.0.RELEASE.
Closing this as the resolution is a duplicate of #88.
Hi, I recently opened two issues in Spring Data Rest [0], [1], which are a result of a missing configuration of the mappingBasePackages for the mongoMappingContext. I could fix this after a lot debugging, until I found the origin of the problem, with [3]. The question for me here is: is this the kings road or should there be some improvements in Spring Data Rest (@olivergierke) or in the Cloud Connectors.
[0] https://jira.spring.io/browse/DATAREST-442 [1] https://jira.spring.io/browse/DATAREST-443 [3] https://gist.github.com/jhiemer/5f743a85792d58060c8a