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

AbstractCloudConfig imports classes from Spring data Redis, MongoDB and RabbitMQ #88

Closed
gauthierj opened this issue Oct 8, 2014 · 10 comments
Milestone

Comments

@gauthierj
Copy link

Hi,

In project "spring-cloud-spring-service-connector", the object AbstractCloudConfig imports classes from "spring-data-redis", "spring-data-mongodb" and "spring-data-rabbitmq". Therefore it is impossible to extend it to create a DataSource, without adding useless dependencies.

Thanks, regards,

Gauthier

@scottfrederick
Copy link
Contributor

AbstractCloudConfig does import service-specific classes, but the dependencies on the libraries that provide these classes are marked optional in the build file. This means that these dependencies are not transitive, and apps or libraries that use Spring Cloud Connectors do not automatically have all these libraries as dependencies. See the Maven documentation for more details.

Does the fact that these dependencies are not transitive remove your concerns here?

@scottfrederick
Copy link
Contributor

@gauthierj Any feedback on response above?

@davidehringer
Copy link

I think the problem is that because they are imported you get a NoClassDefFound if you don't include them as dependencies even if you aren't using them. If you have something like:

public class CloudConfig extends AbstractCloudConfig {

    // access some services, none of which are rabbit, redis, or mongo
}

You still have to include rabbit, redis, and mongo related dependencies even though you don't use them in your app.

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>1.6.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>1.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.3.4.RELEASE</version>
        </dependency>

Otherwise you get NoClassDefFoundExceptions.

@gauthierj
Copy link
Author

Thanks @davidehringer that's exactly my problem.

Sorry for the late answer @scottfrederick, but I'm not truly working on that currently.

@scottfrederick
Copy link
Contributor

@davidehringer and @gauthierj Sorry for the back-and-forth on this, but I think we are seeing different things and I'm not sure what's causing the differences.

Here are several sample projects that use Spring Cloud Connectors, including AbstractCloudConfig, but only include the dependencies they actually use in the app:

Spring Music:

Spring Sendgrid:

rabbitmq-cloudfoundry-samples:

Can someone share a project that demonstrates the NoClassDefFoundException behavior so we can figure out what's different between these projects?

davidehringer added a commit to davidehringer/spring-cloud-connector-dependency-issue that referenced this issue Nov 26, 2014
@davidehringer
Copy link

@scottfrederick not a problem.
Here is an example project that demonstrates the issue: https://github.com/davidehringer/spring-cloud-connector-dependency-issue

@ramnivas
Copy link
Contributor

@davidehringer What's the version of JDK you are using?

@davidehringer
Copy link

1.7.0_67

@jhiemer
Copy link
Contributor

jhiemer commented Mar 24, 2015

Having exactly the same issue in three projects.

@scottfrederick scottfrederick added this to the 1.1.2 milestone May 1, 2015
@scottfrederick
Copy link
Contributor

Fixed in 625040c.

The reason that this problem was hard to nail down was that (per my testing anyway) the NoClassDefFoundException would only be triggered when the @Configuration class that extends AbstractCloudConfig was nested within a Spring Boot main class (or possibly nested in any @Configuration or @Component class). The exception would not get thrown if the @Configuration class was a top-level class. There may be other edge cases, but that explains why the problem didn't happen in all the (older, mostly non-Boot) projects listed in the comment above, but happened in many newer (I presume Boot) projects.

Moving the ServiceConnectionFactory class (which is where the DataSource, MongoDB, Redis, RabbitMQ dependencies come from) from an inner class of AbstractCloudConfig to a top-level class, and making AbstractCloudConfig depend on an interface instead of this concrete class, change the way Spring inspects these classes for configuration, and prevents the invocation of the Java refection API that was triggering the NoClassDefFoundException.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants