List only used jars - maven

I have Maven projects which I can build with these dependencies:
<dependency>
<groupId>org.wildfly.arquillian</groupId>
<artifactId>wildfly-arquillian-container-embedded</artifactId>
<version>1.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<version>9.0.2.Final</version>
</dependency>
There are a lot of jars into these dependencies and I would like to use on the necessary. How I can list which jars are only needed for the build?

The simple answer to you question is that there is no easy way to do what you are asking. In maven you declare for your package all the dependencies that the code inside your package will ever need in all scenarios. In this case if your using only a specific part of the wildfly-embedded package, and that part that you are using only depends on a subset of the package's declared dependencies then Maven has no way of knowing this.
One approach you could take is to simply look at the declared dependencies of those artifacts, exclude one of them, and then run your test suite. Assuming you have a comprehensive test suite if the tests past then you can reasonably assume that the dependency you excluded was not required by any of the parts of the library you utilized. You can do this for each of the declared dependencies.

Related

Remove extra and unnecessary dependencies from spring boot application [duplicate]

I have a large Maven project with many modules and many pom.xml files. The project has changed and I suspect the pom's contain some unnecessary dependencies. Is there is a command which removes any unused dependencies from a pom?
The Maven Dependency Plugin will help, especially the dependency:analyze goal:
dependency:analyze analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared.
Another thing that might help to do some cleanup is the Dependency Convergence report from the Maven Project Info Reports Plugin.
You can use dependency:analyze -DignoreNonCompile.
This will print a list of "used undeclared" and "unused declared" dependencies (while ignoring runtime/provided/test/system scopes for unused dependency analysis.)
But be careful while using this:
As some libraries used at runtime are considered unused!
For more details refer to this link
As others have said, you can use the dependency:analyze goal to find which dependencies are used and declared, used and undeclared, or unused and declared. You may also find dependency:analyze-dep-mgt useful to look for mismatches in your dependencyManagement section.
You can simply remove unwanted direct dependencies from your POM, but if they are introduced by third-party jars, you can use the <exclusions> tags in a dependency to exclude the third-party jars (see the section titled Dependency Exclusions for details and some discussion). Here is an example excluding commons-logging from the Spring dependency:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.5</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Have you looked at the Maven Dependency Plugin ? That won't remove stuff for you but has tools to allow you to do the analysis yourself. I'm thinking particularly of
mvn dependency:tree
I had similar kind of problem and decided to write a script that removes dependencies for me. Using that I got over half of the dependencies away rather easily.
http://samulisiivonen.blogspot.com/2012/01/cleanin-up-maven-dependencies.html
You can use DepClean https://github.com/castor-software/depclean/
DepClean is a tool to automatically remove dependencies that are included in your Java dependency tree but are not actually used in the project's code.
You can use dependency_cleaner https://github.com/junaidbs/dependency_cleaner
This jar will help to identify and remove unwanted dependency from pom.
It will automate the process of Removing a dependency and run then check whether the dependency needful
If you are using eclipse, right-click on the jar in Maven Dependencies:
Select Maven -> Exclude Maven Artifact...

Does Maven need to explicitly specify the dependency that Spring/Hibernate dependented?

I'm new to Maven, I try to use Maven with Spring, Hibernate in my project. After go though the Spring and Hibernate reference, I found that "there is no need to explicitly specify the dependent liberaries in POM.xml file for such Apache commons liberaries".
My questions is that : If my other parts of project refer to Apache commons liberary, such as commons-io, SHOULD I explicit specify this dependency in POM.xml file?
You should define those dependencies in Maven which your project is using. For example, even though some library depends on commons-io but if your code needs this then you should directly define commons-io in your pom.xml
You should not worry about the dependencies of the libraries you have defined in your pom.xml. Maven will do that for you.
Maven is used to avoid the issue of having to run down JAR files that are dependent on other JAR files. Of course you do not HAVE to use maven to do this, but you should. Maven will automatically download the dependent JAR files of the JAR file you require. THe hibernate-entity manager JAR file, for example, has over 100 dependencies and maven does the work for you.
Anyway,even if you do add the commons-io file to the build path/classpath of the maven project,and then update the project configuration, maven will kick it out.
You can provide a lib name on a site like mvnrepository.com to see what it depends on (e.g. take a look at a section called "This artifact depends on ..." in case of spring-webmvc library). Those dependencies (which your artifact depends on) are called transitive dependencies. You don't have to specify these in your pom.xml as maven will resolve them for you.
For the sake of readability you should only state those dependencies in your module that you rely on directly. You want JUnit to test your software, only declare JUnit; you need hibernate to use ORM, declare hibernate, and so on. Leave the rest to Maven.
And most of the time you should state what you intend to use in the very module you want to use it in. So if you want to use a dependency in more than one module, consider moving it into a dependencyManagement block in a parent pom and referencing it from there in the module you want it in.
parent pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
child pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
This guarantees you version-stability and still allows you to find out what a module uses by only looking in it's pom (and not all over the place).

Maven: Include POM with used dependencies in assembly

We deliver our package with many external dependencies to customers. Now customers can use you libraries to develop stuff on top. For those who are also using Maven we would like to include a pom.xml file in the assembly which contains all dependencies, so they can simply use it in their Maven build:
It should contain all dependencies used by us as follows:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math</artifactId>
<version>2.1</version>
<scope>compile</scope>
</dependency>
Is there a way to achieve that in Maven?
The pom.xml for your jar/war is by default placed inside your jar/war in the location META-INF\maven\<groupId>\<artifacdId>
You have two choices:
The first one which is the most common and preferred way is relying on Maven's transitive dependency resolution.
Have a POM (assume called foo-api:1.0) in your project that declares the dependency (e.g. A:1.0:jar, B:1.0:jar).
Developer's own project (bar:2.0) should then simply depends on foo-api:1.0. Maven will simply include A:1.0:jar and B:1.0:jar as dependency of bar:2.0, through the transitive dependency resolution.
Another way is similar to the above approach, but use foo-api:1.0 as parent POM of bar:2.0.
Either way should work but which one is suitable depends on your design.

maven circular dependency + inheritance best practice

I have a few projects in the following structure: Project A, B, C
They are all under a parent project D. in pom.xml under D folder:
<module>A</module>
<module>B</module>
<module>C</module>
The dependency among them is like : A<--B<--C.
And A,B,C are sharing lots of common dependencies.
1.What's the best practice to organize the dependencies in this case in order to make sub poms very light, also the duplicated dependencies are excluded?
2.What should be put into "dependencies" section and what should be put into "dependency-management" section of the parent pom?
3.common dependencies are more like:
log4j, slf4j, thrift, jetty, javax.servlet etc...
most of them are transitive dependencies other than directly required by my projects. Does it make sense put them in the parent D's pom.xml as dependencies, let the sub projects(A,B,C) to inherit them from D? I noticed that if you do so, mvn dependency:tree is going to give you warning like.
[WARNING] Unused declared dependencies found: log4j, slf4j ....
If that gives me warning, I assume it's something maven doesn't recommend u to do?
Most important: Only declare dependencies directly required by a module. It is difficult to suggest anything specific without knowing more about your modules and their dependencies. What are examples for common dependencies in your case? Maybe reorganizing your modules helps in reducing common dependencies. Depending on your project it might be reasonable to put all classes from your modules A, B and C that depend on the same artifact into a new module E.
In my opinion nothing should be put into the dependencies section in the parent pom (and seeing the warning, it seems maven feels the same ;-)). At least put all the versions of dependencies used in more than one module into the dependency-management section of your parent. This helps to always stay at the same version of a specific dependency over your whole project.
As in 2. you should only specify the version of these artifacts in your dependencies-management section in the parent and repeat them in each module that needs it without specifying version. As stated in 1. you should only specify the direct dependencies. For example if you are using slf4j you should only need log4j in the module containing your main class.
To sum up:
Declare only direct dependencies of a module, transitive dependencies are handled automatically by maven (this is one of the main reasons to use maven at all).
Only declare needed dependencies: For example in the case of slf4j you only need one module depending on slf4j-log4j12, all the other modules need only to depend on slf4j-api.
Define versions in your parent pom so all submodules use the same version. Do this in the dependencyManagement section like this:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>
</dependencyManagement>
For each module specify all direct dependencies in the modules pom but without version like this:
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
To handle a lot of dependencies that are shared by a lot of modules you can also use this method: Create a new "dependency collection module" (let's call it X) that does nothing but depend on each needed artifact. Now each module only needs to depend on X to automatically depend on its dependencies too. I don't recommend this method though because (among other reasons) now each module relies on the dependencies in X and you cannot be sure what happens if you remove a dependency from X and you need to look at more than one pom to find a modules direct dependencies.
Hope this helps a bit :-)

Is there a simple way to remove unused dependencies from a maven pom.xml?

I have a large Maven project with many modules and many pom.xml files. The project has changed and I suspect the pom's contain some unnecessary dependencies. Is there is a command which removes any unused dependencies from a pom?
The Maven Dependency Plugin will help, especially the dependency:analyze goal:
dependency:analyze analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared.
Another thing that might help to do some cleanup is the Dependency Convergence report from the Maven Project Info Reports Plugin.
You can use dependency:analyze -DignoreNonCompile.
This will print a list of "used undeclared" and "unused declared" dependencies (while ignoring runtime/provided/test/system scopes for unused dependency analysis.)
But be careful while using this:
As some libraries used at runtime are considered unused!
For more details refer to this link
As others have said, you can use the dependency:analyze goal to find which dependencies are used and declared, used and undeclared, or unused and declared. You may also find dependency:analyze-dep-mgt useful to look for mismatches in your dependencyManagement section.
You can simply remove unwanted direct dependencies from your POM, but if they are introduced by third-party jars, you can use the <exclusions> tags in a dependency to exclude the third-party jars (see the section titled Dependency Exclusions for details and some discussion). Here is an example excluding commons-logging from the Spring dependency:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.5</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Have you looked at the Maven Dependency Plugin ? That won't remove stuff for you but has tools to allow you to do the analysis yourself. I'm thinking particularly of
mvn dependency:tree
I had similar kind of problem and decided to write a script that removes dependencies for me. Using that I got over half of the dependencies away rather easily.
http://samulisiivonen.blogspot.com/2012/01/cleanin-up-maven-dependencies.html
You can use DepClean https://github.com/castor-software/depclean/
DepClean is a tool to automatically remove dependencies that are included in your Java dependency tree but are not actually used in the project's code.
You can use dependency_cleaner https://github.com/junaidbs/dependency_cleaner
This jar will help to identify and remove unwanted dependency from pom.
It will automate the process of Removing a dependency and run then check whether the dependency needful
If you are using eclipse, right-click on the jar in Maven Dependencies:
Select Maven -> Exclude Maven Artifact...

Resources