Well, I'm not talking about the well-known commons-logging problem, I know I can disable it by setting the 99.0-does-not-exist version.
My problems is, some packages are contained in different dependencies, say, aspectjlib is contained both in org.aspectj:aspectjlib and aspectj:aspectjlib. In some cases, transitive dependencies may introduce the two jars at the same time, while of different versions, e.g., org.aspectj:aspectjlib:1.7.3, aspectj:aspectjlib:1.6.1. And mis-loading aspectj:aspectjlib:1.6.1 accidentally is not my intention. So is there a way like commons-logging that I can disable aspectj:aspectjlib completely?
I tried the same trick using 99.0-does-not-exist, only to find an error from maven:
[ERROR] Failed to execute goal on project XXX: Could not resolve
dependencies for project XXX:jar:1.0.0-SNAPSHOT: The following
artifacts could not be resolved:
aspectj:aspectjlib:jar:99.0-does-not-exist,
aspectj:aspectjrt:jar:99.0-does-not-exist,
aspectj:aspectjweaver:jar:99.0-does-not-exist: Could not find artifact
aspectj:aspectjlib:jar:99.0-does-not-exist in tbmirror
(http://mvnrepo.taobao.ali.com/mvn/repository) -> [Help 1]
Well, although some repositories do provide 99.0-does-not-exist for logging system dependencies like log4j, slf4j-log4j, commons-logging, etc., this is not a universal solution.
I find a solution to do this: use 'provided' scope.
To clarify, in my example above, I have two conflicting dependencies: org.aspectj:aspectjlib:1.7.3, aspectj:aspectjlib:1.6.1, I want to disable aspectj:aspectjlib:1.6.1, I only need to put this in top-level pom:
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjlib</artifactId>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
in this way, aspectj:aspectjlib:1.6.1 will never appear in the final built lib.
You can use Maven's dependency exclusions to eliminate the version you don't want. Using your example:
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-new-aspectj</groupId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-old-aspectj</groupId>
<exclusions>
<exclusion>
<groupId>org.aspectj<groupId>
<artifactId>aspectjlib</artifactId>
<exclusion>
</exclusions>
</dependency>
</dependencies>
Alternatively, you can simply pin the version you desire using dependency management:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjlib</artifactId>
<version>1.7.3</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-new-aspectj</groupId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-old-aspectj</groupId>
</dependency>
</dependencies>
If you are not sure which dependencies include which versions, you can use this to discover that info:
mvn dependency:tree -Dincludes='org.aspectj:aspectjlib'
There is no 99.0 version for aspectj:aspectjlib, your project is configured to use wrong version, check for 99.0 in your pom.xml
Related
I have error java: module com.example.learningfx reads package jfxtras.labs.util.event from both vworkflows.fx and jfxtras.labs and I think I need to exclude package from jfxtras.labs or vworkflow.fx. Jow can I not include some packages from dependency? Do I need to make this in pom.xml or module-info.java? I use maven and IntelliJ. I think there is already some questions like this but I don't find it
You can only include/exclude whole dependencies, not packages from dependencies.
See https://maven.apache.org/pom.html#Exclusions
You do not provide complete groupId:artifactId:version coordinates, so the example cannot be exact:
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>vworkflows.fx</artifactId>
<version>...</version>
<exclusions>
<exclusion>
<groupId>org.jfxtras</groupId>
<artifactId>jfxtras.labs.util.event</artifactId>
</exclusion>
</exclusions>
</dependency>
...
I am using spring-boot 2.0.3.RELEASE. When I am clicking on "show Effective POM" option by using IntelliJ IDEA, it loads Effective POM. And there I can see a few dependencies that my client don't want to have at there side.
Is there any way to tell Maven not to include these dependencies? How can we exclude dependencies from effective poms?
Maven provides a way to exclude dependencies with the exclude tag
Here is an example taken from the documentation website https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
<dependencies>
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
The idea is to locate parent dependencie from where you are getting deps you don't want and add an exclusion tag.
If they are needed in runtime you can specify the scope to provided
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
That will tell maven to use the deps to compile but not no include them in the target package, and they will be provided in the production environment by the JVM executing the code.
Hope this helps
I am fairly new to maven's capabilities..
I have seen that in pom.xml where dependencies are put, at times, only groupID and artifact id are mentioned and version is skipped. why is this?
For example the below dependency is from springsource website http://spring.io/guides/gs/authenticating-ldap/
<dependencies>
<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.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-server-jndi</artifactId>
<version>1.5.5</version>
</dependency>
</dependencies>
But elsewhere in stackoverflow it was also mentioned that version is not optional. I would be glad if someone could explain this.
Yes, version is not optional.
Consider a multimodule application which has 10 modules, say module1, module2.. module10.Assume that all of these 10 projects use the spring-boot-starter-web. In case these 10 modules are interdependent, you might want to use the same version of the spring-boot-starter-web in each of these 10.
Now just imagine how complicated it would be if you were to maintain the same version number in all of these 10 pom files and then update all of them when you want to use a newer version of spring-boot-starter-web. Wouldn't it be better if this information can be managed centrally?
Maven has got something known a <dependencyManagement/> tag to get around this and centralize dependency information.
For the example which you have provided, below set of links will help you understand how the version number is resolved even though it's not present in the pom which you are looking at.
Look at the parent tag of the pom you are looking at (https://github.com/spring-guides/gs-authenticating-ldap/blob/master/complete/pom.xml)
Now lets go to that parent and see if the versions are specified in the dependencyManagement section of that pom(https://github.com/spring-projects/spring-boot/blob/master/spring-boot-starters/spring-boot-starter-parent/pom.xml). No it's not defined there as well. Now lets look at the parent of parent. https://github.com/spring-projects/spring-boot/blob/master/spring-boot-dependencies/pom.xml. Oh yea, we have got the version numbers there.
Similar to dependencyManagement, plugins can be managed in the pluginManagement section of the pom.
Hope that explains it.
Refer : dependencyManagement, pluginManagement
A few additions to the excellent answer by coderplus:
In a multi-module project, it is considered to be a good practice to configure the artifacts used by the project in the dependencyManagement of the root pom.xml so that you don't have to write versions in child module pom.xmls (like in some dependencies in your example).
It is also considered to be a good practice to declare versions of the external libraries that you use as properties and then use these properties in dependencyManagement/dependencies/dependency/version. This is more or less done here:
<properties>
<logback.version>1.1.2</logback.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
In a multi-module project, you should also declare your own artifacts in dependencyManagement.
But please do not write the version explicitly (like Spring people do here), use ${project.version} instead.
So it would have been better to write:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${project.version}</version>
</dependency>
instead of
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>1.2.0.BUILD-SNAPSHOT</version>
</dependency>
here.
The whole purpose is DRY, don't repeat yourself. The more redundant declarations you have in your POMs, the harder they can hit. Hunting for the obsolete dependencies is so much fun.
If the <version> isn't specified then the <version> of <parent> is used. If there is no <version> in the <parent> then the <version> in the <parent> of the <parent> is used. etc.
I got a strange error in my pom.xml. Maven (I'm using Maven 2) is signaling Missing artifact javax.jws:jsr181:jar:1.0, even if I get the corresponding dependency in my pom.xml:
<dependency>
<groupId>javax.jws</groupId>
<artifactId>jsr181</artifactId>
<version>1.0</version>
</dependency>
What could possibly be the cause of this error?
Ok, I found the solution to the problem. I think the way to find it could be interesting, too.
When I look on mvnrepository.com, the pom file on the repository pointed on an URL on bea.com, which is not available anymore. So I had to change to the maintenance release, like Brian Agnew suggested. And of course, update some other dependencies in my pom.xml, which needed the obsolete version in their own dependencies. Maven comes with a cost...
<!-- https://mvnrepository.com/artifact/javax.jws/jsr181-api -->
<dependency>
<groupId>javax.jws</groupId>
<artifactId>jsr181-api</artifactId>
<version>1.0-MR1</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.1-1</version>
<exclusions>
<exclusion>
<groupId>javax.jws</groupId>
<artifactId>jsr181</artifactId>
</exclusion>
</exclusions>
</dependency>
Looking at my repository, I think you want:
<dependency>
<groupId>sun-jaxws</groupId>
<artifactId>jsr181-api</artifactId>
<version>1.0</version>
</dependency>
One of my Android projects requires oauth.signpost artifact, so I have something like this in my pom.xml:
...
<dependency>
<groupId>oauth.signpost</groupId>
<artifactId>signpost-core</artifactId>
<version>1.2.1.1</version>
<scope>compile</scope>
</dependency>
...
The problem is that this depends on more artifacts, for instance: org.apache.httpcomponents:httpclient:4.0.1. The problem is that Android already provides that package and thus it makes my building process crash.
So, what I usually do is going to the dependencies configuration on IntelliJ and manually mark those redundant artifacts as provide instead of compile:
This process is annoying, not only because I have a lot of Maven dependencies, but also because sometimes IntelliJ forgets what dependencies were market as provide and it will mark'em all as compile.
The only solution I see is to specify, in the pom.xml, which dependencies are provide and which are compile. But there are a lot of them, so it would take some time (also, I'd have to manually check which version is needed for each artifact, etc.).
So, is it a way to tell Maven to mark sub-dependencies as provide, while keeping main dependencies as compile?
There is the option to add dependency exclusions.
Consider the following:
Let's assume you have two projects - bar and foo.
Bar dependends on log4j.
You would like foo to depend on a different version of log4j.
This would be your pom.xml in the foo module:
<project>
<groupId>kung.fu</groupId>
<artifactId>foo</artifactId>
...
<dependencies>
<dependency>
<groupId>kung.fu</groupId>
<artifactId>bar</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
</project>