I have a project which has multiple .jar files in it. In the past, I had a build.xml file which I was running through Ant, and it was creating a new jar out of these multiple jars, and this brand new jar was being referred as a dependency.
Now that I switched to maven, I'd like to know how I can mavenize this. In other words, how to tell maven to build the multiple jars into one jar, and then refer it as a dependency? In order to put things into more solid basis, I'll share the folder structure I have:
+- mainProject
+- pom.xml
+- someGroup
| +- pom.xml <- refer here
| +- sampleModule1
| | +- pom.xml <- build here
| | +- build.xml
| | +- first.jar
| | +- second.jar
One idea in my mind is to tell maven to call build.xml, which will create that new jar out of those two jars, and then use it as dependency, like here:
<dependency>
<groupId>someGroup</groupId>
<artifactId>org.boofcv</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../shared/org.boofcv/brand-new.jar</systemPath>
</dependency>
However, I doubt that it would work, since the chicken-egg problem may occur. By the time I call maven install, the task of creating the new .jar may take place after maven looks for it as dependency, resulting an error.
Does anyone know a workaround for this?
After searching more, I got to know that it is not possible to call an Ant script to build these jars into one jar, and at the same time to tell Maven to use the final jar. See the below quote:
"When using the Maven Antrun Plugin, Maven tries to resolve the dependencies to build ClassPaths for the AntRun invocation and you thus face a chicken and egg problem : you can't declare a dependency that will be created during AntRun execution that requires this dependency to run. This can't work."
instead, I found out a plugin called maven-shade-plugin. It creates a one big jar out of small jars, which I can use as dependency later in my top-level pom.xml, which was what I asked for.
Related
Our warfile contains not the expected SNAPSHOT-Version of a jarfile, it contains an older release version via another dependency.
Simplified dependency:tree
war-x.x.x-SNAPSHOT
\- jar1-x.x.x-SNAPSHOT
+- jar2-x.x.x
| +- problemjar-x.x.x
+- jar3-x.x.x-SNAPSHOT
jar3-x.x.x-SNAPSHOT has a dependency "problemjar-x.x.y-SNAPSHOT" (newer version), but the war project build (and the dependency:tree) contains "problemjar-x.x.x" from "jar2-x.x.x".
For now, we "exclude" "problemjar-x.x.x" for "jar2-x.x.x".
But it would be nice to know the reason for this behaviour, IMHO the exclusion is just a workaround.
Notes:
The dependency "problemjar-x.x.y-SNAPSHOT" in "jar3-x.x.x-SNAPSHOT" is not "provided".
The Maven version is 3.2.5
The levels in the simplified dependency:tree above are correct, so the path to the older version is not shorter than the path to the newer SNAPSHOT version
edit: project structure
war and jar1 are children of one parent pom, the simplified dependency:tree is from the war project which has the jar1 project as a dependency. The others are normal/external dependencies, which applies to jar1 too as seen from the war project.
Maven does not take the newest version from the dependency tree.
It takes the nearest version, and in your case this is the first it encounters.
If you want to force Maven to take a specific version, it is better to use <dependencyManagement> instead of exclusions.
Make sure of the following:
1) Each child module should take it's version from it's parent, i.e. do not have a <version> tag only a <parent> tag that contains a version.
2) When you call the dependency from the same project always do it as follows:
<version>${project.version}</version>
I need to create a jar-with-dependencies. I'm using maven assemply plugin 3.1.0.
I want to:
include dependencies with scope compile and that, transitively
exclude dependencies with scope provided.
IE, in the following case as shown by mvn dependency:tree:
[INFO] +- com.jayway.jsonpath:json-path:jar:2.2.0:compile
[INFO] | +- net.minidev:json-smart:jar:2.2.1:compile
[INFO] | | \- net.minidev:accessors-smart:jar:1.1:compile
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.16:provided
I want to include in the final jar json-path, json-smart, accessors-smart but NOT slf4j-api.
With the default jar-with-dependencies descriptor, I also have slf4j-api included in the resulting jar.
1/ Is it the intended behavior? This seem in contradiction with other maven resolution.
2/ what is assembly descriptor that allows to get what I want?
Thanks
So, it seems to just not work with the assembly plugin, and until explained why it is otherwise, I believe it's a bug: https://issues.apache.org/jira/browse/MASSEMBLY-883
I created a minimal project to demonstrate the problem here: https://github.com/fanf/test-maven-assembly
The solution is to use the shade plugin (https://maven.apache.org/plugins/maven-shade-plugin) which is correctly excluding transitive dependencies with scope provided (and can do many more things than the assembly plugin regarding uber-jar).
From the past one week I am trying to get code coverage of my multi module project using Sonar. My project structure is as follows.
Web Service XYX
+- pom.xml
+-SubFOlder
+- Module 1
+- pom.xml
+- Module 2
+- pom.xml
+- Module3
+- pom.xml
Means I have one folder in my directory and inside that I have all my sub modules. am able to generate a jacoco.exec file in all the sub modules target directory. Want to know the way to combine all these submodules jacoco.exec so that I can get a merged code coverage in sonar report.
As I've answered here: You can put all the reports together in one folder (don't forget to call the different!) and use the merge mojo for that, or use a central unique file to all your reports by adding the flag "append":
-javaagent:append=true,destFile=/home/YourProject/report.exec
Here you'll find more information about how to configure the agent.
Hope it helps!
I create a simple maven 109 project - maven-archetype-quickstart. Then, add to pom.xml a dependency to derby.
When I run mvn dependency:tree, I see, that the dependency parsed correctly: [INFO] \- org.apache.derby:derby:jar:10.8.1.2:compile. But when I see the package generated by mvn package, it has only 3.2kB and the dependency is not there. Why? How it works?
Because most people don't want all dependencies in their JAR by default. Imagine the people who want to use your artifact but a different version of derby.
To create an "ueber JAR" (i.e. a JAR which contains everything necessary to run it), use the Maven assembly plugin (search for "Creating an Executable JAR").
For example, I have a game project:
superegg/
|- game/
| `- pom.xml -> (a lot of jars.)
|- ai/
| `- pom.xml
|- sprite/
| |- egg/
| | `- pom.xml -> sprite
| |- badguy/
| | `- pom.xml -> sprite, ai
| `- pom.xml -> game
` pom.xml
(Here --> means depend on)
All sub-modules are in SNAPSHOT versions, and they are not installed, neither deployed.
Now, I want to do something within badguy/:
.../sprite/badguy/ $ mvn exec:java ...
however, maven tries to find the dependencies sprite, ai from maven repositories, instead of ../../game and ../../ai.
How to make Maven resolve sub-module dependencies with-in the project dir?
I don't install them because there are too many submodules (though not listed here), a fully compile/install procedure takes a very long time). I've also tried but not succeeded:
superegg/sprite/badguy/ $ mvn --reactor dependency:build-classpath
[INFO] Cannot execute mojo: build-classpath. It requires a project with an existing pom.xml, but the build is not using one.
superegg/ $ mvn -pl sprite/badguy dependency:build-classpath
Missing dependencies: ...
superegg/ $ mvn --reactor -pl sprite/badguy dependency:build-classpath
Project 'some-module' is duplicated in the reactor
BTW, I can build the whole project from superegg/ with no problem.
As of my understanding, you cannot do that in Maven (it is a build tool, not an IDE). I suggest you do one of the following:
Use the maven-compiler-plugin in version 3.1. It ships with an incremental compiler that will skip compilation if nothing happened. This will speed up your work a great deal.
Build only those modules that you worked in by using the -pl option.
http://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html
http://java.dzone.com/articles/5-maven-tips
I further recommend some sort of remote desktop or a ssh tunnel so that you can use Eclipse/IntelliJ/NetBeans. They provide just what you need.
If you load your top level pom from within IntelliJ, it will continually 'install' all the modules for you. I.e. it works out that you have a snapshot dependency which is already within the Maven reactor, so it doesn't bother going to your local repository.