5

I am developing a library based on Spring Boot, which could be used in multiple Spring Boot applications. The library is supposed to work with Spring Boot 1.3.0.M1 onwards.

I was thinking how to avoid putting a specific version of Spring JARs in it, and instead let the application specify the exact version. Currently I have come out with this solution, which seems to work except with certain combinations:

  1. In the library, have the Spring Boot version as 1.3.0.M1, and have the scope of all the dependencies as provided. Like this:

    ...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.0.M1</version>
        <relativePath/>
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <scope>provided</scope>
        </dependency>
    ...
    
  2. In the application, mention the actual Spring Boot version, e.g. 1.3.0.M3, and re-include all the dependencies, like this:

    ...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.0.M3</version>
        <relativePath/>
    </parent>
    
    <dependencies>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
     ...
    

When I run the application with this 1.3.0.M1+1.3.0.M3 specific combination, I'm getting this error, which I think is just some compatibility issue:

Exception in thread "main" java.lang.NoSuchMethodError: org.springframework.core.ResolvableType.forInstance(Ljava/lang/Object;)Lorg/springframework/core/ResolvableType;

However, experimenting with stable releases, e.g. when I set the lib version to 1.2.0.RELEASE and the app version to 1.2.5.RELEASE, it works.

So, I was wondering whether this would be the right way to handle such scenario, or there is a better way.

Sanjay
  • 8,755
  • 7
  • 46
  • 62
  • If you depend on Spring Boot then almost by definition it is not a library. – kryger Aug 17 '15 at 11:44
  • 1
    It has the parent as `spring-boot-starter-parent`, and has some dependencies like `spring-boot-starter-web`. But, it doesn't have the `spring-boot-maven-plugin`. So, a standard JAR is produced, and not an executable JAR. Why it couldn't it be called a *library*, then? – Sanjay Aug 17 '15 at 11:56

1 Answers1

1

You're mixing optional dependencies and dependency management. If your library requires Spring Boot to run, then you must specify the dependencies with the default scope.

If the user doesn't do anything and just import your library, then he'll get 1.3.0.M1 because that's what available by default.

If you now create a project from start.spring.io using for instance 1.3.0.M3 and add your library to it, you'll see that the project is using 1.3.0.M3. This is because that project has a dependency management section that enforces the use of Spring Boot 1.3.0.M3.

In other words, the user has to specify which version of a library he wants to use; as a library developer, there is nothing you can do.

Regarding the error, it is impossible to figure out what you're doing but my best guess is that you are trying to override both Spring framework and Spring boot with incompatible versions. You may want to review and better understand what dependency management is. This question is a good starting point.

Community
  • 1
  • 1
Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89
  • But, if possible, I was thinking not to bloat my lib JAR with a specific version of Spring Boot JARs. Instead, I wanted to have it thin, and let the application include the specific version of Spring Boot JARs. – Sanjay Aug 17 '15 at 07:33
  • Well, of course you should **NOT** run the repackage goal on your library! Your library should be a standard library, not a full blown spring boot app. – Stephane Nicoll Aug 17 '15 at 08:02
  • Yeah, I am not. Probably I'm not being able to be clear enough - have made some edits to my question now trying to be clearer. – Sanjay Aug 17 '15 at 10:29
  • You are probably overriding something else in that project. run `mvn dependency:list` on the app and make sure all Spring framework jars are using `4.2.0.RELEASE`. For the record, that method was introduced in `4.2.0.RC2` so you are probably using an older version of Spring Framework in the app (you shouldn't. Spring Boot should give you the right version) – Stephane Nicoll Aug 17 '15 at 11:57