My goal is to create a distribution package (zip) with the following layout:
- application.jar
- libWebService
- web-service.jar
- libUtil
- guava.jar
...
The application.jarreferences the libraries in the separate lib folders in its MANIFEST.MF. The point with this layout is, that the dependencies are grouped semantically but are all normal maven dependencies defined in the pom.xml of the module that produces the application.jar.
Is there a simple way to create such kind of distrubtion with maven?
I know that I can use the maven-dependency-plugin (https://maven.apache.org/plugins/maven-dependency-plugin/) and its goal copy-dependencies to copy all dependencies of the current module (incl. its transitive dependencies) into a given output folder. With the exclude/include options I could even filter the dependencies and by invoking the plugin multiple times I could create the desired folder structure, although such kind of solutions would not be easy to maintain. But this solution still lacks the feature that the MANIFEST.MF file has to refer to the different folders. The maven-jar-plugin allows me to define one classpathPrefix for the complete jar but not a separate one for each dependency.
Related
I have a (long) list of what should not be included in my uber-jar, and I would like the list of what is included, so that I can work on the configuration and remove duplicates.
I looked at the output printed by mvn package that lists a lot of
[INFO] Including aaa.bbb:ccc.ddd:jar:x.y.z in the shaded jar
but I am pretty sure some of those were not included when I used the minimizeJar option. And looking into the output jar only allows to know the included classes (very difficult to track w.r.t the dependencies)
Question: Which ever configuration I use, how can I get a list of the dependencies that are actually merged into the uberjar?
I'm not familiar with the maven-shade-plugin, but have you tried out mvn dependency:tree? It should list all dependencies and its subdependencies of your project.
Edit: I re-read your question and it seems that you need a full dependency tree of your final uber-jar. A quick look at the maven-shade-plugin page told me that any dependency will be packed into the uber-jar. This should be what mvn dependency:tree outputs, but you can list the jar's contents aswell with jar tf <uber-jar>.jar. You may have to filter out parent dirs (e. g. com/) and the manifest file.
This is not the answer I am looking for, but for the sake of information sharing, here is what I did to find which dependency to remove from the shaded-jar:
use mvn dependency:list > dep.list
then manually remove lines that are not dependencies
and sort it
visually make a diff with the list of jar present on the deployment cluster
use mvn dependency:tree and my head to find the parent most dependencies that can be removed
mark them as <scope>provided<scope/>
use <keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope> in the shade plugin configuration
Tedious...
I have a simple testing-purpose gradle project, which I want to scan its dependencies using gradle dependencies command. Before I do so I want to make sure that the project's dependencies are actually found in the gradle's cache (.gradle/caches/modules-2/files-2/1). To do so I run the gradle assemble command to download the missing dependencies before scanning.
I found out that its working only if the project has a src/main/java folder with a Java file inside it (even if that Java file is completely empty).
Is this a valid workaround? Is there any better solution to guarantee the dependencies are found in the cache folder before scanning them?
What is the reason that you want to do that?
assemble task assemble your source files, if there is nothing to assemble the task is not needed to run. The fact you are adding the java file to src its a hack to run this task and its children tasks.
Depending on what you want to achieve there are few ways to 'scan' dependencies.
For more info you can visit https://docs.gradle.org/current/userguide/userguide_single.html#sec:listing_dependencies
Aditionally:
There is a netflix plugin that I believe can scan through your gradle scripts a check unused dependencies https://github.com/nebula-plugins/gradle-lint-plugin
There is a plugin that can scan the vulnerabilities of used dependencies etc https://jeremylong.github.io/DependencyCheck/dependency-check-gradle/
I have the following dependency in my gradle file.
compile 'org.A:A:1.0'
which automatically pulls in
'org.B:B:1.0'
and many other jars which it depends on.
But,my project requires repackaged A.jar (let's call it A*.jar which I installed in a local maven repository as custom version).
So now I change the dependency as below
compile 'org.A:A:custom'
which doesn't pull in any of the dependencies mentioned in the pom.xml file present inside the A.
jar file (which it would, had it been org.A:A:1.0)
My questions are:
1) Based on what does the statement compile org.A:A:1.0 pull other jars ? Is it pom.xml file present inside the jar?
2) What are the changes required if I want to automatically pull in both 'org.B:B:custom' and regular versions of other jars which are dependee of org.A:A:1.0
Maven will read the pom file for the artifact it resolves as well. In there the dependencies are found and resolved.
You simply need to also upload the pom of A*.jar and modify the version of it accordingly to A* - that should already do the trick.
Let's say I have a maven project which has some maven modules inside.
My main module depends on the other modules, so when I compile the main module they should be compiled together.
The question is, how to add these modules as dependencies to the main module?
I know if I have a custom lib that I want to use with maven, let's say a utilities project, I have to compile the jar of the project, do a mvn install:install-file on it to install it on the local repository and then add it to the pom.xml.
Do I have to do this with all my modules and add the dependency to the pom.xml on my main module? Because if it should be done like this, there will be a lot of work to do when changing code on the other modules.
What is the best practice to use avoid the trouble of compiling/installing the modules to local repository?
The question is, how to add these modules as dependencies to the main module?
The same way you add any other dependency to your maven project. By adding group id, artifact id and version to <dependency> element
Do I have to do this with all my modules and add the dependency to the pom.xml on my main module?
If your main module depends on some module A then only the pom of the main module should contain dependency declaration towards module A. You do that for all the dependencies of your module.
I don't know what you mean by "a lot of work when changing the code on other modules". Maven has nothing to do with code changes, it just builds the projects whatever they look like at the given moment...
What is the best practice to use avoid the trouble of compiling/installing the modules to local repository?
Any project that you invoke mvn install on gets built and it's jar copied to local repository. That's all you need to do to get the jar into the repo. This will also put all the dependent jars, if available, into the local repo.
As for best practices for multi module projects:
If your parent project (the one that has modules inside) has <modules> section that lists the modules of your application, and modules are in subdirectories of your parent project, then you simply mvn install (or whatever you want to do) the parent project and that will cause all the modules to be built in order defined by declared dependencies between them. That means that if your main module has dependency on module A, then module A will be built before the main module. This way you can build and install all your modules with one command. On the other hand this approach makes more tight coupling between modules which is not desired in some cases, so it depends on your use case whether it is a good approach or not.
I have a webapp that consists of multiple projects. We assemble using Ant and we suspect that some of the jars in /java directory are unneeded.
To find unneeded jars I ran
mvn dependency:analyze -DignoreNonCompile
to get a list of unused declared jars for each project. However it is possible that a jar unused by one project is still used by another. To check this, I ran
mvn dependency:tree
to get the dependency structure of all projects.
Using information from these commands, I will now use a script to check if a jar exists such that it is unused in all projects that declare it. Is this a reasonable approach for compile-scoped jars? What about jars in other scopes?
Thanks.
However it is possible that a jar unused by one project is still used
by another.
I recommend to declare all needed dependencies as direct dependencies and not rely on transitive dependencies which might get removed in a newer version.
Define the versions of the dependencies in the DependencyManagement section of the common parent POM and omit the versions later when declaring the dependcies. Like this you can make sure you're using the same version of the dependencies in all your projects.