Issue pulling SNAPSHOT dependencies from Archiva snapshot repository - maven

I've been setting up an Apache Archiva instance as both a proxy to Maven Central and to capture our development snapshots. I've managed to setup the proxy and I can deploy artifacts to the Archiva snapshot repository however I cannot pull artifacts from the snapshot repositories to use in other projects.
Relevant parts of pom.xml (dependant project)
<project>
<!-- Excluded detail -->
<dependency>
<groupId>uk.abc</groupId>
<artifactId>ABC</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<!-- Excluded detail -->
<distributionManagement>
<repository>
<id>archiva.snapshots</id>
<name>Snapshot Repository</name>
<url>https://xxx.xxx.xxx.xxx/archiva/repository/snapshots</url>
</repository>
</distributionManagement>
<!-- Excluded detail -->
</project>
My ~/.m2/settings.xml
<settings>
<servers>
<server>
<id>archiva.snapshots</id>
<username>username</username>
<password>xxx</password>
</server>
<server>
<id>archiva.internal</id>
<username>username</username>
<password>xxx</password>
</server>
</servers>
<mirrors>
<mirror>
<id>archiva.internal</id>
<mirrorOf>central</mirrorOf>
<url>https://xxx.xxx.xxx.xxx/archiva/repository/internal</url>
</mirror>
<mirror>
<id>archiva.snapshots</id>
<mirrorOf>snapshots</mirrorOf>
<url>https://xxx.xxx.xxx.xxx/archiva/repository/snapshots</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>archiva.internal</id>
<name>Archiva Managed Internal Repository</name>
<url>https://xxx.xxx.xxx.xxx/archiva/repository/internal/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>archiva.snapshots</id>
<name>Archiva Managed Internal Repository</name>
<url>https://xxx.xxx.xxx.xxx/archiva/repository/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>
When I build the dependant project I cannot reference classes (public access).
Just to note that I can browse the snapshots repository and I know the war file is there.
Any ideas?

It turns out that you cannot use the "war" dependency type and expect to be able to reference the contained classes. You can however create an additional jar (create both war and jar) containing the classes:
http://maven.apache.org/plugins/maven-war-plugin/faq.html#attached
You can the use the type "jar" when pulling in the dependency... in my case:
<dependency>
<groupId>uk.abc</groupId>
<artifactId>ABC</artifactId>
<version>1.0-SNAPSHOT</version>
<type>jar</type>
</dependency>
I think therefore the question is a bit misleading... the dependency was being pulled from Archiva but was not of an accessible type.

You are probably not activating the profile correctly
before the profile in settings.xml put something like
<activeProfiles>
<activeProfile>default</activeProfile>
</activeProfiles>
Remember this about activeByDefault
This profile will automatically be active for all builds unless
another profile in the same POM is activated using one of the
previously described methods. All profiles that are active by default
are automatically deactivated when a profile in the POM is activated
on the command line or through its activation config.
if you want to confirm if this is the issue, look at the active profiles by running help:active-profiles

Related

Why is maven using the wrong repository when multiple dependencies in different repos?

I have a settings.xml file that has the following...
<settings>
<mirrors>
<mirror>
<!--This sends everything else to /jpmc-public -->
<id>PRIVATE-SNAPSHOT</id>
<mirrorOf>PRIVATE-SNAPSHOT</mirrorOf>
<url>https://url1</url>
</mirror>
<mirror>
<id>PRVATE</id>
<mirrorOf>PRIVATE</mirrorOf>
<url>https://url2</url>
</mirror>
<mirror>
<id>public</id>
<mirrorOf>*,!PRIVATE,!PRIVATE-SNAPSHOT</mirrorOf>
<url>http://url3</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>local</id>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<url>http://url</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>
<id>PRIVATE-SNAPSHOT</id>
<url>https://url1</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
<repository>
<id>PRIVATE</id>
<url>https://url2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>public</id>
<url>http://url3</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
</profile>
</profiles>
...
</settings>
Then I have something like this in my pom
<dependencies>
<dependency>
<groupId>some.group</groupId>
<artifactId>public-lib</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>come.other.group</groupId>
<artifactId>private-lib</artifactId>
<version>${scala.test}</version>
</dependency>
</dependency>
But when I run it tried to get the public lib from the private repo and fails. If I edit the settings to remove the repository tags then it gets the public stuff fine but fails trying to get the private stuff from the public repo. How am I supposed to say that a specific dependency comes from a specific repo?
The general situation is as follows:
You cannot define which repository a given dependency is drawn from.
You need not define which repository a given dependency is drawn from. Maven looks into all repositories and only fails if none of them contains it.
But:
You can confuse Maven by wrong mirrors in the settings.xml.
In rare cases, Maven resolution brakes if one of the repositories is broken.
In a company, it is usually the best idea to run a Nexus or Artifactory and add all the relevant local and remote repositories to it. Then you can point just to that Nexus/Artifactory as a mirror in your setttings.xml.

Not retrieving jars from maven nexus setup specific to project

Got 2 Nexus maven repo - one serving or holding common jars - mostly from maven central & some others. And other - project specific maven nexus, where it holds 2 thirdparty jars which are needed for compilation of current project of interest.
Below is updates which is added to refer to local nexus maven setup & corresponding dependencies..
pom.xml snippet :
<project
...
<!-- download plugins from this *proj specific* repo -->
<repositories>
<repository>
<id>zzz-maven</id>
<name>zzz-maven</name>
<url>http://blah.blah.com/nexus/content/repositories/zzz-maven</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>zzz.zzz-report<groupId>
<artifactId>zzz-report<artifactId>
<version>1.2<version>
</dependency>
...
<!-- And other dependency to fetch jars from common nexus (which is working fine) -->
Added below to settings.xml (highlighted in bold text) - one covering Url to retrieve proj specific jars & other part of authenticating to proj specific Nexus
<settings>
<mirrors>
<mirror>
<id>nexus</id>
<name>Common nexus across org - Anonymous access </name>
<url>http://common-nexusxyz.com/nexus/content/repositories/maven</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<profiles>
</profile>
<profile>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<!--**Added this one** -->
</profile>
<profile>
<id>zzz-maven</id>
<repositories>
<repository>
<id>zzz-maven</id>
<name>zzz-maven</name>
<url>http://blah.blah.com/nexus/content/repositories/zzz-maven</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
<activeProfile>zzz-maven</activeProfile> <!--**activated** additional one here -->
</activeProfiles>
<servers>
<server>
<id>zzz-maven</id>
<username>userNameForZZZ</username> <!--**Specified** explicit password needed for proj specific maven nexus here -->
<password>passwordForZZZ</password>
</server>
</servers>
</settings>
But still throws out Warning & then the error for mvn install or mvn compile like :
[WARNING] The POM for zzz.zzz-report:zzz-report:jar:1.2 is missing, no dependency information available
Would like to know what is missing - so that it will download proj specific jars from proj specific maven nexus?
Tried with both <repositories> & <pluginRepositories> option in pom to consider for download
Expect it to connect to proj specific maven nexus & download dependency jar defined in pom
You have defined
<mirror>
<id>nexus</id>
<name>Common nexus across org - Anonymous access </name>
<url>http://common-nexusxyz.com/nexus/content/repositories/maven</url>
<mirrorOf>*</mirrorOf>
</mirror>
which means that all requests (due to mirrorOf having the value *) are redirected to that particular repository, no matter what other repositories are defined in the POM or the settings.xml.

Configure Maven settings for deployment

I want to deploy artifacts to Nexus from Jenkins to different repositories (like builds-all, builds-verified, releases). The thing is that I want to keep minimal configuration in the project POM file. My settings file now looks like:
<servers>
<server>
<id>orion-nexus</id>
<username>admin</username>
<password>password</password>
</server>
</servers>
<localRepository>~/.m2/repository</localRepository>
<profiles>
<!-- Deployment configuration for CI builds for mainline -->
<profile>
<id>build</id>
<repositories>
<repository>
<id>builds-all</id>
<url>http://orion-nexus:8081/</url>
<snapshots>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
Project POM:
<distributionManagement>
<repository>
<id>orion-nexus</id>
<layout>default</layout>
<url><!-- how to avoid explicit URL? --></url>
</repository>
</distributionManagement>
I wan to run deploy like mvn -B -P build clean install deploy. However, I don't understand how to avoid setting explicit URL in distribution management section. Can I set a variable in settings file and propagate it to my POM?
Is there any step-by-step guide for such workflow?
You can declare a property inside a profile on your settings.xml and use its name within <distributionManagement/> configuration.
settings.xml
<profiles>
<profile>
<id>distmgt</id>
<properties>
<distUrl>scp://...</distUrl>
<properties/>
</profile>
</profiles>
pom.xml
<distributionManagement>
<repository>
<id>orion-nexus</id>
<layout>default</layout>
<url>${distUrl}</url>
</repository>
</distributionManagement>
And finally
mvn -P distmgt clean deploy
You can avoid the -P build params using activation.

How to fetch artifacts from own repo using maven?

How do I create a simple project that fetches artifacts from my repo using maven? And where will these artifacts get saved to - my default maven repo?
I am using Apache Archiva.
Just simply start using a repository manager like Nexus and that's it. Please configure your settings.xml file according to the following:
<settings>
<mirrors>
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>URL OF your ARCHIVA SERVER</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<!--Enable snapshots for the built in central repo to direct -->
<!--all requests to nexus via the mirror -->
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<!--make the profile active all the time -->
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
The artifacts which are being downloaded are first stored into the Archiva and of course on your hard drive $HOME/.m2/repository.
If you like to deploy artifact into archiva you need to configure the distributionManagement in your pom file similar like this:
<distributionManagement>
<repository>
<id>releases</id>
<name>Archiva RElease repo</name>
<url>http://URL OF YOUR ARCHIVA/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots<id>
<name>Archiva Snapshots repo</name>
<url>http://URL OF YOUR ARCHIVA/snapshots/</url>
</snapshotRepository>
...
</distributionManagement>
...
To test this you can use mvn deploy to see if the artiacts are being deployed to the snapshot repository. You can change the version of your test project into 1.0 and redo a mvn deploy which will try to deploy the artifacts into the release repository.

Build/Deploy third-party project in maven but upload to my snapshots repository

I build weekly a large third-party project (apache sling) in Jenkins. I've got jenkin's settings.xml set up to use my own archiva server to download all dependencies (using the mirror section).
However, I haven't figured out how to get the build to upload snapshots my own snapshots repository when doing a 'deploy'. It instead tries to upload the snapshots to an apache.org snapshots server and fails.
Is there a way to configure settings.xml to override the snapshots server in a similar way it's possible to override the repository? This has to be done without editing the project's pom.xml.
The reason I need to do this is because I need access to some of the snapshot versions as dependencies in another project, and I don't want to have to manually upload them all into archiva.
Here's my settings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>/Users/Shared/Jenkins/.m2/repository</localRepository>
<servers>
<server>
<id>astra.internal</id>
<username>-deleted-</username>
<password>-deleted-</password>
</server>
<server>
<id>astra.snapshots</id>
<username>-deleted-</username>
<password>-deleted-</password>
</server>
</servers>
<mirrors>
<mirror>
<id>central-proxy</id>
<name>Local proxy of central repo</name>
<url>http://-deleted-.com/repository/internal</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>snapshots</id>
<name>Local proxy of snapshots</name>
<url>http://-deleted-.com/repository/internal</url>
<mirrorOf>snapshots</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<id>Repository Proxy</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<!-- ******************************************************* -->
<!-- repositories for jar artifacts -->
<profile>
<!-- ******************************************************* -->
<repositories>
<repository>
<id>astra.internal</id>
<url>http://-deleted-.com/repository/internal/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>astra.snapshots</id>
<url>http://-deleted-.com/repository/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>
You can overwrite the Distribution management section with command line parameters.
mvn clean deploy -DaltDeploymentRepository=ui-snapshots::default::http://localhost:8081/artifactory/libs-snapshot-local/
Have a look at the maven deploy plugin.
Alternatively, you should be able to use the Jenkins post build step. There you need to specifically provide the Repo url anyway.
The location of the repository is part of the pom.xml, the distributionManagement often in one of the upper-most parents. So it is not something you can set from the settings.xml.
There's a good chance that you can change it with the distMgmtSnapshotsUrl property, see org.apache:apache:13:pom, assuming the sling-project uses this as its (indirect) parent.
As far as I know you have to edit the pom file for the project and have this section (with your server settings of course):
<distributionManagement>
<repository>
<id>archiva.internal</id>
<name>Internal Release Repository</name>
<url>dav:http://localhost:8080/repository/internal</url>
</repository>
<snapshotRepository>
<id>archiva.snapshots</id>
<name>Internal Snapshot Repository</name>
<url>http://localhost:8080/repository/snapshots</url>
</snapshotRepository>
</distributionManagement>
Would it help you to put it in a company wide pom you inherit from?

Resources