Install 3rd Party Libraries with Transitive Dependencies / Dependency Tree? - java

I am a Maven newbie and spent hours to learn the basics, but I still have not found any good documentation how to install locally a 3rd Party JAR with all its (transitive) dependencies.
I know mvn install:install-file does install a single JAR. But how to install locally in the repsoitory something like this:
+ Parent.jar
+ ChildA.jar (Requuired by Parent)
+ ChildB.jar (Required by Child A)
To make it more complcated and real life: Parent.jar and ChildA.jar are legacy/commercial Jars not available in the public maven Repository but the Child B is a jar that is found in the public repository (for example like a logging jar).
UPDATE: I do not only want to install them locally (with a system dependency) but to also "correctly" integregrate them with maven so i can redistribute this dependency tree to other developers or the public (and I assume this is important for maven), so that maven knows and understands the dependecytree (to avoid version conflicts, unnecessary downloads etc...)
Any links or information how that exaclty describe how this can be done would be great.
Thank you very much!!
Marks

If it's a commercial jar, you may be in violation of the license if you deploy it to a central repository, and the only recourse is to deploy to your company's repo (if you have one setup).
In order to do that you need to define a pom for childA, specifying childB as a dependency, then run the install:install-file goal for that. Then do the same for parent, with childA as it's dependency.
Once you do that, you can then take those items, and upload them pretty easily to your company's central repo through it's GUI (both Nexus and Artifactory support this through the GUI).

Since you actually want to actually publish so that others in the public can use it with the defined dependencies, you pretty much have to get the 3rd party jars into a publicly available repo.
Here are instructions on how to accomplish that.
Please note though, the licensing for the code may not allow you to publish it to a central repo. This is checked before it can be deployed.

I think, you maybe look for this.
Maven will load all needed dependecies into the local repo itself if they are availebale in the online repo. If you want to install your own projects, setup the reactor with profiles to have all wanted modules in it and run mvn install -P yourprofile on it. More about profiles can be found here. Afaik is there no way, to install projects including their dependencies into the local repo.

if you need to install it to a local Maven repository, just use
mvn dependency:go-offline

Related

How include 3rd party jars in maven project (compile, build, package) where adding local maven repo is not an option?

We have a git project that has some 3rd party jars which are not available in any Maven repo and are in a "lib" folder in the project. I need to include them for compiling, building and then package them into the WAR in WEB-INF/lib.
I cannot add them as a local maven repo from the command line because this projects needs to be buildable for anyone cloning the repo without requiring them to run extra commands (I have no way around this requirement).
I saw some people suggesting System scope but that then Maven won't package them into your WAR:
<dependency>
<groupId>com.roufid.tutorials</groupId>
<artifactId>example-app</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/yourJar.jar</systemPath>
</dependency>
How do I get these jars to be used for compiling/inspection, building and then packaged into the WAR?
You can use :
System scope but make the packaging yourself via assembly plugin
A maven repo along with your project (i.e. maven repo on-the-fly, basically same as local repo but without having a extra moving part to worry about because this repo follows your project).
For Maven repo on-the-fly option, you can do as described here (which is, take any already existing Maven repo, which already contains your needed jars, such as your local one, put it in your project, and then reference this repo from your project using relative paths).
I'll assume you've verified that whatever mechanism you might use to distribute these jars would be in compliance with the relevant licenses. If it would, then it seems there would be little reason for the jars' creators not to provide for official Maven distribution, so your best option might be to lobby for them to do that. But if not, and yet for some reason they'll allow for you distributing the jar (either through cloning of your repo, or via a separate Maven repo you maintain):
There are several ways. I give preference to approaches that don't put the jars in the git repo.
Publish a Maven Repo
So it's possible to host a public-facing repo and serve the artifacts that way. The pom can add your public-facing repo to the build, so that those who clone can build without having to run any special commands.
Running your own repo isn't terribly difficult. The OSS versions of Nexus or Artifactory jFrog would probably be perfectly capable.
But, if we're assuming the authors' refusal to publish their own jars via Maven means they don't want them distributed that way, then there's no reason to spend much time on the details of this option. So moving on...
Distribution in the Git Repo
I guess this is what you're doing, though again if Maven distribution violates the license I'd make sure you're splitting hairs the right way in thinking that this doesn't.
So the question would be how to get Maven to deal with the artifacts distributed in this way, and again there are some options.
Your objection to putting the jars in the local repo is that it would require extra commands of the user; but actually this could be automated in the "validate" phase of the build. Binding install:install-file to the validate phase should work.
Alternately, your objection to using system scope is that the file isn't copied into the final war. You might be able to use the dependency plugin to force the issue, but I'm not sure of that. What I am sure of is you could treat the directory containing the jars as a web resource with suitable configuration in the war plugin. (You'd want it to be treated as unfiltered and to map to the WEB-INF/lib folder.)
In any case, if you distribute jars (or other large binaries) in the git repo, I strongly recommend you look at git lfs. This will require one-time configuration by each of your users, but it will prevent your repo from gradually becoming bloated and unusable.
Use forward slash (/) to backslash () in the systemPath.
<dependency>
<groupId>com.roufid.tutorials</groupId>`enter code here`
<artifactId>example-app</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}\lib\yourJar.jar</systemPath>

Maven and dependency:sources goals: use alternate repository to download sources?

I am working with an enterprise Nexus repository, whose contents is rather static, meaning it is not a copy of central, but a snapshot at some time.
This Nexus repository does not contains sources classifier. Hence, when I launch one of those goals:
mvn dependency:sources
mvn eclipse:eclipse
I've got a lot, if not all, of dependencies without sources.
What I want to do is pretty simple: I want to tell dependency and eclipse plugins that they should use the central repository only when looking for sources.
If that possible natively?
Can I do that with Nexus and how ?
If you are not even the manager of this Nexus server you are out of luck. You can only work around it by using another Nexus server, maybe installed locally, that does access central as well as your corporate, locked-down instance.
However, most likely, you are not allowed to do that.. locking it down was the reason to have a static repo in the first place.
I would suggest to work with the Nexus administrator to add javadoc and sources to your static repo.
And btw. I have a little tool that can provision a repository called the Maven Repository Provisioner and it can include javadoc and sources. Check it out at https://github.com/simpligility/maven-repository-tools

Install Library and Its Dependencies From Maven Repository Into Internal Repository

Question
I have an internal maven repository in a shared folder say s:\mvnrepo – it's just a convention for a directory layout after all. Now I want to install a library com.example.lib:lib:1.0.0 and its dependencies from another external maven repository into s:\mvnrepo with the hypothetical command
mvn installlib com.example.lib:lib:1.0.0 -Dinto=file:///s:/mvnrepo
That would be a dream! Is such a thing possible?
(I don't have high hopes seeing as everything maven related is always so unapproachable and complicated...)
Supplemental Information
Now, I know there are maven repository management systems like Nexus but I really do think my use case should not require them. I also know about the deploy-file goal but it doesn't install transitive dependencies into the specified repository.
I also thought about simply creating a dummy project that has the specific library listed in its pom.xml. Then just execute mvn install -Dinto=file:///s:/mvnrepo. The problem is that the install goal apparently does not have an option to specify the repository directory (i.e. -Dinto is purely hypothetical).
I found out that it is possible to download a library and all its dependencies with Intellij. That's great but Intellij really only downloads the jars and does not create a maven compatible directory structure (i.e. there are no poms downloaded nor are the jars in a group subfolder etc.).
Background information
For work we want to have an internal maven repository such that it is possible to build an application on a freshly installed server that does not have an internet connection while still being able to specifiy dependencies in the gradle file as if we would use an external maven repository like jcenter (resp. bintray). So the gradle file we use would look something like this:
repositories {
// jcenter() // we don't want that
mavenUrl 'file:///s:/mvnrepo'
}
dependencies {
compile 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
}
Now, I downloaded the sdkmanager plugin jar and its pom file from mvnrepository.com and used something like
mvn deploy:deploy-file -Dfile=sdkmanager.jar -Dpom=sdkmanager.pom -Durl=file:///s:/mvnrepo
All fine and dandy, the sdkmanager plugin is installed into s:\mvnrepo with the correct directory layout and gradle even picks it up! But gradle is not quite satisfied, you see. It demands the jarchivelib which is a dependency of com.jakewharton.sdkmanager:gradle-plugin:0.12.0 (see the page on mvnrepository.com where jarchivelib really is listed as a dependency of the sdkmanager plugin). Now, I could repeat the fun and download jarchivelib and its pom from mvnrepository.com, deploy it and so on. Thinking about it... that does not sound like fun at all! So now you see my concrete use case and maybe you could suggest an even better approach than what I seek for in my question.

How to create local Maven repository for hosting non-Mavenized libraries?

Here's the problem: I love using Maven, as it completely simplifies development and dependency management. However, I'm working with a server which isn't Mavenized, so I can't just add it as a provided dependency. Is there a way to simply specify an additional library folder and add it to the Java compiler classpath, or would I need to actually create an entire local Maven repository for this? I know it completely limits my portability, but I'm okay with that. Thoughts? Also, after compiling, I'll need to copy all of my non-provided dependencies to the local server lib directory, I assume I can use the copy-dependencies plugin to move everything over.
Download Nexus for free from Sonatype, or Artifactory, or any of the other repository managers.
The alternative is to learn about install:install-file to shove jars into your personal local repo. However, having a full repo as above has so many advantages (not the least speed via caching) that it's easier to just install one.
You can use a Maven2 repository implementation such as Nexus, Artifactory, or Archiva.
You can create a simple POM for the non-maven dependency you are working with and use the deploy:deploy-file goal to deploy it to the repository.
If you just need the dependency locally you can use the install:install-file to install the dependency in your local repository. This approach requires nothing more than maven be installed on your machine.
If you just want to add libraries to the path of your build without worrying about repositories you can declare them as system dependencies. I do not recommend this approach but it should work fine.

How to add javax.* dependencies in Maven?

I am getting tired of manually installing javax jar files in Maven and would like to know what is the best solution to include a dependency on javax.cache, javax.transaction, or other JSRs that are not easy to find in Maven repositories.
Have you seen https://people.apache.org/~ltheussl/maven-stage-site/guides/mini/guide-coping-with-sun-jars.html ?
This link suggests groupID and artifactID's to use, as well as a java.net repository.
It looks to me like almost all of these exist in the central Maven repository under this naming scheme.
I'm not aware of one, but adding the java.net repository may help you with some of these dependencies:
<repositories>
<repository>
<id>java.net repository</id>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>
If building on more than one box and/or for team development, a local (intranet) maven repository manager can help with these "missing" jars. This centralizes the configuration and management of not only 3rd party jars that are not in a public repository, but also all external repositories in general. It could also help automate your builds, creating more 'reproducable' builds (e.g., if you have a pool of continuous integration servers).
install a mvn repo mgr (see list -- imo, nexus is really simple to start with);
use a custom settings.xml that includes a "mirrors" section pointing to your intranet mvn repo mgr. Either update your ~/.m2/settings.xml, or run maven with "mvn -s etc/settings.xml"-- useful for hudson builds, where you don't want a custom per-user settings.xml;
manually upload your 'problem' jars to your internal repo (again, super-simple w/ Nexus via a web-interface);
set up the internal mvn repo mgr as a "mirror" of repo1.maven.org/maven2, codehaus, java.net, ... (etc).
Now, you can centrally define all 3rd party repositories & 3rd party jars -- rather than requiring each person, each box and/or each project define them individually in their pom or settings.xml. Each project / person / box would ONLY define your central, internal maven repo as the single repo for all maven projects.
This also really speeds up your artifact re-download time for fresh builds, or for those times when you need to (or would like to) delete your local ~/.m2/repository cache.
Repo managers: nexus, archiva, artifactory... e.g.,: maven.apache.org/repository-management.html
- http://docs.codehaus.org/display/MAVENUSER/Maven+Repository+Manager+Feature+Matrix
javax.cache are in jcache:jcache:1.0-XXX artifact (in Maven's central repo)
<dependency>
<groupId>jcache</groupId>
<artifactId>jcache</artifactId>
<version>1.0-dev-2</version>
</dependency>
javax.transaction.* classes are in javax.transaction:jta:1.1 artifact, JTA jar can’t be inserted in the Maven repository because the Sun’s Binary License (I know, this sucks). To use it you need to download manually the JAR (it's free) and put it into a local repo or use 1.0.1B version which is contained in java.net.
NOTE: I've read in some place JTA will be integrated in future versions of the JDK
I know is really a pain to find these artifacts in Maven's repositories but you can make a search of a class in www.mvnrepository.com and it will show you the correct groupId and artifactId for mostly all the packages.
In the particular case of JTA, I hit this post:
http://www.jugpadova.it/articles/2005/11/26/maven-2-spring-and-jta-depencies
.. which makes sense, if I didn't have to spend a lot of time in Oracle's horrible site to get the forementioned JAR file. (I was an Oracle's enthusiast myself but that site could use a lot of UX rework here and there).
I decided to replace the dependency with what Hibernate provides, via Geronimo, as per this post (worked perfectly):
https://forum.hibernate.org/viewtopic.php?p=2420836
The deal with Java licensing and Maven is currently being worked on by the Hibernate team, or so it seems here:
https://hibernate.onjira.com/browse/HHH-4548
Thanks to everyone for sharing!

Categories

Resources