I have multiple spring projects that all have the same custom parent POM from which they all inherit their spring-boot version (1.5.18.RELEASE). Only one of the child projects need to be updated to version 2.1.4.RELEASE, but when I import spring-boot-dependencies, the spring-boot dependencies in the child project still remain at version 1.5.18.RELEASE.
Custom Parent POM:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.18.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>services</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Services :: Parent</name>
<description>Parent Project for Services</description>
Child POM:
<parent>
<artifactId>services</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../services/pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
You have to update the parent to the 2.1.4.release. This is because there can be lots of development problems if the child and parent are not in sync.
Tip: You can delete the version tag in the child dependencies.
spring-boot-starter-parent not only defines dependencies but also configures plugins and ships properties. Because you are upgrading from Spring Boot 1.5.X to Spring Boot 2.X it most likely won't be enough just to bump versions, there are incompatible changes between major releases e.g. Spring Boot 1.5.X is Java 6+ but Spring Boot 2.X is Java 8+.
You should use spring-boot-starter-parent-2.1.4.RELEASE as a parent in your child pom.xml. Your current approach is tinkering, follow the Spring Boot docs and set up child module as a proper Spring Boot 2.X module or you will waste a lot of time debugging problems caused by partial setup.
Related
In my application I am using grovvy dependency for using a class called GrovvyClassLoader. Earlier I was using spring version 2.2.11.RELEASE and my grovvy was on 2.5.13. Since I have upgraded to spring 2.6.6, it tends to download grovvy version 3.0.10 automatically.
I have tried to use <grovvy.version> tag inside <properties> tag in pom file to prevent spring from downloading grovvy automatically but even that is not helpful. Surprising is the fact that even grovvy dependency in my pom is set to version 2.5.13.
This my pom(parent pom),
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/>
</parent>
<properties>
.
.
.
<groovy.version>2.5.13</groovy.version>
</properties>
This is a child pom to the above pom where I am actually setting dependency for grovvy,
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>2.5.13</version>
</dependency>
Can anybody tell me why is spring overriding my version and how can stop it.
I am new to Spring so I would really appreciate if anyone of you can help me in this. I am adding a dependency of spring-boot-starter-security with a current version of 2.2.6.RELEASE and my parent is also having the same version. But still am getting an error-
Dependency 'org.springframework.boot:spring-boot-starter-security:2.2.6.RELEASE' not found .Tag name: artifactId Description : The unique id for an artifact produced by the project group, e.g. maven-artifact. Version : 3.0.0+ *
**Sorry in advance for any mistake ! **
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">*
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.arpita</groupId>
<artifactId>security_first</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>security_first</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
file -> invalidate caches/restart and it will work.
BTW you don't need to specify version for starter POM. If you remove the version tag from security starter , it should work fine.
you no need to mention the version of the spring boot project it will take care by spring boot
add the below dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
finally, update the your project
My suggestion is to install maven yourself.
I have the same problem some times. And I think it is because of the Intellij. So I close the project which is a simple spring boot project to study and install maven by myself instead by Intellij. After configuring the environment variable in window 10, I reopen the project and it appears everything is ok now.
You don't need to mention the version but it depends. Your spring boot parens can have older version or newer version than you specify. If you specity older version it's not compiles. Erwin Smith wrote file -> invalidate caches/restart and it will work. which worked for me, but could not help you if the situation is as I wrote. Check the version in your parent pom if it's newer do invalidate caches/restart otherwise udate version to newer and it should work.
Im looking to create a Spring library project to share across an internal team.
At a very basic concept level The library will send message events to a queue and my plan is to standardise this within a team across several Spring Boot Microservices send messages the same way.
My pom in the library project looks something like this
<artifactId>my-library</artifactId>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
etc...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
I have a service in the library project that looks like this
public class EventService {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
public void sendAuditEvent(AuditMessage auditMessage){
Set<ConstraintViolation<AuditMessage>> violations = validator.validate(auditMessage);
if(!isEmpty(violations)){
log.error("Unable to send audit message");
violations.stream().forEach( v-> log.error(v.getMessage()));
}
log.info("Found {} violations", violations.size());
// etc blah blah
return;
}
}
When I import the library into another project my thinking is that I can Autowire the EventService. By adding it in the pom and then
#ComponentScan({"my.library.package.eventlibrary.service"})
How do I prevent spring version locking? If the library is using spring 2.1.5.RELEASE today and the project that imports the library uses a different version would I not end up with potentially maven conflicts?
Also lets say the project that imports the library uses a lower version of hibernate api and the library has 6.0.16.Final. How would I prevent the project from using the newer one found one in the library classpath?
To clarify my question further is there a way I can separate the dependencies in the library from the project that uses it.
Pre Java 9. You can exclude the spring dependencies using maven when you declare the dependency to your module, same goes on for Hibernate. But you can't tell to your module to use a different hibernate version in a WAR.
If you want to work around this you can develop your library as independent micro service expose interface in the form of REST or Websocket if you want full duplex communication or something else JMS whatever....
Post Java 9 you can use java modularity to define the exact dependencies for your jar module. Check Project Jigsaw https://www.baeldung.com/project-jigsaw-java-modularity.
In your case in order to have different versions of the same library (hibernate). You would need two separate class loaders. To achieve this you would need to use layering read here http://openjdk.java.net/projects/jigsaw/spec/sotms/#layers
And here is the source code of many examples including ones that use layers. Focus on them : https://github.com/accso/java9-jigsaw-examples/tree/master/jigsaw-examples
You can try to exclude all transitive dependencies that your library can bring to projects that will use it.
To do this you should replace spring-boot-starter-parent with spring-boot-dependencies in dependencyManagement section and use provided scope for all dependencies which the library needs to work with and which will be exactly used by the projects, that will work with the library.
For example, a pom.xml of your library can be looks like this:
<!-- ... -->
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>0.1.0</version>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<spring-boot.version>2.1.5.RELEASE</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- ... -->
Then you will be able to use your library in the different projects, that use for example the old Spring Boot:
<!-- ... -->
<groupId>com.example</groupId>
<artifactId>old-project</artifactId>
<version>0.13.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.19.RELEASE</version>
<relativePath/>
</parent>
<!-- ... -->
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- ... -->
So this project will use hibernate-validator:5.3.6.Final from its spring-boot-starter-web.
Important notes - the code of your library should be 'compatible' with this version of Spring Boot. In other words, you should test your library with different versions of Spring Boot in which you are interested.
See my project as an example.
Might be not what you are looking for, but you can distribute your library as a spring-boot-starter auto configuration module (of course, if the clients are spring boot applications).
This way you can control your dependencies in an agile way and you give your clients more freedom in using the library.
In your particular case, if you need to send a message to a queue you for sure need to have a corresponding classes in classpath. With auto configuration you can have Class Conditions or Been Conditions based on which you can track if your clients have correct configurations in runtime. You can also fail the context loading if something is wrong (providing a meaningful error message).
Spring also provides tracking mechanisms of what could happen if a particular class/library is missing.
In my project, we've Parent module which is none of in our control and has using mongodb-driver-core-3.6.4.jar and spring-data-mongodb-2.0.11.RELEASE.jar. But somehow I want to use latest versions of both mongodb-driver-core and spring-data-mongodb. How to override this from Parent module ?
I already went through the link: https://spring.io/blog/2016/04/13/overriding-dependency-versions-with-spring-boot, but doesn't works for me.
I want to either override Spring Boot starter version or want to use somehow mongodb-driver-3.8.2.jar and spring-boot-2.1.4.RELEASE.jar
I've pom.xml file something like below:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example.ahr</groupId>
<artifactId>ahr-rest-api-starter-parent</artifactId>
<version>2.3.1</version>
</parent>
<groupId>com.example</groupId>
<artifactId>ahr-data</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ahr-data</name>
<description>ahr Data Service </description>
<properties>
<java.version>1.8</java.version>
<mongo.version>2.1.4.RELEASE</mongo.version>
</properties>
............
..................
.................
We simply need to override the spring-boot-dependencies from the Parent module, so that Spring Data Mongo starter can pick up the latest versions of itself.
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Here is the one more change we need to make -
<properties>
<java.version>1.8</java.version>
<spring.boot.version>2.1.4.RELEASE</spring.boot.version>
</properties>
I am tired of having to manually change the dependency version for every repository and run the build and tests.
Are there any good solutions/tools out there to centralize this, so that you only have to change the version in one file?
A requirement is that you still can override the desired version from the local repository.
In my Maven projects i use a parent pom for dependency management. I use the "dependencyManagement" tag in parent pom for declare al available dependencies and his versions for child modoules.
DIRECTORY HERARCHY
- project-name
- module-A
- pom.xml
- pom.xml
In parent pom.xml I specify the depencyManagement tag:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>artifact</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
In module-A pom.xml there is something like:
<parent>
<artifactId>module-A</artifactId>
<groupId>com.test</groupId>
<version>1.0</version>
</parent>
<dependencies>
<!-- The version is inherited from parent pom -->
<dependency>
<groupId>com.test</groupId>
<artifactId>artifact</artifactId>
</dependency>
</dependencies>
This way permits change the version of dependencies only in parent pom.xml. Al child modules will use it.
You can find more details in Maven's official documentation: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html