why is the scope of RestEasy compile in the pom.xml when the container (JBOSS) provides it? - maven

Here is the relevant portion of pom.xml
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-all-5.0</artifactId>
<scope>provided</scope>
</dependency>
Why is the scope of resteasy compile (which is default, when none is provided) but that of javax.servlet is provided. I am deploying this on Jboss which ships with resteasy. so shouldn't the scope of resteasy be provided as well?
and btw, I do not see any version mentioned. so what is the default version that gets picked up?

If you are using jboss 7, resteasy-jackson-provider is included, so it would be correct to use a provided scope.
I guess default version is being picked up from a bom declared in the dependencyManagement section of your pom, could that be right?
For older jboss versions, resteasy is not included, so you will have to add the jars to your WEB-INF/lib directory.
Necessary jars can be obtained using maven (compile scope) or check out this link http://www.mastertheboss.com/jboss-frameworks/resteasy/resteasy-tutorial

The RESTEasy API and runtime is provided by newer versions of JBoss. Usually you import a Java EE-spec pom in the dependencyManagaement section and add the needed APIs in the dependency section, e.g for JBoss AS7:
<dependencyManagement>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>3.0.2.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_1.1_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
The runtime will use the JSON-Provider which is found on the classpath. So it makes sense to add them with scope compile to your project. If you want to use Jettison you'd add following to your pom:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jettison-provider</artifactId>
</dependency>
If you don't add one your application server may provide a default one. JBoss AS7 / Wildfly for instance will use resteasy-jackson-provider if you don't add a provider to the classpath.
JBoss 5 does not provide the JAX-RS libs as far as I know so there it makes sense to add the resteasy-jackson-provider with scope compile.

Related

Can I use camel-spring version 2.25.x with camel-core version 2.23.x

I am using below Red Hat Fuse BOM for my camel application to get the camel dependencies for my project. It returns camel dependencies version 2.23.x
<dependencyManagement>
<dependency>
<groupId>org.jboss.redhat-fuse</groupId>
<artifactId>fuse-springboot-bom</artifactId>
<version>7.7.0.fuse-sb2-770010-redhat-00001</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependencyManagement>
My Maven is set to get the dependency through JFrog, which blocks camel-spring-2.23.x version due to some vulnerability found in this version of jar as per our client security policy. My question is, Will it be correct to specify the camel-spring dependency in pom.xml as below to download 2.25.x version and let the other camel lib dependencies as 2.23.x ? Is it going to cause any issue in amy camel application due to different camel library versions?
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>2.25.2</version>
</dependency>

Determine compatible Versions of Spring Modules and other libraries

Which is the best way to determine the versions for my Spring modules and other libraries in a Spring Boot project?
Versions for Spring Modules
Versions for Third Party libraries
There are a lot of question when you search for "Compatible versions in Spring".
But all these questions are regarding specific libraries.
I would like to have general rules of how to determine compatible versions for my project.
You may checkout my post on this A comprehensive list of dependencies managed by latest Spring-Boot 2.3.2.RELEASE (as a custom parent)
That's is just a reference for how it should be, but you may discard the version in as they will be managed indirectly by spring itself.
Ok so, this is something almost every spring developer stumble upon. Let me try to explain this how was I able to resolve all the managed and third party libraries.
Let's suppose you want to build spring-boot microservices with a centralized configuration server.
So we can take it as following modules:
A company project starter: acts as a parent, managing the dependency
A config-server
A config-client
and let's suppose you chose spring-boot 2.3.2 version, which I used and find more stable. You would expect all the managed ones are using this spring-boot 2.3.2 version directly or indirectly.
I would highly recommend using https://mvnrepository.com
artifact: my_company-boot-starter-parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<groupId>com.my_company</groupId>
<artifactId>my_company-boot-starter-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>my_company starter-parent</name>
<dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- ... -->
<!-- ... -->
<!-- other dependencies -->
<!-- ... -->
<!-- ... -->
</dependencyManagement>
If you got to Spring Boot Starter Parent ยป 2.3.2.RELEASE, under Managed Dependencies you can see the comprehensive list of all the dependencies with default version that would be referenced implicitly with boot version 2.3.2, see column Version.
The Updates column indicate that these managed dependencies are having their newest updates as this, but you are not required to override the dependency version of managed ones. If you intent to use more recent version, you have to chose more recent version of spring-boot-starter-parent. So let the spring download all the managed one itself.
With spring-boot-starter-parent 2.3.2 , they do not mention which spring-cloud-dependencies verion you should use, and this is where we get stuck and we need to figure it out.
Let us got to spring-cloud-dependencies . Hee you can see numerous version but which one to chose, it's like verifying which latest version uses spring-boot 2.3.2 indirectly.
You need to follow the managed dependency and go along with it until you find your parent version.
For example If you go for :
Hoxton.SR6
Spring Cloud Dependencies(Hoxton.SR6) -> Spring Cloud Config Dependencies( 2.2.3.RELEASE) -> Spring Cloud Starter Config(2.2.3.RELEASE) -> Spring Cloud Starter(2.2.3.RELEASE) -> Spring Boot Starter(2.3.0.RELEASE)
Here you can see, we end up using Spring Boot Starter(2.3.0.RELEASE) which is not what we expected it to be.
Hoxton.SR7
Spring Cloud Dependencies(Hoxton.SR7) -> Spring Cloud Config Dependencies(2.2.4.RELEASE) -> Spring Cloud Starter Config(2.2.4.RELEASE) -> Spring Cloud Starter(2.2.4.RELEASE) -> Spring Boot Starter(2.3.2.RELEASE)
Here we end up using same boot version 2.3.2. So in your parent pom.xml, you can set the spring cloud version as :
<properties>
<java.version>15</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lombok.version>1.18.20</lombok.version>
<spring-cloud.version>Hoxton.SR7</spring-cloud.version>
</properties>
And in child poms (jars), you can just use the dependencies justby mentioning the group and artifact, skipping the version.
sample:
<parent>
<groupId>com.my_company</groupId>
<artifactId>my_company-boot-starter-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.google.googlejavaformat</groupId>
<artifactId>google-java-format</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
</dependencies>
See, we have not provided the any version here, so spring-cloud-config-server version would be auto managed and it would be 2.2.4.RELEASE which again uses spring-boot-starter-web and spring-boot-starter both of 2.3.2 version.
Third party libraries
This is somewhat based on language version. You might want to use the latest third-party libs which is most recent till your language version supports it.
Like lombok: 1.18.20
Hope this might have helped you and others and provides an approach towards version compatibility.
Tips: Never forget to check the Managed Dependency Coordinates in Aappendix of all the spring boot release page as they keep their managed dependencies & version there. Like this one Appendix F: Dependency versions
1. Use Spring Initializr
Select all Spring modules you need in spring initializr and generate your code: https://start.spring.io/
You do not need to use the full generated code. But you should copy the library versions out of the generated pom.xml.
2. Watch out for dependency pom.xml
If available, import dependency pom.xml in your dependencyManagement.
Use the versions provided by these dependency poms.
E.g.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Spring Dependency Version Documentation
You can also check the Spring Dependency Version Documentation. But I prefer the initilizr, because it's easier to handle.

Spring boot 2.1.7 having tomcat-embed-core conflit

I am migrating existing Spring project into Spring boot.unable to run spring boot application its showing following error.
The error log says there is a conflict on tomcat-embed-core.
In eclipse Dependency hierarchy of porm.xml is given below
i exclude the maven architect ,and try to run the application its showing following error
porm.xml
<modelVersion>4.0.0</modelVersion>
<artifactId>MyService</artifactId>
<packaging>jar</packaging>
<properties>
<java.version>1.8</java.version>
<!-- 2.1.3.RELEASE -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springframework.boot.version>2.1.7.RELEASE</springframework.boot.version>
</properties>
<name>MyService</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.sybase.jdbc3.jdbc</groupId>
<artifactId>jconn3</artifactId>
<version>${jconn3.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<version>${tomcat.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>${tomcat.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
what was wrong in this porm.xml
Where is
${tomcat.version}
defined?
That version probably does not match the tomcat version that auto magically is included with spring boot items.
And thus the conflict.
Go here:
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web/2.1.7.RELEASE
And start following the COMPILE dependencies, and you'll find the versions that are auto included with 2.1.7.RELEASE. and you have to alter the other includes that are overwriting the springboot auto include tomcat versions.
Again, follow the COMPILED dependency trail.
So below is what you should find by crawling the COMPILED dependency trail (from immediately above in my answer)
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat/2.1.7.RELEASE
And you'll find you need to set
tomcat.version to
9.0.22
By defining tomcat.version as 8.x, you are breaking it.
Another way to put it
You have to go ~way~ back to springboot 1.5.2.RELEASE or 1.5.3.RELEASE
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat/1.5.2.RELEASE
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat/1.5.3.RELEASE
(Again, in the two above links, looked at the COMPILE dependencies)
To find a version of tomcat (that is auto included with springboot) that gets close to tomcat 8.5.x (where 8.5.x is the one you are attempting to use)
That's pretty old.
The principal you are missing is that springboot auto includes dependencies. And anything else you import has to play nice with everything springboot auto includes.
And your current value for tomcat.version is NOT playing nice with everything springboot 2.1.7.RELEASE is auto including.
And now that you've been through all of that. You'll find you'll make your life easier if you engage the springboot world more completely.
Alot of times, springboot will have a (sub)package that will bring in the thing you really desire.
spring-boot-starter-jdbc
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc/2.1.7.RELEASE
You would probably be better off bringing that package in, vs hand-picking ones. Aka, get rid of your "tomcat-jdbc" include and see if the spring-boot-starter-jdbc can give you what you want.
The curse/blessing of spring-boot is that it is its own universe. But if you engage, you probably want to play by its rules more often than not.
PS
It is pom.xml, not porm.xml
Try adding spring-boot-starter-tomcat as a dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Remove tomcat-juli and tomcat-jdbc dependencies. If you need JDBC support, add the corresponding starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
If you use JSP views, you will probably need the following dependencies as well:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
Also, pay attention to your dependencies versions. Spring Boot's parent POM defines version management for many common artifacts so you don't need to set the <version></version> for these libraries. See https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/htmlsingle/#appendix-dependency-versions

Excluding "provided" libraries from MobileFirst Maven builds

I have added a <scope>provided</scope> dependency to my Maven pom.xml for my Java adapter, because the referenced jars are provided by my application server, but Maven install is still including the jars in the .adapter file.
Is this the expected behavior? Is this a Maven issue, or something related to MobileFirst platform foundations use of it? The MFP provided libraries seem to not be included.
Not included in .adapter file:
<dependency>
<groupId>com.ibm.mfp</groupId>
<artifactId>adapter-maven-api</artifactId>
<scope>provided</scope>
<version>8.0.2017012516</version>
</dependency>
Included:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3</version>
<scope>provided</scope>
</dependency>

spring.io hibernate config

I'm using the Spring IO 1.0.1 BOM to manage my dependencies for my project. I've imported it in my super-pom's dependency management section like this -
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
Now, in a submodule POM of my project, I've declared these dependencies
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
</dependency>
And my final packaged war includes both hibernate-jpa-2.0 and hibernate-jpa-2.1. Since the entity manager depends on 2.1 and the api is 2.0. These are causing conflicts within my deployed app.
I cannot find a declaration of 2.1 in the platform bom so I'm confused about how to proceed. The documentation lists both of these as libraries provided by the platform, but the BOM doesn't provide any resolution between their conflicting versions. What is the recommended approach? Should I manually exclude 2.0 and explicitly declare 2.1 even if its not in the parent BOM? Should I force hibernate-entitymanager to use the 2.0 APIs?
I was hoping that the IO platform BOM would help me with these kinds of collisions.

Resources