Local Nexus Maven repository for common java libraries - maven

We have a Nexus install that has a collection of commonly used java dependencies (commons-codec, jodatime etc.)
The directory structure is similar to the below
commonjavalibraries
|
|_ commons-codec
| |_commons-codec
| |_1.2
|_ commons-compress
|_commons-compress
|_1.3
I am in the process of adding the latest version of these dependencies to the repository.
To do this I have created a new pom and setup dependency management to deploy to Nexus.
However I now know that the groupId:artifactId:version attributes of the pom dictate how the project is deployed to nexus. Which I think would mean I'd need a separate pom for each group element.
How is the central repository pom managed? I realise it's possible to proxy the central repository, unfortunately our network doesn't allow downloading of jar's hence the need for a hosted commonjavalibraries repository in the first place.
Is there a way of doing what I'm trying to achieve without creating a pom for each group element?

After a bit more digging I noticed that when dependencies were downloaded from central they were stored in .m2/repositories along with their pom files.
I wrote a Python script to copy these into another location and then walk that directory tree and run mvn deploy:deploy-file for each jar/pom pair I came across.

Related

How to download only one jar with pom.xml?

I want to use a project called projectA that I have in a maven repository as dependency of a projectB.
The mvn deploy of projectA is successful (I can see in the repository the projectA-0.0.1-20190902.072951-1.jar, projectA-0.0.1-20190902.072951-1.pom and maven-metadata.xml files), but when I specify the dependency in the pom.xml file of projectB, the project works but it downloads two JARs of projectA from the repository:
- projectA-0.0.1-20190902.072951-1.jar
- projectA-0.0.1-SNAPSHOT.jar and the same issue for every file downloaded by the dependency to this project.
I think that only one JAR is necessary, and I don't know what I need to put maybe in settings.xml or in the pom.xml file of any project to get only one JAR when the dependency is downloaded.
Thank you so much for your help!
In the past it was possible to tell Maven to deploy Non-unique Snapshot Deployments but in Maven 3
... snapshot artifacts will always be deployed using a timestamped version
So:
the files with the timestamps are the one you have deployed to your remote repo (mvn deploy ...) and then downloaded from there as dependencies
the ones with -SNAPSHOT are the result of the local builds (install goal)
If your concern is download traffic - that is not an issue. The -SNAPSHOT ones are not downloaded.
If your concern is disk space then you can have a cron job or use something like Build Helper Maven Plugin to remove old version artifacts from the local repository.

Adding all jars from a Nexus repo to Leiningen dependencies list

I want to add all jars from the local Nexus repo to a Leiningen :dependencies list. I've added the Nexus repo to the :repositories list in project.clj. Is there any way to add all jars to :dependencies, instead of specifying them one by one?
Thanks!
pom to project
"Java project's lib folder contains lots of jars"
Does this Java project fetch these jars directly from nexus repo (e.g. via pom.xml), because it should.
And if it does, and you just don't want to manually craft project.clj with all these dependencies, you can use something like lein-nevam to convert it to project.clj to start you off.
less dependency, more independency
Does the Clojure library really need all these Java project's dependencies though? Or just a subset of them? As I mentioned in comments, it is always best to narrow down the number of dependencies due to many reasons: code collision, transitive dependencies, version management, compatibility, etc.. rather thаn to "just include them all"
In order to use Nexus you just have to configure Leiningen to use Nexus as the repository. Then you can specify all your dependencies as usual but they will be retrieved from Nexus. This can include components from Central, clojars and any other repo you want to add to the public group.
More details are in the Nexus book chapter about tool config and especially the Leiningen section.
If you then specifiy the dependencies you need in your library (and only those) and publish to Nexus with a pom that specifies these any Java project that uses Maven or Gradle or whatever to build can consume your library and will also get the correct transitive dependencies. Same is if your code was e.g., created with Maven and written in Java.

How does my pom find my parent pom if the repositories are configured in the parent pom?

I've refactored all repository configuration out of my various projects into a parent pom that I've created for the specific purpose of having a single point of configuration for stuff like repo's and distribution management. This is supposed to be best practice as I understand it. In deployed my parent pom to the nexus server, and then tried to run my child projects. They can't find my parent pom . . . this kind of makes sense to me since, wihtout the parent pom they don't know about the nexus repo . . . seems like a chicken and egg kind of thing? Am I missing something obvious?
It's true that your project needs to know where to find the repositories to download its dependencies. But before going to external repositories, Maven will check your local repository to see if the artifacts it needs are in there. Does your local repository contain the parent pom? If not, you can add it by running
mvn install
on the parent pom. The problem may have been caused by deploying the parent pom directly to Nexus, bypassing your local one. You can avoid this in future by deploying using
mvn deploy
This will first install the artifact locally, and then deploy it to the external repository (Nexus, in your case). More details here: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
If you're in a situation whereby your parent pom is built and deployed by others, this won't help. You can either specify the repositories in your project's pom, or in your local settings.xml. A common approach is to expect all developers to include a repository definition in their local settings.xml which points to your Nexus repository, using it as a mirror for all other repositories. You can then configure each external repository you need in Nexus, and let it retrieve any dependencies you need for you. I'm not familiar with Nexus, but more details on mirroring can be found here: http://maven.apache.org/guides/mini/guide-mirror-settings.html
You must maintain the repositories definitions for each child (maven module), this is main best practice in a build process: "Make the build portable".
Any developer/system should be able to build any module without source dependencies to the parent or other modules, only with the repository reference.

Unconventional dependency name in maven

I have a few dependencies like this. For example : jdic
In my pom.xml, I defined a dependency
<dependency>
<artifactId>jdic</artifactId>
<groupId>jdic</groupId>
<version>0.8.6</version>
</dependency>
And I have a remote repository (internal server): eg http://repo/thirdparty/
And jdic can be found in http://repo/thirdparty/jdic/jar/jdic.jar
As you notice, the naming is not conventional groupId:artifactId:version, instead its just jdic.jar
so when I run maven compile
mvn clean compile
maven tells me that it cannot resolve dependencies.
I'm aware that we can just download those jars to the local repository .m2/repository and run
mvn compile (ie without clean)
and it the jar will not be a problem. But is there any other way that I can make it retrieve from the remote despite its unconventional name and lack of metadata/pom info for those dependencies?
I already have a mirror to this internal repository that overrides the central
You could install the jdic in your internal/mirror repository with the version (jdic-0.8.6.jar).
If you are using a repository manager and you uploaded the jar to it, it would automagically create a pom for it as well as ensure the dependency was created with version, as per maven convention.
A remote Maven repository is NOT any web server putting files in any way you want. There are lots of convention to follow. One of them is the way to represent the version (which is one essential element of an artifact). With your "remote repository" it is clear that there is no way Maven can find the artifact.
Setup a real Maven remote repository to host such files. You can have a look in Nexus and Artifactory.

How do I add an artifact to a local maven repository so that it will properly reference its own set of dependencies?

I am developing an application that depends on a number of legacy JAR files and I want the project to build straight out of version control without other users having to install these JARs in their local repository. I cannot add them to the corporate repository so I have created a repository that is local to this project and I have added these JARs to that repository using maven-install-plugin:install-file and setup the repository entry in the POM file so it knows to search the local repository.
This works exactly the way I want...up to a point. The problem is that most of these legacy JAR files have their own set of dependencies. I would like for them to work just like other artifacts that have their own set of dependencies so that maven can resolve everything and include all the necessary files but I can't find a way to do this with any maven-install-plugin:install-file options (or any other maven commands/plugins). I am pretty new at maven so I am probably just ignorant on this point.
As a work around, I attempted to go into the local repository directory and manually edit the POM file for the artifact to include the dependencies. This didn't cause any errors but it is also not pulling in those dependencies.
Can someone out there give me a clue?
The maven-install-plugin:install-file goal has a pomFile attribute. You can use this to specify a POM file for your legacy jar. You would create a POM file that points to all of the dependencies by artifactId in the <dependencies> section. If you have a remote nexus repository you can use the admin screen for the repository to deploy a jar.
Once you edit POM files in your project specific repository, host it as maven repo using Maven Repository Managers (like sonatype nexus). Add your project nexus repo as one of the maven repo in project pom.xml as below
<repositories>
<repository>
<id>my-project-mvn-repo</id>
<name>my-project-mvn-repo</name>
<url>http://<your project maven repo URL here></url>
</repository>
<repositories>
Now all developers should be able to make build. The legacy jar files POM contains dependency. Maven should take care of automatically pulling dependent jars on developer's workspace.

Resources