What is the easiest way to determine if a Maven dependence is actually used? - maven

I have a few dependencies in a Maven pom I am trimming. To check them I comment the dependency out and re-run the build. If it failed, then the dependency is needed. If it did not fail, then I remove it.
Is there an easier, faster way to check if a dependency is required for a Maven build?

No solution will be perfect due to the dynamic nature of the java classloader.
A dependency analysis tool like JarAnalyzer will certainly help identify static or compile-time relationships between jars in a directory.
Dynamic or run-time relationships are much harder to determine, which is why one of the suggestions was to ensure you have a conmprehensive set of units tests that exercises as much of your code as possible.

Related

Is there a way to find which dependencies are used at runtime with Maven?

I'm trying to refactor a big project, and there is also a big pom. I want to refactor it and remove unused dependencies. I used
mvn dependency:analyze
to look at some unused dependencies. The fact is that some libraries used at runtime are considered unused, like this answer said: https://stackoverflow.com/a/42967645/18089908.
In addition, in my pom all the dependencies are missing the scope tag.
Is there a way to see which dependencies are required at runtime?
There is no general way to do this.
Read the docs and run your integration tests.

Reducing Maven Dependencies

I am using Maven to build my project. There are lot of dependencies which are in provided and runtime scope. The build size is large and I want to remove the unwanted dependencies. So is there any way in which I can check which dependencies are unwanted.
The best way to minimize dependencies to the ones you really need is to not embed that dependencies. If you simply use the maven-bundle-plugin on your code it will create Import-Package statements for the code you really need. This might even give you a good hint on what dependencies you might be able to exclude for embedding.
In general in OSGi the goal should be to not have that many dependencies in the first place. If you use libraries with extensive dependencies then your should question the quality of these.

Maven reduce bundles size by excluding unneeded dependencies in bulk?

The project I'm working on has dependencies on a few well known and big libraries. Things are working well, the transitive dependencies are playing nice with each other, for now. But unfortunately the total bundle size is around 100 megs.
I'm not sure if this is too large or not, but is there a way in maven to effectively remove dependencies, without making pom.xml very verbose and long?
And pointers to help me in the right direction would be awesome!
You can remove dependencies by declaring exclusions. The question I would post to first though is .. why do you want to remove them?
Unless you know that the dependencies are not needed, it might not make sense to try to remove them. Especially not if there are no issues e.g. in terms of application performance or startup times.
The Maven Dependency Plugin as well as the Eclipse integration have tools that allow you to understand the dependencies better with tools like the dependency:tree goal or the Dependnecy Hierarchy view of the POM.
Don't try to fix something that is not broken.
BUT ..
if you really know what is needed at runtime and use the tooling from Maven and M2e you can potentially remove a lot of bulk of your final artifact. However you will have to configure it in the pom using dependency exclusions. Newer Maven versions even allow patterns being used.
Another thing you can do is use a tool like proguard that removes all unused classes from the final artifact. This can be considerably complex but also VERY effective.
It will really be up to you to find the right balance between effort and benefit of outcome.

Maven exclude philosophy

What maven Excluded dependencies was invented for?
Should I care to exclude any dependencies other then for fixing libraries conflicts?
What would good maven project architecture look like:
tend to exclude as much as possible
or as minimum as needed?
I don't know the reasons for the design but I've seen it used in the following cases:
I had a library which had junit as a compile time dependency so JUnit code leaked into my production code.
I had a library which uses log4j. Since I'm using slf4j, I used dependency exclusion to get rid of the hardwired logging framework and used a slf4j-log4j bridge instead so I could ultimately log to logback.
In another case, I was using only some features of a framework and didn't need all the dependencies. Since they weren't optional in the first place, I used exclusions to keep my classpath lean and clean.
General rules:
Use it to get rid of things that break your build
Get rid of things that you're replacing with something else
Get rid of things that you know you don't need (optional)
If none of the rules apply, leave the dependency alone; chances are that the immediate dependency might change over time and suddenly, it will need some dependency that seemed superfluous before and you code will unexpectedly break.
In addition to Aaron's answer:
An exclusion is usually needed when the provider of the dependency did something wrong (i.e. did not make a dependency optional where he should have, included an actual logging backend - as opposed to api - or used the wrong scope).
The one exception is logging frameworks. See Aaron's answer for that.
So no, do only exclude dependencies if you have a specific reason to exclude them.

Freezing transitive dependencies on maven release to get build fully reproducible

A problem that relates to basic maven concepts:
Once released I would like to have a guarantee that the project build is fully reproducible. So all project and plugin dependencies, including transitive one, should be always resolved the same way.
Unfortunately it is not the case, if dependencies are expressed in terms of version ranges. It can happen that even though direct dependencies of a project are set (using versions:use-releases), the transitive dependencies can still be resolved in some other way in the future.
How to address the problem? Is there a known solution?
I was thinking (just an idea), about creating a plugin, which on release time would dump all dependencies of the project to a separate file, and then once building in the future, the dependencies read from the file would take precedence over the standard way maven uses to resolve dependencies. But I'm afraid that there is no plugin api for that. So it would require some hacking, which I would like to avoid. Is there another way?
Thanks,
Lukasz
Freeze artifacts versions using <dependencyManagement>. Even if you don't use version ranges (as you said), but rather 3rd party libs (your dependencies) do, your <dependencyManagement> will have higher priority in specifying version of any artifacts.
The simple solution is: Do not use version-ranges. This is bad practice cause it will result in the described problems.

Resources