Maven: metadata xml files downloaded often from remote repositories - java

I'm using Maven to handle a Java project. I thought that Internet connectivity was only needed in the 1st compile to download the required libraries from the remote repositories, but I get several download messages whenever I compile code. Messages like these:
Downloading: http://repo.maven.apache.org/maven2/org/eclipse/core/resources/maven-metadata.xml
Downloading: http://repository.springsource.com/maven/bundles/external/org/eclipse/core/resources/maven-metadata.xml
Downloading: http://repository.springsource.com/maven/bundles/release/org/eclipse/core/resources/maven-metadata.xml
Downloading: https://oss.sonatype.org/content/repositories/snapshots/org/eclipse/core/resources/maven-metadata.xml
Why that happens and how I could prevent it?

This usually happens when no version information is specified for the artifact.
maven-metadata.xml is a file which contains the <groupId>, <artifactId> and the versioning information about the various versions available for the dependency.
If the version of the artifact is not specified in the pom.xml, maven downloads this metadata file to check if the local repository contains the latest version.
So, you can avoid this download by specifying the version information of the artifact in pom.xml file, instead of changing the update policy which might affect the update process of other jar files in future.

The most important thing is to start using a repository manager furthermore check the configuration in your settings.xml file which can be configured to check the remote repositories (update policy).

1) Check that you indeed have these artifacts in your local repo
2) Check your repository configuration so you are using your repos only to download releases.
<project>
...
<repositories>
<repository>
<id>my-repo1</id>
<name>your custom repo</name>
<url>http://jarsm2.dyndns.dk</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
...
</project>
3) You can force maven to only use your local repo with the -o option:
mvn -o clean package

Related

How to upload or deploy multiple versions of an artifact to Sonatype Nexus?

I'm looking for a way to upload and store multiple versions of an artifact to the Sonatype Nexus maven-2 repository, so a team has access to previous versions of the artifact if a new version was released and uploaded.
I upload a java library to the hosted maven-2 release repository. Everything works well until I upload another version of the same library to the same repository.
After uploading the second version all files are present in the repository, but Maven cannot resolve not first nether second versions.
I tried both ways to upload artifacts - manually with the nexus UI and using the Maven deploy command. Results are the same.
I believe there is a way to store multiple versions in one repository.
Is there a special configuration for that case?
Please, help me to figure out how can I solve this issue.
As I mentioned, I have all settings that allow me to deploy and download one artifact from nexus.
In the library pom.xml I have:
<groupId>com.company.lib</groupId>
<artifactId>LibName</artifactId>
<version>1.0.7</version>
<name>LibName</name>
...
<distributionManagement>
<repository>
<id>testdeploy</id>
<url>https://nexus.company.com/repository/testdeploy/</url>
</repository>
</distributionManagement>
In the project where I want to download a library I have:
<dependencies>
<dependency>
<groupId>com.company.lib</groupId>
<artifactId>LibName</artifactId>
<version>1.0.7</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>testdeploy</id>
<url>https://nexus.company.com/repository/testdeploy/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
In settings.xml I have:
<servers>
<server>
<id>testdeploy</id>
<username>...</username>
<password>...</password>
</server>
<servers>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>https://nexus.company.com/repository/maven-public</url>
<name>Nexus M2</name>
</mirror>
<mirror>
<id>central_new</id>
<mirrorOf>central</mirrorOf>
<url>https://repo.maven.apache.org/maven2</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>release</id>
<repositories>
<repository>
<id>testdeploy</id>
<name>custom repo</name>
<url>https://nexus.company.com/repository/testdeploy/</url>
</repository>
</repositories>
</profile>
</profiles>
After uploading two versions of the library to nexus I have the following file structure:
com
company
lib
LibName
1.0.6
LibName-1.0.6.jar
LibName-1.0.6.jar.md5
LibName-1.0.6.jar.sha1
LibName-1.0.6.pom
LibName-1.0.6.pom.md5
LibName-1.0.6.pom.sha1
1.0.7
LibName-1.0.7.jar
LibName-1.0.7.jar.md5
LibName-1.0.7.jar.sha1
LibName-1.0.7.pom
LibName-1.0.7.pom.md5
LibName-1.0.7.pom.sha1
maven-metadata.xml
maven-metadata.xml.md5
maven-metadata.xml.sh1
When I try to download any of these versions via Maven I get an error
"Could not find artifact com.company.lib:LibName:1.0.6 in nexus (nexus.company.com/repository/maven-public)"
Solution:
In my case there were two problems:
The "testdeploy" repository was not added in maven-public group.
The "testdeploy" repo was made to test deployment artifact's versions from maven. I wanted to deploy another version of the library into the real repo after testing. The problem was that the real repo still had the library with the same artifact id and version. So there was a conflict between the real repo and test repo ("testdeploy") even after adding the "testdeploy" version into the "maven-public" group. To test deployment I had to change the librarie's artifact id.
Once these two issues were solved I didn't need to specify "testdeploy" repository in pom.xml. Defining the settings of the mirror (maven-public) and the server credentials in settings.xml were enough to make it work.
Maven identifies a unique artifact by a combination of 3 values: the groupId, the artifactID and the version. Appending -SNAPSHOT to a version has some additional special behaviour described here
The unique identifier for your artifact per your first pom snippet, would be
com.company.lib:LibName:1.0.7
If you want different addressable artifacts, change the version number. If people are still using the original 1.0.7 you should be producing 1.0.8 or some other incremented version.
Worth noting that projects that build in this often use SemVer and it's a convention that works in well understood ways so is probably a safe place to start.
EDIT TO ADD:
Based on comments, and re-review it looks like whatever is trying to pull 1.0.6 is not doing so from https://nexus.company.com/repository/testdeploy/. Instead it's trying to pull from nexus.company.com/repository/maven-public and failing.
For the project trtying to pull 1.0.6 what is the repository config? Your settings.xml only adds the testdeploy repo if the releases profile is active, so the testdeploy repo would need to be called out in the pom.
Your approach is correct and the normal way to work with different versions.
I guess you just have problems with different repository definitions in your Nexus, or some other network related issue.

How to make maven download dependencies from central repo. rather than downloading from remote company repo.?

So I thought of creating a spring boot project but on my company laptop. I downloaded the project from spring initializer and tried to execute on IntelliJ idea but got this error:
"java: package org.springframework.boot does not exist"
"java: cannot find symbol
symbol: class SpringBootApplication"
I ran maven clean and install cmds but still the same issue. Now I reckon this is happening bc maven is downloading dependencies from my remote company repository.
I remember saving a custom setting.xml file in .m2 folder which contains a custom repository.
So if I am right how can I make maven download from the central repo or solve this problem?
It sounds like you listed your own repository in your POM or settings.xml, like so:
<repositories>
<repository>
<id>vaadin-addons</id>
<url>https://maven.vaadin.com/vaadin-addons</url>
</repository>
</repositories>
Doing so, without also listing Maven Central, will cause Maven to only attempt to resolve from your own repository. You must also list Maven Central, like so:
<repositories>
<repository>
<id>vaadin-addons</id>
<url>https://maven.vaadin.com/vaadin-addons</url>
</repository>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>
Maven checks repositories in the order they are specified. You cannot specify a repository per dependency, but you could create a new module with your dependencies and their specific repositories.

Maven Build Jar

I am working on Maven project and I have a jar app-client.jar which have dependency on app-core.jar. So I have a pom.xml for app-client.jar and that pom.xml has dependency of app-core so we added dependency of app-core in this pom.xml.
Now I wanna use the app-client.jar in my main project. Because this jar is build locally and not available at remote repository. So I did add the app-client and also specify the location repository where it will located.
as following..
<repositories>
<repository>
<id>repo</id>
<releases>
<enabled>true</enabled>
<checksumPolicy>ignore</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<url>file://${project.basedir}/../lib</url>
</repository>
<repositories>
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>app-client</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
and also I put my jar as following
[My Module] / [com] / [sample] /[app-client] /[1.0]/app-client-1.0.jar
When I run mvn clean install I got error app-client's pom.xml not found. and build get failed. Usually when I use single jar then its working fine, but if I use jar having dependency with other jar it getting failed.
So how can I build my app-client jar and their pom so that it behave normal and also deploy app-core.jar too.
firstly when you are building app-client.jar build a fat jar which includes app-core.jar dependency.
Next copying app-client-1.0.jar into the specified location of local repo doesn't work, to add this jar into your local repo use this command mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>.
If you build app-client.jar with mvn clean install, then it will be installed into your Maven local repository (.../.m2/repository). Then any other project on the same computer can reference it in its pom without further information. So no <repositories> entry necessary.
If you want to work with multiple people on the same project, use a Nexus/Artifactory server to share the jars.
Solutions with lib folders and system paths are deprecated and cause trouble.

Copy Maven repository to another computer

Is there some index or cache that needs to be refreshed or deleted when I copy over the Maven repository from another computer?
I would like to copy the local Maven repository from my laptop for use on another computer that is effectively offline. After copying the files from ~/.m2/repository it does not work as expected. When I execute mvn package -o I get an error that it cannot find one of the artifacts from the new repository:
[ERROR] Failed to execute goal on project [...]: Could not resolve dependencies for project [...]:
Cannot access central (https://repo.maven.apache.org/maven2) in offline mode and the artifact com.oracle:ojdbc6:jar:11.2.0.3.0 has not been downloaded from it before.
But I do have the artifact in the folder at ~/.m2/repository/com/oracle/ojdbc6/11.2.0.3.0 that was copied in from the other computer. (This particular one is not public; it is stored on our company Nexus server which cannot be reached from the target system.)
Maven uses the "update policy" in the settings.xml file to decide whether to download the artifact or to use the one in the local repository if available.
If you don't want Maven to update your dependencies, you should configure <updatePolicy>never</updatePolicy>. You also need to use the same repository <id>s in both locations.
So if you are only using Maven's Central Repository, your repository configuration would look something like this:
<repository>
<id>central</id>
<name>Maven Central</name>
<url>https://repo1.maven.org/maven2</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>

How can I add source code to my dependency libraries in Maven?

For instance, I have included into my dependencies junit-addons : junit-addons. But in the maven repository there isn't any source code. And I know it exists (I have downloaded it). How can I modify the dependencies in order to use libraries from my local project instead from the maven repository (I would omit the junit-addons from the respository and use a local JAR and its source code instead).
Note: I use m2eclipse.
I've solved the problem in a very straight forward way:
I have copied into the folder ${user.home}/.m2/repository/{group-name}/{artifactId}/{version}/ the source file following MAVEN standard: {artifactId}-{version}-sources.jar and it works as a charm! Eclipse checks the local repository and finds the sources.
I don't know if this is the MAVEN way, though.
How can I modify the dependencies in order to use libraries from my local project instead from the maven repository
You can't. If a sources JAR isn't available in the central repository, just put the sources somewhere on your file system in a folder, JAR or zip (you could install:install-file a sources archive in your local repository, following Maven's conventions) and setup Eclipse to use them (right-click on the JAR under Maven Dependencies in the Package Explorer, select Java Source Attachment and setup the Location path).
I use free version of Artifactory repository. I created a jar file {artifactId}-{version}-sources.jar and uploaded to the repository into the same group-id as binary jar file.
Then in my pom I added dependency:
<dependency>
<groupId>mygroupid</groupId>
<artifactId>artifact</artifactId>
<version>1.0</version>
<classifier>source</classifier>
</dependency>
During maven build phase source jar was downloaded to my local repository.
I use netbeans 7.0 and it automatically managed everything for me. For example, right click on method and choosing go toSource correctly brings me to source code in the jar.
You could use the install-file mojo to locally install artifacts into your local maven repository. If you want to share this artifact with others (say your team or another workstation), you could use your own repository manager (e.g. Nexus) and configure it as a mirror for any repository, e.g. central. Nexus will fetch (and cache) artifacts from central. Additionally, you may upload just about any artifact (like junit-addons sources) to your nexus installation.
In order to do configure a mirror, you'll have to edit ${user.home}/.m2/settings.xml
<settings>
<!-- SNIP -->
<mirrors>
<mirror>
<id>nexus-releases</id>
<mirrorOf>*</mirrorOf>
<!-- replace nexus.example.com with the location of your nexus installation -->
<url>http://nexus.example.com/releases</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
<id>nexus</id>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
</profile>
</profiles>
</settings>
After you have downloaded it into your local repository, you could make a copy of it. Give it a new artifactId (e.g. libraryName-myVersion) and add dependencies in the pom. Make sure you change the folder names, jar names, pom names and the artifactId itself in the pom. Store everything in your local repository. Now you can use your hacked version of your dependency.
But to be honest, I do not thing this is a good idea to do. But maybe it helps/could not be avoided in your case.

Categories