Maven Dependency Version As Property - java

I have a maven pom file that defines a dependency as such:
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
</dependency>
</dependencies>
It is often said that everything in the pom can be referenced as a Maven property:
https://bowerstudios.com/node/991
For example, you can read ${project.version}, ${project.build}, etc. Is there a way to read a dependency's version as a Maven property, ala ${project.dependencies.dependency.groupId=org.apache.httpcomponents&artifactId=httpclient.version} ?

You could define a custom property under <properties> and refer to it from your dependency. Preferred way is to place the property in parent pom (if exist and is a multi module project). Alternately, you can skip the <version> altogether if you had defined the <dependency> in <dependency-management> section
<properties>
<http.client.version>4.3.6</http.client.version>
</properties>
...
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${http.client.version}</version>
</dependency>
</dependencies>

Related

Changing the version of a transitive dependency in maven pom.xml

I've been trying to override a transitive dependency version in one of my projects. I found the following sample project on github to experiment on ( https://github.com/Richou/swagger-codegen-maven-plugin). The parent pom of this project contains a dependency for swagger-codegen. Swagger-codegen in turn has a dependency called slf4j-ext whose version is 1.6.3. I want to upgrade/override the version of slf4j-ext to 1.7.30 from the parent pom. I tried adding the required slf4j-version inside the property tag in the parent pom but it didn't work when I checked the maven dependency tree. What is the correct method to do it?
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen</artifactId>
<version>2.1.2</version>
</dependency>
</dependencies>
<properties>
<slf4j-version>1.7.30</slf4j-version>
<java.version>1.7</java.version>
</properties>
You can add the slf4j-ext with the version you want in the dependencyManagement section of your parent pom.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-ext</artifactId>
<version>${slf4j-version}</version>
</dependency>
</dependencies>
</dependencyManagement>

How to include multiple jar in type from type field in pom dependency?

I have the following pom definition
<dependencies>
<dependency>
<groupId>com.my.stuff</groupId>
<artifactId>my-stuff</artifactId>
<version>${my-stuff.version}</version>
<type>test-jar</type>
</dependency>
I want to use both jar and test-jar , is there a way to do that?
I guess that test-jar is not a type, but a classifier. You probably want something like:
<dependencies>
<dependency>
<groupId>com.my.stuff</groupId>
<artifactId>my-stuff</artifactId>
<version>${my-stuff.version}</version>
<classifier>test-jar</classifier>
</dependency>
<dependency>
<groupId>com.my.stuff</groupId>
<artifactId>my-stuff</artifactId>
<version>${my-stuff.version}</version>
</dependency>
</dependencies>

How to prevent from overriding parent pom dependency version in child pom

I have parent pom with such config:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.9</version>
</dependency>
</dependencies>
</dependencyManagement>
And my child pom:
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
</dependencies>
I want to use 4.3.5 version in my classpath, because at the moment I am getting error, parent version should not be modified:
java.lang.NoClassDefFoundError: org/apache/http/impl/client/HttpClients
Any ideas how to prevent from overriding that 4.2.9 version?
As you know that your parent pom dependency is include in the child pom then don't need to write dependency in the child pom.xml .
To include the parent pom dependency in child use
<dependency>
<groupId>${defined groupId of parent}</groupId>
<artifactId>${artifact defined for parent }</artifactId>
<version>${version defined for parent}</version>
</dependency>
In your parent Pom file for the specified Dependency add scope as Provided
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.9</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
But As #Deltharis commented better to use the dependency only in the parent POM
I changed parent version to desired and removed dependency from child (the simple and the best solution).
Thanks goues to #Deltharis for the comments!

Automatic resolve dependency hierarchy for a custom jar

I am struggling with the maven dependencies. The maven dependency hierarchy is not resolved in my projects where I add my custom build jar. This is a little bit confusing, because all the dependencies of other externally provided dependencies (like org.json, reasteasy-jaxrs ) are nicely shown in the dependency hierarchy view.I am using Eclipse EE IDE for Web Developers with maven plugin.
The project structure: The project is a platform consisting of several services using the same project-support module. Further, the project-support will be used in external projects (here project-consumer) as well.
project-parent (pom)
project-support (jar)
project-service-a (war)
project-service-b (jar)
project-consumer (war)
project support (jar)
Extract of project-parent.pom
<modules>
<module>../project-support</module>
<module>../project-serviceA</module>
<module>../project-serviceB</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tomcat.version>7.0.50</tomcat.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.6.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
Extract of project-support.pom
<parent>
<groupId>com.somecompany.project</groupId>
<artifactId>project-parent</artifactId>
<version>1.1.0-SNAPSHOT</version>
<relativePath>../project-parent</relativePath>
</parent>
<artifactId>project-support</artifactId>
<name>projectsupport</name>
<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
</dependencies>
Extract of project-service-a.pom
<parent>
<groupId>com.somecompany.project</groupId>
<artifactId>project-serviceA</artifactId>
<version>1.1.0-SNAPSHOT</version>
<relativePath>../project-parent</relativePath>
</parent>
<artifactId>project-service-a</artifactId>
<name>projectsupport</name>
<dependencies>
<dependency>
<groupId>com.somecompany.project</groupId>
<artifactId>project-support</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
So, when looking at the project-serviceA dependency hierarchy (and also in the effective pom), the required dependencies of project-support are not included which results in code compilation errors. Further the project-support is used in projects outside the scope of project-parent.
So my question: Why does maven not resolve the dependencies tree of project-support and adds them into the effective pom?
Thanks in advance.
You have set the scope of the dependencies to provided in you parent's dependency management section. According to the introduction to the dependency mechanism, the dependency scope is used to limit the transitivity of a dependency.
The above linked introduction also includes a table that declares which scopes play in the transitivity game and which do not. The provided scope is not part of the transitivity.
So the solution is to not declare any scope in the dependency management but declare a reasonable scope in the dependency usage.

Maven - moved code to new artifact; transitive dependencies issue

Here is my situation:
I created a new artifact in a library called 'web-ng-framework', and moved code into it from an old artifact in the library, 'web'
I deleted the 'web' artifact
And here is the problem:
ProjectA uses an older version of the library, and so it has a compile dependency on 'web'
ProjectB depends on ProjectA
ProjectB uses the latest version of the library, so when ProjectB is built, it contains both the 'web' and 'web-ng-framework' libraries, causing a possible conflict
Does anyone know how I can solve this? Thanks!
EDIT:
Would doing 'relocation' of 'web' to 'web-ng-framework' maybe work better? In ProjectA, I could include a dependency on 'web' so that Maven would see that what it really needs is 'web-ng-framework'. Would that work?
When including ProjectA in ProjectB exclude web. Like this
<dependency>
<groupId>your.group</groupId>
<artifactId>projectA</artifactId>
<exclusions>
<exclusion>
<groupId>your.group</groupId>
<artifactId>web</artifactId>
</exclusion>
</exclusions>
</dependency>
A classic solution to this problem is the 'Version 99' hack.
To do this, use the following in your root pom:
<dependencyManagement>
<dependency>
<groupId>your.group</groupId>
<artifactId>web</artifactId>
<version>99.0-does-not-exist</version>
</dependency>
</dependencyManagement>
Then put an empty web-99.0-does-not-exist.pom and web-99.0-does-not-exist.jar in your repository.
This ensures that every project that inherits from this root pom will not get the old version of the web.jar anymore.
I suggest that you use optional dependencies
This can be acheived by making web depencency optional in projectA.
<project>
<groupId>some.group</groupId>
<artifactId>projectA</artifactId>
...
<dependencies>
<!-- declare the dependency to be set as optional -->
<dependency>
<groupId>some.group</groupId>
<artifactId>web</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>
When declaring some other project that depends on projectA the web dependency will not be included.
<project>
<groupId>some.group</groupId>
<artifactId>projectB</artifactId>
...
<dependencies>
<dependency>
<groupId>some.group</groupId>
<artifactId>projectA</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>some.group</groupId>
<artifactId>web-ng-framework</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
Now projectB will only have a dependency on projectA and web-ng-framework, not web.

Categories