Maven Internal Repository, Is it Really This Hard? - maven

I have several projects which use Maven and I would like to run an internal repository on my work network. I have several libraries which are from third parties and cannot be released into the wild, as well as a few libraries of our own which need to be available within the network (including to our TeamCity CI Server) but cannot be deployed outside the network. After a bit of research, I found three main recommendations on how to accomplish this: Archiva, Artifactory, and Nexus. I have tried each, and have failed to achieve a successful build of any of my projects using the internal repositories created by any of them.
This leads me to believe that I am misunderstanding something or doing something wrong. Does anyone know of a tutorial that will walk me through setting up and internal Maven repository and integrate it with my project?

I have only worked with Nexus, but I found it very easy to install:
Go to http://www.sonatype.org/nexus/go to download the OSS version
Get the 'WAR' distribution
Install the servlet in my installation of Tomcat, via the Web Application Manager
At that point, I can visit http://myserver:8080/nexus to see everything working.
For a superficial setup, I add the default password to my settings.xml:
<servers>
<server>
<id>my-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>my-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
and in my POM file:
<distributionManagement>
<snapshotRepository>
<id>my-snapshots</id>
<name>My internal repository</name>
<url>http://myserver:8080/nexus/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>my-releases</id>
<name>My internal repository</name>
<url>http://myserver:8080/nexus/content/repositories/releases</url>
</repository>
</distributionManagement>
To go beyond this, the learning curve jumps up quite a bit, but I found Sonatype's online books to be pretty good. Repository Management with Nexus is the one for understanding what you can do with the repository server. The only thing I found tricky is that some of the info applies only to their commercial software and they don't work too hard to advertise the difference.

Repository managers like Archiva and Nexus are more than just an internal repository. They serve as proxies that obviate reaching out to Maven central or other external repository.
For just an internal repository all you need is a network or HTTP accessible location that has the structure of a Maven repository. Then you refer to it as another repository in your settings file.
<repository>
<id>my-internal-repo</id>
<url>http://myrepo.mycompany.com/</url>
</repository>
See more in Maven's documentation at http://maven.apache.org/guides/introduction/introduction-to-repositories.html.

I would suggest to use the Nexus evaluation guide (latest available version is 2.13 now) that comes with the Nexus Pro Installer, but also works with Nexus Open Source for the simple use cases of proxying and deploying components.
The examples are also available on github and include setups for Maven, Ant/Ivy and Gradle. Once you have a look at the examples and read the guide you will be able to set up your projects in the same way easily.
And of course if there is any problems you can always ask on the mailing list or chat with the developers on hipchat

Related

How to reference public GitHub packages from maven project

I have a GitHub repo with a library published to its own GitHub packages maven repository. And I also have another project where I want to reference this library as a dependency.
When I add the following configuration to the POM file of my project it just doesn't work.
<repositories>
<repository>
<id>github</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/test-account/test-lib</url>
</repository>
</repositories>
It requires me to authenticate. I understand that this is pretty logical as it is basically not a sources repo but an underlying maven repo. But is there a way to have normal maven access to this dependency? My library is in the public repo.
P.S. Please, do not suggest using Jitpack as I would like to have clean solution without any additional resources.
The answer seems to be "you can't". See this comment from a GitHub staff member:
Our Maven service doesn’t allow for unauthorized access right now. We plan to offer this in the future but need to improve the service a bit before that.
For now the simplest option seems to be to create a personal access token with read access and include it in the URL of the <repository> section in your pom.xml, like this:
<repository>
<id>github</id>
<name>GitHub Packages</name>
<url>https://my-user:b96e7de7514e45c5#maven.pkg.github.com/my-user/my-repo</url>
</repository>
Otherwise, options are probably:
Create a personal access token with read access and just share it with the whole world.
Use the workaround described here
Publish to Maven Central (but that's a whole world of pain)
Currently, you cannot. There is an ongoing discussion here with this feature request. You can find multiple workarounds in that discussion thread and also voice your opinion.
The accepted answer no longer works.
Currently GitGuardian automatically revokes the Personal Access Token (PAT) if that method is applied in public repositories. As recommended by GitHub staff, the work-around solution is the following:
Create a PAT with just the read:packages scope
Execute docker run ghcr.io/jcansdale/gpr encode
This will output the following:
$ docker run ghcr.io/jcansdale/gpr encode 0123456789abcsef
An encoded token can be included in a public repository without being automatically deleted by GitHub.
These can be used in various package ecosystems like this:
A NuGet `nuget.config` file:
<packageSourceCredentials>
<github>
<add key="Username" value="PublicToken" />
<add key="ClearTextPassword" value="0123456789abcsef" />
</github>
</packageSourceCredentials>
A Maven `pom.xml` file:
<repositories>
<repository>
<id>github-public</id>
<url>https://public:0123456789abcsef#maven.pkg.github.com/<OWNER>/*</url>
</repository>
</repositories>
An npm `.npmrc` file:
#OWNER:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken="\u0030123456789abcsef"
You can use this snippet in you project’s configuration file.
Note, you shouldn’t include your own read:packages PAT if you have access to any private packages you need to protect. In this case it is best to create a machine-user.
If you don't consider as additional resource a Gradle plugin, then I'd suggest you mine
I was exactly in your shoes, you can either:
have a Github repository acting as a Maven repository
or publish on Github Packages and easier the consumption for Gradle
clients

Setup AEM Adobe CQ5 6.1 project to build/install offline

I'm new to CQ5 and looking for steps/settings I may need to do to setup an AEM adobe CQ5 6.1 project to build/install offline (not connected to internet).
I've to use our internal network Nexus (which has lot of general dependencies available except AEM related).
I've to use Maven & Java7.
Looking for possible issues/resolutions, steps & any helpful info.
Thanks all for your inputs.
After a detailed investigation, this is now resolved. Just want to share the findings so that it may help others.
The content-package-maven-plugin which was uploaded to our local nexus got corrupted.
Interestingly maven was not throwing any errors when i was trying mvn install command on my AEM project. Rather it was giving NoClassDefFound error for a further dependency of content-package-maven-plugin.
From the output of, mvn dependency:resolve-plugins, it was confirmed that the dependencies are not fully resolved for particular this plugin JAR, I tried to manually download the artifact from nexus & try to open/unjar it.
The artifact pom was corrupted and hence I uploaded the fresh artifact in nexus, and this time all went smooth.
My AEM project is now building fine with local nexus dependencies.
a typical AEM project does have lots of dependencies. There are some dependencies for the AEM platform(including granite, sling, osgi etc). These dependencies are downloaded from the adobe public repositories, unless you have a nexus repository in your company where all these dependencies are available.
If your Organization specific Nexus repository can connect to internet and download dependencies (AEM and non AEM related) atleast for the first time , then you do not need to connect to internet from your local sand box.
Theoretically, your organization specific nexus repo also might not be
connected to the internet and all the JARs can be uploaded to Nexus
manually. But, that would be the last thing I will do in my life !
Your project can download all the dependencies from the Nexus repo(only) in multiple ways.
Configure the repository configuration in your pom.xml file to point
to your internal Nexus repo.
<repositories>
<repository>
<id>internal</id>
<name>Internal Public Repository</name>
<url>URL to the public repository of your internal nexus</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>internal</id>
<name>Internal Public Repository</name>
<url>URL to the public repository of your internal nexus</url>
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
Change your Maven settings (settings.xml) to use your internal Nexus
every time it downloads dependencies (Recommened).
settings.xml can be found in your <user>/.m2 directory or <maven-installation>/conf
<mirrors>
<mirror>
<id>public</id>
<mirrorOf>*</mirrorOf>
<url>URL to the public repository of your internal nexus</url>
</mirror>
</mirrors>

Is it possible to deploy to a Nexus Repository using Maven 1?

Some of our projects still use Maven 1. Is it possible to deploy artifacts to a Nexus Maven 1 Repository using "maven:deploy" goal? I could not find the properties to set username and password.
We found a work around by sharing the storage folder of the Nexus server and deploying directly into that folder using file protocol, but this is not really a preferred solution.
If you're using Maven 2 (not Maven 3) you can also deploy artifacts in Maven 1 format by adding "legacy to your distributionManagment
<distributionManagement>
<repository>
<id>nexus</id>
<name>Release Repository</name>
<url>http://localhost:8081/nexus/content/repositories/maven1</url>
<layout>legacy</layout>
</repository>
...
</distributionManagement>
This won't work with Maven 3, the legacy layout support was removed in that version of Maven.
Nexus supports hosted repositories using the Maven 1 format so you can use the usual deployment setup. Unfortunately I do NOT remember how to do the deployment with credentials in Maven 1, but I assume the archived documentation would detail that.
If you can not get this to work easily and the project is not VERY complex I would actually suggest to drop Maven 1 and upgrade to Maven 3. This would solve your problem and bring numerous improvements to your development team. Maven 1 has been unsupported and deprecated for years and which puts you into this troublesome situation.

Deploy from Maven to Nexus got error: ReasonPhrase:Forbidden

http://numberformat.wordpress.com/2011/05/18/nexus-repository/
I am following the above link to setup Maven and Nexus, everything new. I couldn't left a new comment there so I post here.
After so long, I am in another company, when I tried to setup a simple sample in my local PC, I got this error in "mvn deploy" to the simple Maven my-app sample. I installed the simple Nexus Open Source w/o Tomcat.
[WARNING] Could not transfer metadata com.mycompany.app:my-app:1.0-SNAPSHOT/maven-metadata.xml from/to snapshots (localhost:8081/nexus/content/repositories/snapshots): Access denied to: localhosts:8081/nexus/content/repositories/snapshots/com/mycompany/app/my-app/1.0-SNAPSHOT/maven-metadata.xml , ReasonPhrase:Forbidden.
In your settings.xml located in MAVEN_HOME/conf you have to add in servers section
<server>
<id>nexus-releases</id>
<username>deploy</username>
<password>123456</password>
</server>
And in your pom must looks like
<distributionManagement>
<repository>
<id>nexus-releases</id>
<url>http://localhost:8081/nexus/content/repositories/releases</url>
</repository>
</distributionManagement>
Ids have to be the same.
Richard Seddon resolved my issue in nexus-users group.
Add this to nonProxyHosts:
localhost
You need to be authorized to run deployment. This is done by having the server section in your settings.xml. Check out the Nexus eval guide, specifically the publishing section and the sample projects in there for more detail.

Maven: how to find parent pom?

I am in the process of learning maven and setting up a build environment. One thing I can't figure out, how to set up a project such that it finds a company-wide parent pom. I would like this to work:
$ git clone some_project
$ cd some_project
$ mvn install some_project
The some_project/pom.xml should reference a company-wide pom which it could get from a company maven repository. But where do I specify the company repository?
Putting it in some_project/pom.xml would probably do but then the location is hardcoded in many projects, which could lead to quite some trouble down the road should the server location change.
Having it in settings.xml could work I guess but would break the above requirement.
Edit
Thanks for the answers. I am going with the settings.xml solution although it won't allow the above sequence of commands. Seems like there is no solution that does not require some sort of initial manual setup and of the proposed solutions settings.xml is the simplest to me. Therefore I can't decide which of the two answers to accept. Both are equally good.
Here's the part from settings.xml I came up with:
...
<profiles>
<profile>
<activation>
<property>
<name>!skip</name>
</property>
</activation>
<repositories>
<repository>
<id>internalrepo</id>
<name>Central Internal Maven Repository</name>
<url>http://server.company.example.com/mvnrepo</url>
</repository>
</repositories>
</profile>
</profiles>
...
I'd recommend putting it in settings.xml.
If your company runs its own maven repo, it makes sense to have this configured in settings.xml - especially as you may need to add things like access credentials, which of course should never appear in a (shared) project pom. The only downside is that each user will have to jump through one additional (one-time) hoop when first installing their maven client.
An alternative is to not actually get the root pom from the company maven repo initially, but instead install it directly into your local repo from git. If your root pom is itself a maven project (which is not uncommon) and is available in git, simply clone it and run mvn install.
Putting the company repository URL in settings.xml is considered a good practice. You can also have associated username/password needed for repository upload.
If you care about repository relocation, you must rely on a good DNS choice (repository.mycompany.com is generaly fine) and a good usage of web servers rewrite rules.

Resources