Multiple Spring WEB MVC versions in pom.xml - spring

I totally new with Spring MVC and just started learning it 3 days ago. I'm still trying to understand it's configuration. I would like to know if it's advisable and possible to have multiple dependency definitions in pom.xml file.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mywebsite</groupId>
<artifactId>emusicstore</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
</dependencies>
</project>
I know this may be a simple question but I need to know if this is a good practice or not.
I noticed that when I tried to use the 4.3.3 RELEASE it didn't generate the dispatcher-servlet.xml and applicationContext.xml files inside the WEB-INF folder. But when I used the 4.2.4 RELEASE it generated the two files.
Thank you.

It's not a good practice, because it's better to be explicit in which versions to use.
Maven will just omit one of the versions. You can use the Maven dependency plugin to see which ones are selected:
mvn dependency:analyze

Related

Maven dependencyMangement doesn't inherit the virtue of dependencies in the parent pom

All our external dependencies are defined in enterprise pom. We do not want to define scope of the dependencies in the enterprise pom cause we have applications that are deployed both to Tomcat and JBoss. As we all know couple of dependencies come bundled out of the box in JBoss but may not exist in Tomcat default installation.
bom-parent is the parent of all the application specific enterprise poms. We then created a second level enterprise pom for each app, in the example below its bom-app1. All the projects inherit the app specific enterprise poms.
Sample project with detail instructions and comments available on GitHub
GitHub : https://github.com/samirshaik/mvn-dep-issue.git
Problem:
In the app specific enterprise pom we would just like to define scope of the dependency declared in dependencyManagement section in the first level enterprise pom. But this is not possible as Maven forces us to declare the version of the dependencies re-declared in the app specific enterprise pom. We went ahead and used the same version property as is declared in first level enterprise pom and every thing worked, except that we lost all the properties of the parent dependency like the exclusion of all the transitive dependencies.
To us this is very genuine requirement but looks like dependencyManagement the way its designed today, doesn't consider the virtues of inheritance.
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.samir.enterprise</groupId>
<artifactId>bom-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>Enterprise BOM</name>
<properties>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
Below is sample snippet of the child BOM, which should let me define the scope of the dependency and inherit all the features of the parent.
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.samir.enterprise</groupId>
<artifactId>bom-parent</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.samir.enterprise</groupId>
<artifactId>bom-app1</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>Enterprise Child BOM</name>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

Spring Boot project in IntelliJ IDEA stops working after reboot

This is probably a newbie question, but I am not able to sort things out.
I've created a Spring Boot JAR-based Maven project using the Spring Initializr interface in IntelliJ IDEA. Its dependencies on Web and JDBC; an embedded instance of Tomcat is used to run the project.
I also have a couple of other Maven dependencies I add without problems from the relevant dialog; I also manually add the Apache Phoenix thin client JAR, that includes a copy of Logback (I am not able to get their Maven repository to work, but I don't think this is relevant to this question).
I am able to run the project flawlessly; after a system reboot (I am on Windows), a cascade of errors follows. First and foremost an exception signaling a conflict between Logback comes:
Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from [...]). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.impl.Log4jLoggerFactory.
I would not like to alter the Phoenix client JAR; I am able to follow the instructions to replace the Spring dependency on Logback with another logger (log4j2 for example), but then the embedded Tomcat fails to create the container.
To get back to work, I have to recreate the project from scratch.
Could you please point me in the right direction to pinpoint the actual problem? Thank you.
Post scriptum: I am attaching the content of my pom.xml, apart from some potentially identifying information.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>[RETRACTED]</groupId>
<artifactId>[RETRACTED]</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>[RETRACTED]</name>
<description>[RETRACTED]</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Firstly, rather than adding the apache phoenix client (or any other dependencies) manually you should add them to your maven pom.xml, so maven resolves the dependency at build time. If your project has dependencies which maven is failing to resolve this is a separate issue which you need to resolve, but adding them manually is bad practice for a number of reasons.
Once you have added the phoenix client as a dependency, you need to explicitly exclude slf4j-log4j12 and log4j as part of the dependency declaration. The XML should look something like this:
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.13.1-HBase-1.3</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
The reason these need excluded is that they are conflicting with the versions bundled in the spring-boot project
Hopefully this will sort your problem.

IntelliJ can't find maven dependencies for GAE

I was following along with the Creating a Simple Hello World Backend API tutorial (GAE) and all was running fine via local terminal but as soon as I opened the project in IntelliJ, IntelliJ can't build the project...
The pom file has a bunch of errors about being unable to find any dependencies, however I can still build the application just fine outside of IntelliJ.
I'm not overly familiar with Maven but I believe it is configured correctly in the IDE as I can build other generic examples generated by IntelliJ. I've attempted to re-import all dependencies but no luck...
Is there something else I need to do here?
Snippet from the pom file where both dependencies are failing to find versions.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<groupId>com.example.helloworld</groupId>
<artifactId>helloworld</artifactId>
<properties>
<app.id>your-app-id</app.id>
<app.version>1</app.version>
<appengine.version>${appengine.version}</appengine.version>
<gcloud.plugin.version>0.9.58.v20150505</gcloud.plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
</properties>
<prerequisites>
<maven>3.1.0</maven>
</prerequisites>
<dependencies>
<!-- Compile/runtime dependencies -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>${appengine.version}</version>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-endpoints</artifactId>
<version>${appengine.version}</version>
</dependency>
Your appengine.version property is recursively defined, so IntelliJ can't figure out what it is. Substitute <appengine.version>${appengine.version}</appengine.version> with <appengine.version>1.9.24</appengine.version> and you should be fine.

Overrriding spring version in Spring boot/ spring cloud

I note that with spring cloud Angel.SR3 which uses Spring Boot 1.2.4, the spring version loaded is 4.1.6.RELEASE.
There is a memory leak issue in the yaml processor that I read was fixed in spring 4.1.7.RELEASE.
Specifically addressed in this https://jira.spring.io/jira/secure/ReleaseNote.jspa?projectId=10000&version=14936 ([SPR-13173] - YAML Processor leaves StreamDecoder open)
I tracked through and saw that the starters use ${spring.version} to specify the spring version to be used.
I tried overriding by adding 4.1.7.RELEASE to my properties, but it still loads the 4.1.6 version
Anyway I can do this? I understand that these are curated but this particular memory leak is causing us a lot of issues.
As requested I have attached the front part of the pom. All base dependencies are pulled in through the spring cloud parent. I noticed that they use ${spring.version} to define the correct value of spring. I attempted to override it via a property setting. At no time in the rest of the my pom do I explicitly bring in any of the spring framework libs. The parent pom does that.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.libertas.vipaas</groupId>
<artifactId>vipaas-starter</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>Vipaas Starter</name>
<description>Vipaas Starter</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Angel.SR3</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.javadoc.skip>true</maven.javadoc.skip>
<spring.version>4.1.7.RELEASE</spring.version>
..... other stuff ...
</properties>
... other stuff as not relevant ....
Using dependencyManagement it should work:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
You can check it with:
mvn help:effective-pom | grep -A1 "artifactId>spring-context"

how to automatically update maven dependencies in a multi-level project?

At my workplace, different groups works on providing different services.
My team consumes these services. Currently, whenever a new version of Service is rolled out, we manually change the pom.xml to the latest version of dependency and then make a build. I am wondering if there is an automatic way of pulling latest release into build.
Here is an example to explain:
pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.company.product</groupId>
<artifactId>User-Application</artifactId>
<version>1.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<Service1-version>1.0.2</Service-1>
<Service2-version>1.1.2</Service-2>
<Service3-version>2.0.2</Service-3>
</properties>
<dependencies>
<dependency>
<groupId>com.company.product</groupId>
<artifactId>Service1</artifactId>
<version>${Service1-version}</version>
</dependency>
<dependency>
<groupId>com.company.product</groupId>
<artifactId>Service2</artifactId>
<version>${Service2-version}</version>
</dependency>
<dependency>
<groupId>com.company.product</groupId>
<artifactId>Service3</artifactId>
<version>${Service3-version}</version>
</dependency>
.....
....
</project>
When new release of each service is made, we manually change the pom.xml to get the latest dependency. How can this be managed automatically?
The versions-maven-plugin should be able to do this with the task versions:update-properties. See an example here.

Resources