How to get all transitive dependencies programatically - java

I have seen many posts on this, but let me say that i am not trying to write a plugin.
I am making a project analyser which needs to find out resolved dependencies with their path.
Given a pom.xml(in a project) i want to find out all the dependencies(transitive too) with their paths and if possible the missing dependencies too.
Getting a version independent solution would be bonus.
PS: Every answer is suggesting to use exec to run the command on cli, i am already using this and want to find a better approach of doing this.

You could use the maven dependency plugin. The two that I have used and found very helpful I've mentioned below:
dependency:tree
Displays a tree structure of the entire dependencies both direct and transitive used. Be sure to use the verbose mode.
Link
dependency:list
Displays all dependencies used in a project in a list fashion. I personally do not find this that handy at times when I need to know what are transitives and which are direct for licensing purpose. But it has its place when you just need to know what you are using or detecting duplicate libraries with different versions.
Link
In addition there is also analyze, when reading the documentation it seems quite handy but I would need to try this out and I will.
dependency:analyze

Use mvn dependency:tree. For programmatic access simply use the java Process api.
http://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html
Java Process with Input/Output Stream
Also Maven plugins are simple java classes. You can download the dependency:tree plugin's code and use it/modify it to your taste.

Related

Mill Build Tool - Install dependencies without compiling source code

I'm using the Mill Build Tool for a Scala project, which uses a build.sc file to list specific dependencies for different modules within the project. Now, I'm trying to dockerize the project and would like to install the dependencies in the image before having to copy over the entire repository. I want to avoid this, so that the dependencies don't have to be installed every time I make a small change in the source code. Is there any simple way of doing this? Thanks!
Here's a similar post for sbt: sbt only fetch dependencies
Updated answer:
Since mill 0.9.3 there is support to easily prepare offline work.
See pull request #951 for details.
In short, you can use the prepareOffline target to fetch dependencies in advance.
mill __.prepareOffline
Original answer:
There is currently no easy and straight forward way of doing this. Although you can force the resolution of all compile dependencies by running mill __.compileClasspath, but this will also trigger the compilation of all inter-module dependencies.
As a work around you could try to generate IntelliJ IDEA project files, which will also trigger dependency resolution. Afterwards you can delete the generated directories (.idea/ and .idea_modules/).
Technically, it is quite simple to introduce a new fetchIvyDeps target for exactly that purpose, but it's not there yet. You might want to open a feature request or create a pull request.

Creating dependencies from directory

Does anyone know a tool to create the Maven dependencies from a lib directory? I have several web projects with quite a lot of JARs and would like to "mavenize" them. Looking for the proper dependency for each one is quite a pain and seems like something that may be solved with a program.
Well, since these jars (presumably) didn't come from Maven in the first place, they won't contain a manifest that tells your their GAV co-ords. So it's hard to see how a tool could infer what's needed from just a directory. Unless you're phenomenally lucky and every jar has the exact arteface ID and version in the filename, in which case you might be able to script something.
You probably don't want that anyway. A lot of those jars, I'm betting, are transitive dependencies, and you don't really want them littering your POM.
tl;dr bite the bullet and just Mavenise it by hand. You could always write a script that uses a bit of wget magic against the public repos or something, to help you along the way.
Ant2Ivy https://github.com/myspotontheweb/ant2ivy is a Groovy script that can do this.
Despite its name, it can also create pom files (https://github.com/myspotontheweb/ant2ivy/commit/9e3e8358f2b31507b13f5def69627da422e1656b).
It looks up the names/hash in Maven Central for you in order to create the pom.
You can write a plugin which adds all the dependencies (with <scope>system</scope> to the project's dependencies list. You can check how to do this by having a look at the build-helper-maven-plugin.
I would strongly object doing this. Look, if you're going to use Maven to do your Ant monkey-business, just use Ant for that. Will save you time and effort.
If on the other hand you would like to "Mavenize your build", you should really Mavenize it properly and not be lazy about it. Solutions are only as crappy as you make them. If you're lazy, they'll be a mess either way, so the effort would be pointless.
I suggest you add each of the dependencies using either of:
search.maven.org
www.jarvana.com
www.mvnrepository.com
www.versioneye.com
And do the job right. In addition, install an artifact repository manager as well. :)
Good luck.

Best Way to Setup Solr (Ant vs Maven)?

I have a project that's currently built with ant that pulls the latest trunk version of Solr in through git and then builds through ant. I'm pretty used to Maven and its system for dependencies at this point and find our old ant way of doing things pretty messy and hard to maintain. With that said, basically everywhere I seem to look online, people are building solr with Ant, and the few tutorials I found for doing things with Maven are all along the lines of this one, which doesn't seem to work.
So, to be clear, all I'm looking for here is a clean way to develop the project in Eclipse and to be able to deploy it. I'm sure someone must have done this before and must have a good answer. I'd be really interested in hearing it.
I just got it working by throwing all dependencies into Maven, making my own repo for a pegged version of Solr 4.0-SNAPSHOT, copying the web.xml from it into src/main/webapp/WEB-INF/, and running things through mvn jetty:run with salient variables passed in as arguments as:
mvn jetty:run -Dsolr.dataDir="./solr-data" -Dsolr.master-host="localhost" -Dsolr.solr.home="./solr-home"
This method is officially unsupported, but it means I no longer have to bother with ugly ant configs or holding all of Lucene and Solr in git repos attached to my project, so I could build from them. It also means changing/updating versions just requires a one line change in my pom.xml instead of digging through and switching a whole ton of extraneous configs. I'm pretty happy, and once I got a better feel for how Solr is supposed to work, reconfiguring the project really wasn't that bad.
This answer is probably more a comment, but a comment is too small to expose it all.
I know nothing about Solr, but from a neutral point of view, I would say you have two options:
Mavenize Solr (looks like what is suggested by your article). Maybe you could post another question on what problems you encounter using their solution.
Invoke the original ant tasks using the maven-antrun-plugin. This would also probably require to attach the built jars (or if it only contains classes/resources, jar them first). You could decide to install them locally using maven-install-plugin or attach them with maven-build-helper-plugin.
In eclipse, there are plenty of tricks to access the built files. You could simply add the project as a dependency.
This second option should work, but I don't find it very clean
You should be able to use Maven if you want, I know some of the Solr developers do. Have a look here: http://wiki.apache.org/solr/HowToContribute#Maven. This isn't the most supported way though, and I can't help you with this since I never tried it.
I actually work with Solr + Ant and there's basically a task for everything: ant test, ant dist and so on. I agree that's a bit old fashioned, but it works. Lately the build has been improved a lot introducing Ivy as dependency management tool, in order to remove all jars from the source tree.
Let me know if you have some specific problems with ant, maybe I can help you more.

How can I visualize jar (not plugin) dependencies?

I am currently refactoring a large Java application. I have split up one of the central (Eclipse) projects into about 30 individual "components", however they are still heavily inter-dependent. In order to get a better idea of what depends on what I am looking for some way to graph the compile time dependencies.
All tools I have found so far are capable of graphing package or class dependencies or the dependencies between Eclipse plugins, however what I have in mind should just take a look at the classpath settings for each Eclipse project and build a coarser grained graph from that.
Later I will then go deeper, however right now this would just mean I would not be able to see the forest for all of the trees.
Check out JBoss Tattletale. It might not do all you ask but it's worth checking out. It's still relatively new though.
The tool will provide you with reports that can help you
Identify dependencies between JAR files
Find missing classes from the classpath
Spot if a class is located in multiple JAR files
Spot if the same JAR file is located in multiple locations
With a list of what each JAR file requires and provides
Verify the SerialVersionUID of a class
Find similar JAR files that have different version numbers
Find JAR files without a version number
Locate a class in a JAR file
Get the OSGi status of your project
Remove black listed API usage
Structure101 is capable of visualizing class and method JAR level dependencies in Jboss 5.
See the screenshot below or view it larger.
One tool that I believe would do what you want is Understand. It's not free, but you can download a free trial edition before investing any money into it.
Take a look at Dependency Finder
I am not sure if there is a(n Eclipse) classpath analysis tool.
May be Understand mentioned by MattK can help.
The closest I would pick amongst all the static code analysis tool referenced here would be JarAnalyzer (no graph though), able to detect "Physical dependencies" amongst jars.
Sounds like a use case for Degraph. It analyzes a bunch of class files and jar's, and visualizes the dependencies.
What makes it suitable for your usecase (I think) is the possibility to define arbitrary groups of classes to be bundled together. So you can reproduce your jar structure, seeing dependencies, especially cyclic dependencies.
You can unfold the groups to see their contained classes or collapse them to simplify the view.
For a quick impression what is possible, take a look at the Degraph Examples.
Example for Log4j:
JDeps is already included in the JDK, and shows JAR dependencies. For example:
jdeps -R -cp "my\jar\dir\*;my\other\jar\dir\*" my\classes\dir
Check out Class Dependency Analyzer (CDA): http://www.dependency-analyzer.org/
I have found it very useful for tidying up jars.
for the record (and for improving this knowledge base), I found Shrimp very helpful:
http://www.thechiselgroup.org/shrimp
Also, for easy dependency-checking, Byecycle is worth a try, but seems not to be updated anymore:
Byecycle
Both tools also offer Eclipse integration.

How do you figure out with Eclipse which JARs depend on which one?

I've trying to use Eclipse JDT AST parsing classes. After including the initial JAR, and sorting out a couple more dependencies, it is with 7+ JARs and I still having NoClassDefFoundError exceptions. This situation arises whenever I'm trying to test libraries with little or no documentation. Trial and error seems a very dumb (and annoying) approach to solve this problem.
Is there a way to automatically sort this out using Eclipse?
Update: Later I found that adding all the JARs you have, and using Ctrl-T (to view/locate types), lets you manually locate the JAR. That was the solution that Google provided so far. Is there a better way?
If you refer to this SO question Finding unused jars used in an eclipse project, you also have:
ClassPathHelper, which can quickly focus on unresolved classes:
It automatically identifies orphan jars, blocked (obscured) classes, and much more.
The only limit is dependencies that are not defined in classes, e.g. in dependency injection framework configuration files.
I have found setting up a workspace exclusively for browsing the eclipse source code incredibly useful. In this manner, you can use PDE tools like the Plug-in Spy, bundle dependency analysis, browsing the documentation, etc much like you would your own plugin projects. I found this article at Vogella a very useful guide.
If you know which bundle your desired class is you can generate the transitive closure of dependencies by creating a new OSGi launch configuration, with just the single bundle selected. By hitting the Add Required button, you can see all bundles necessary to use the one you're interested in.
Edit:
From your question it wasn't clear as to the environment you want to run the compiler in. If you're interested in an embeddable Java compiler to be run outside of an OSGi environment, may I suggest Janino.
You could use a dependency analyzer like:
JarAnalyzer
This will parse a directory full of Jars and give you an XML output dependency map, for which there are several tools for displaying in either graphical or text form.

Categories

Resources