maven-dependency-plugin dependency:get with AAR dependencies - maven

I would like to fetch a maven package with all dependencies. To perform this, I use this command:
mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.1:get \
--settings settings.xml \
-Dmaven.repo.local=/path/to/m2-repository \
-Dartifact=my.pkg.name:vers
My settings.xml file :
<settings>
<profiles>
<profile>
<id>global</id>
<repositories>
<repository>
<id>google</id>
<name>Google Maven</name>
<url>https://maven.google.com</url>
</repository>
<repository>
<id>jcenter</id>
<name>Jcenter</name>
<url>https://jcenter.bintray.com</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>global</activeProfile>
</activeProfiles>
</settings>
It's works fine if there are no aar packages in the dependency tree, otherwise, for each aar packages, I have the error like :
The following artifacts could not be resolved: <pkg-prefix>:<pkg-name>:jar:<pkg-version>
There is a plug-in to manage aar and other android archive formats (com.simpligility.maven.plugins:android-maven-plugin) but I don't know how I will have to use it to perform the same thing that with maven-dependency-plugin with the get method

Related

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.

Does the repos in maven not have jar files?

I have tried looking through various repos around, however i could not find one that contains the jar file for this dependency:
<dependency>
<groupId>com.oracle.java</groupId>
<artifactId>jre</artifactId>
<version>1.8.0_131</version>
</dependency>
Error i got: Could not resolve dependencies for project com.blackducksoftware.test:example-maven-travis:jar:0.1.0-SNAPSHOT: Could not find artifact com.oracle.java:jre:jar:1.8.0_131 in jboss (http://repository.jboss.org/nexus/content/groups/public-jboss)
Is there a reason why only pom files are in the repo and not the jar file?
How do I get the jar file?
From mvnrepository.com:
Note: this artifact it located at Alfresco repository (https://artifacts.alfresco.com/nexus/content/repositories/public/)
So you need to add a profile entry to your settings.xml file.
Example:
<profile>
<id>alfresco-repo</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>alfresco-repo</id>
<name>Alfresco Repository</name>
<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
</profile>

How to build and release a Maven project from an offline machine (with a file directory as lib-repository)

I need to build and release projects using Jenkins,
on a server with no access to maven central, and even, with no access to Nexus.
Given that I have access to maven-central on dev machines,
to fill the maven local_repository, I could do
mvn dependency:resolve-plugins dependency:go-offline
to then copy the local_repository on the linux server.
Then, to get ride of a Non-resolvable parent POM error,
as described here, I filled the specific profiles for both windows (dev) and linux (jenkins) with faked central profile to override the maven-central reference made by my parent pom:
<profiles>
<profile>
<id>windows</id>
<activation>
<os>
<family>Windows</family>
</os>
</activation>
<properties> <repository.base.url>file:///c:/maven_distribution_repo/</repository.base.url>
</properties>
</profile>
<profile>
<id>linux</id>
<activation>
<os>
<family>Linux</family>
</os>
</activation>
<properties>
<repository.base.url>file:///appli/Maven_3.1.1_build/maven_distribution_repo/</repository.base.url>
</properties>
<repositories>
<repository>
<id>central</id>
<name>Maven Plugin Repository</name>
<!--<url>http://repo1.maven.org/maven2</url>-->
<url>${repository.base.url}</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<!--<url>http://repo1.maven.org/maven2</url>-->
<url>${repository.base.url}</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
That way, mvn -o compile still raise a Non-resolvable parent POM error !,
but using the --legacy-local-repository option suggested here ,
managed to fake the remote repository by using a local one,
and the Non-resolvable parent POM problem disappeared:
mvn --legacy-local-repository compile
Still, a strange error appeared (decribed here):
[ERROR] Failed to execute goal on project myProject: Could not resolve dependencies for project some.package:myProject:war:0.0.7-SNAPSHOT: Failed to collect dependencies at org.jxls:jxls-poi:jar:1.0.11 -> org.jxls:jxls:jar:[2.0.0,): org.jxls:jxls:jar:[2.0.0,) within specified range -> [Help 1]
But it was hiding an earlier warning:
[WARNING] Could not transfer metadata org.jxlsjxls/maven-metadata.xml from/to central (/path):/appli/Maven_3.1.1_build/maven_distribution_repo/org/jxls/jxls/maven-metadata-central.xml (access forbidden)
Using --legacy-local-repository, maven seems to use the distribution repository path as the local libs repository !
I swapped them in the pom:
<profile>
<id>linux</id>
<activation>
<os>
<family>Linux</family>
</os>
</activation>
<properties>
<!--<repository.base.url>file:///appli/Maven_3.1.1_build/maven_distribution_repo/</repository.base.url>-->
<repository.base.url>file:///appli/Maven-3.1.1_build/maven_local_repo/</repository.base.url>
</properties>
...
and had also to copy into the local repository:
all maven-metadata-maven2_central.xml into maven-metadata.xml
using the following bash command:
for file in $(find /appli/Maven-3.1.1_build/maven_local_repo -type f -name 'maven-metadata-maven2_central.xml'); do cp $file $(echo ${file%/*}/maven-metadata.xml); done
And ... BINGO !
BUILD SUCCESSFULL
Seems weird, at later stage, to release:perform into the local lib repository.
Would you have any better and not that painful solution ?
Maven deploy plugin would solve this problem.
mvn deploy -DaltDeploymentRepository=local-temp::default::file://directory/
More Exhaustive example:
# 1. Create temporary folder
tmp_repo=$(mktemp -d systemds-repo-tmp-XXXXX)
# 2. Create a simple settings.xml
cat <<EOF >../tmp-settings-nexus.xml
<settings>
<activeProfiles>
<activeProfile>local-temp</activeProfile>
</activeProfiles>
<profiles>
<profile>
<id>local-temp</id>
<repositories>
<repository>
<id>local-temp</id>
<url>${tmp_repo}</url>
</repository>
</repositories>
</profile>
</profiles>
</settings>
EOF
# 3. deploy to local
mvn --settings ../tmp-settings-nexus.xml -Pdistribution deploy \
-DaltDeploymentRepository=local-temp::default::file://${tmp_repo} \
-Daether.checksums.algorithms='SHA-512,SHA-1,MD5'
You should consider setting up a local repository (for example, Nexus) that will be accessible to your build machine.
This is a very common setup.
It enables you to build without internet connection to the build machine.

Copy snapshot artifact from nexus without pom

I want to download a snapshot artifact using the dependecy.copy target. I don't want to have a POM file.
mvn -U dependency:copy -Dartifact=mygroupId:myArtifactId:myversion-SNAPSHOT:jar
Unfortunately this only works if the artifact is already in the local maven repo cache. When it's not in the maven cache I get the following error:
Unable to find artifact.
...
foo-public (https://nexus.foo.org/content/groups/public-foo/, releases=true, snapshots=false)
It says foo-public because I'm using a settings.xml
<mirror>
<id>foo</id>
<mirrorOf>*</mirrorOf>
<name>My Maven Nexus Repository</name>
<url>http://nexus.foo.org/content/groups/public-foo/</url>
</mirror>
The reason seems to be that Maven's Super POM has set snapshots=false for the central repo. If I add a minimalistic pom.xml to the working directory I don't have the error as snapshots=true seems to be the default for any other repo.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>dummy</groupId>
<artifactId>dummy</artifactId>
<version>1</version>
<repositories>
<repository>
<id>dummy</id>
<url>dummy</url>
</repository>
</repositories>
</project>
My current work around is to write the dummy POM before calling my mvn command. Another possible work around is to add the following to settings.xml (Found in Sonatype nexus book)
<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>
</profile>
</profiles>
<activeProfiles>
<!--make the profile active all the time -->
<activeProfile>nexus</activeProfile>
</activeProfiles>
Do you have a more elegant idea that works without so much preparation? For instance a command line switch?
One solution is to use dependency:get goal instead of dependeny:copy goal, see Apache Maven Dependency Plugin:
The dependency:get Mojo
This mojo is used to fetch an artifact and (optionally) its dependencies from remote repositories using its Maven coordinates.
mvn dependency:get -DgroupId=org.apache.maven -DartifactId=maven-core -Dversion=2.2.1 -Dpackaging=jar -Dclassifier=sources -DremoteRepositories=central::default::http://repo1.maven.apache.org/maven2,myrepo::::http://myrepo.com/maven2
mvn dependency:get -DgroupId=org.apache.maven -DartifactId=maven-core -Dversion=2.2.1 -Dpackaging=jar -Dclassifier=sources -DremoteRepositories=http://repo1.maven.apache.org/maven2
mvn dependency:get -Dartifact=org.apache.maven:maven-core:2.2.1:jar:sources -DremoteRepositories=http://repo1.maven.apache.org/maven2 -Ddest=/tmp/myfile.jar
Your modified command:
mvn dependency:get -U -DgroupId=mygroupId -DartifactId=myArtifactId -Dversion=myversion-SNAPSHOT -Dpackaging=jar -Dtransitive=false -s settings.xml -DremoteRepositories=https://nexus.foo.org/content/groups/public-foo/ -Ddest=target/myArtifactId.jar

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.

Resources