I have faced with a little problem, I have added next dependency in my project:
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.19</version>
</dependency>
And my project enlarges from 330kb to 12.1mb . I know that HTMLUnit based on Apache Http Client that weights much, but maybe Maven has some feature to exclude libraries/packages that doesn't used in sources? (not manual excluding)
How should Maven know that? You might using some kind of DI which is during runtime ? You can of course exclude dependencies if you know that they are not used...and of course handle the dependencies correct for their purpose as already mentioned to use <scop>test</scope> if it's something which is used only for testing.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
...
<dependencies>
<dependency>
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>sample.ProjectD</groupId>
<artifactId>Project-D</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
Since this is a testing dependency, you can always add <scope>test</scope> to keep it from being packaged in your build.
Related
currently I'm working on a project in my company that imports XML data to our database. While doing this I rely on some basic configuration projects which have been already created and used in other Projects, i.e. an EntityManagerBuilder or other utility classes that are used in order to create a connection to our oracle database. And it seems to me that those dependencies are creating some problems for me.
My project runs perfectly fine if I start it within eclipse. And when I create the project with mvn clean install -DskipTests it builds all fine.
But when I want to run it from the command line the application starts and after a few lines of code just stops, without throwing any errors or exceptions.
The reason why I think that it has something to do with some dependencies is that by logging I managed to find the point where the application stops. Since it stopped at a point I could investigate, I just did that. I downloaded the sources an only added some logging and suddenly my application had no problems at all with that class, instead it just stopped with the next static call to an other class.
I have no idea at all where to search for the error. Since this is an application that has to run by it self as a monthly task, executing it from eclipse is not an option.
Hopefully someone can give me a hint how to solve this.
Here is my POM:
<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.company.infrastructure.foo</groupId>
<artifactId>foo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>foo-import</artifactId>
<packaging>jar</packaging>
<name>FooImport</name>
<properties>
<company.consoleapp.main.class>com.company.infrastructure.foo.import.FooImporter</company.consoleapp.main.class>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.company.maven</groupId>
<artifactId>company-standalone-dm</artifactId>
<version>${company.parent.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<!-- Utilities -->
<dependency>
<groupId>args4j</groupId>
<artifactId>args4j</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<!-- Using foo-dataaccess -->
<dependency>
<groupId>com.company.infrastructure.marken</groupId>
<artifactId>foo-dataaccess</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>foo-import</finalName>
<plugins>
<!-- Consoleapp-Mixin -->
<plugin>
<groupId>com.github.odavid.maven.plugins</groupId>
<artifactId>mixin-maven-plugin</artifactId>
<configuration>
<mixins>
<mixin>
<groupId>com.company.maven</groupId>
<artifactId>company-consoleapp-mixin</artifactId>
<version>${company.parent.version}</version>
</mixin>
</mixins>
</configuration>
</plugin>
</plugins>
</build>
I think this might be something to do with your dependency management in maven, since you haven't specified the versions and maven figures out those versions automatically.
However when you run the application, you need those jars to be in your classpath otherwise you might end up getting a ClassNotFoundException because the jars are not available. So unless you figure out what your dependencies are like you mentioned and add them to your classpath you would end up seeing the error.
It might be worth enabling a further level of logging in your application to give you some indication of where the error is. You could also try and see if at the point of failure is referenced to an external library, which is the one that is not available in your classpath.
Could you also please share how your running your application through CLI.
I have a fairly large legacy project that I'm adding a component to. This component uses HtmlUnit. I can compile it ok with Maven but when I run it I get:
java.lang.NoSuchMethodError:
org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>
(Ljavax/net/ssl/SSLContext;[Ljava/lang/String;[Ljava/lang/String;Ljavax/net/ssl/HostnameVerifier;)
So it's missing the correct constructor. I think this is almost certainly a version conflict in httpclient but I'm not sure how to resolve it. Here's the relevant part of my pom.xml (note all the games I've been trying to play with exclusions and dependency management):
<dependencies>
<dependency>
<groupId>com.mycompany.mine</groupId>
<artifactId>my-base-project</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>base-project</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
</dependencyManagement>
Any ideas?
Edit: it's been suggested that this question is a duplicate of this one, but it's not since the dependency type in this case is not war.
In order to identify conflicting dependecies, use mvn dependency:tree. I like to pipe it to a text file for ease of use:
mvn dependency:tree > tree.txt
Then, use your favorite text editor to look for multiple versions of a depedency.
Alternatively, if you are looking for a specific groupId or artifactId, use the -Dincludes flag:
mvn dependency:tree -Dincludes=<groupId>:<artifactId>:<version>:<packaging>
mvn dependency:tree -Dincludes=org.springframework <<< get all dependencies with by groupId
mvn dependency:tree -Dincludes=:spring-web <<< get all dependencies by artifactId
You might also want to add the -Dverbose flag here.
To resolve dependency conflicts, there are two ways:
1) Exclude the one you don't want
<depdency>
<groupId>some.stuff</groupId>
<artifactId>with.transitive.depdency</artifactId>
<exclusions>
<exclusion>
<groupId>something</groupId>
<artifactId>unwanted</artifactId>
<exclusion>
<exclusions>
<depdency>
With this way, you will have to exclude on every dependency that brings in a transitive one. For this reason I like the other one better.
2) Explicitly add the version you want
<dependency>
<groupId>something</groupId>
<artifactId>with.version.conflict</artifactId>
<version>what I want</version>
</dependency>
This will make sure that any transitive dependency will be swapped with this exact version. This might also lead to errors though, if some framework actually needs an older version. For using this strategy safely, your dependencies will need to be fairly close to the newest available version (or versions released at the same time).
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.
I have created simple project from maven-achetype-quickstart under Eclipse Indigo, then I went to pom.xml gui editor and in dependencies tab added dependency log4j by search in appropriate dialog. Now my pom.xml looks like
<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-.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>Test_Maven_03</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test_Maven_03</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Eclipse says my POM have many problems like
Missing artifact javax.jms:jms:jar:1.1 pom.xml /Test_Maven_03 line 2 Maven Dependency Problem
What does it mean and how to see maven feature of automatic jar downloading.
EDIT 1
If I select log4j 1.2.16 instead of 1.2.15, I get another error: Missing artifact log4j:log4j:bundle:1.2.16. So I see no automatic jar management at all.
It's not included anymore due to licensing issues if I remember correctly. If you don't need jms functionality you can exclude jms from log4j dependency:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
</exclusions>
</dependency>
Change the version of log4j to 1.2.16.
The metadata for 1.2.15 is bad, as you have discovered, because the dependencies are missing from the central repository. However, there is a policy of not changing artifacts or metadata in the central maven repository, because this can lead to builds being unrepeatable. That is, a build might behave differently if an artifact or its metadata changed.
The reasoning is that it's better to work around bad metadata than cause unreproducible builds.
It's better, of course, if project maintainers are more careful about the metadata that they upload to central.
Use Log4J 1.2.16 (the one I linked to in your earlier question); it doesn't have the older JMX dependency and gets it from Geronimo instead.
The answers above (excluding JMX) are fine, so long as you don't need any of the JMX dependencies. However, you will never be able to download the JMX dependencies' .jar files from a standard maven repository. To quote Jörg Schaible-3 at nabble.com:
This is normal and it will stay so, because Sun/Oracle never granted
distribution rights for those artifacts as separate downloads. You will have
to download them from Oracle, accepting their license, and add them to a
local repository manager.
Therefore, if you want to use JMX, you will need to download the respective jmx zip folder from Oracle's website.
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.