Maven: local versus remote repository - maven

This may well have been asked before (so apologies in advance if it has been - I just haven't found the right question yet!)
I'm working on a project with two Maven repositories: a local one (on my machine) and an internal one (on a central server). There are quite a few projects kicking around, and one parent project that uses all of them. When we're done working on a particular project, we install it to the central repository for everyone else to use.
When I build the parent project for local testing, I'd like to use the most up to date versions of each project:
if someone has updated a project in the central repository, I'd like to use that one
if I have changed a project locally and installed it into my local repository, I'd like that to override the centralised one.
What I'm seeing is the build completely ignoring my local repository and just grabbing everything from the internal one. Have I missed a setting somewhere obvious? Or is this just the way things work?

mvn -o will take you into offline mode so nothing is downloaded.
Or in your settings.xml set the update policy to not always for snapshots or releases. See here and relevant section below
<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">
...
<profiles>
<profile>
...
<repositories>
<repository>
<id>codehausSnapshots</id>
<name>Codehaus Snapshots</name>
<releases>
<enabled>false</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://snapshots.maven.codehaus.org/maven2</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
...
</pluginRepositories>
...
</profile>
</profiles>
...
</settings>

You have to make sure you use a -SNAPSHOT version. Then it will compare local and remote and use whatever is newest.
Of course you need to have to have it configured correctly in your settings.xml (maybe you should show us that..)

Related

How maven handle multiple <repository> configurations?

I am getting more and more comfortable with maven. But still some questions.
I have multiple <repository> in my pom.xml.
How will maven handle these repos when downloading artifacts? Will it search by the declaration order?
Besides the explicitly declared ones, will maven still check the default central repo at http://repo.maven.apache.org/maven2/?
If something cannot be found within the explicitly configured repo, will maven fallback to the default central repo?
Is it good to use multiple repos? I am kind of worried about inconsistency.
Below is the <repositories> section of my pom.xml:
<repositories>
<repository>
<id>ibiblio-central-repo</id>
<layout>default</layout>
<name>ibiblio-central-repo</name>
<releases>
<checksumPolicy>warn</checksumPolicy>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<url>http://maven.ibiblio.org/maven2/</url>
</repository>
<repository>
<id>oschina-central-repo</id>
<layout>default</layout>
<name>oschina-central-repo</name>
<releases>
<checksumPolicy>warn</checksumPolicy>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<url>http://maven.oschina.net/content/groups/public/</url>
</repository>
<repository>
<id>oschina-central-repo-3rd-party</id>
<layout>default</layout>
<name>oschina-central-repo-3rd-party</name>
<releases>
<checksumPolicy>warn</checksumPolicy>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<url>http://maven.oschina.net/content/repositories/thirdparty/</url>
</repository>
</repositories>
How will maven handle these repos when downloading artifacts? Will it
search by the declaration order?
Order of declaration as part of the merged settings (see next answer). I have found this JIRA ticket providing further details.
Besides the explicitly declared ones, will maven still check the
default central repo at http://repo.maven.apache.org/maven2/?
Yes, as it will be provided by the Maven super POM, implicit parent of all Maven Pom (here an official example), unless specified in your settings.xml (if you override the repository id specified in the super POM). You can use the Maven Help Plugin to get the effective settings Maven will apply to your build and the effective pom maven will actually (effectively) run.
As documented here, the repositories element is inherited.
If something cannot be found within the explicitly configured repo,
will maven fallback to the default central repo?
As above. Moreover, you could also influence this mechanism via any configured Maven mirror. You could, for instance, redirect Maven to your company repository (see below) instead of looking up on the default one.
Is it good to use multiple repos? I am kind of worried about
inconsistency.
You probably don't need many configured repositories, but you might need more than one if the dependencies you are looking for are not provided by the default repository. A good approach would be to have an enterprise Maven repository (i.e. Artifactory, Nexus) and make your local settings only point to it. Then, configure the internal Maven repository to point to other repositories, in a centralized (and governed) manner.

Getting "Missing Artifacts" while they are exist in .m2

In my setting.xml from .m2 folder, the following configs are applied to get jar files from local nexus repository:
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>central</mirrorOf>
<url>http://192.168.0.172:9090/nexus/content/groups/public/</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
In my pom.xml, an external repository declared to get jar files not presented in central repository:
<repositories>
<repository>
<id>spring-snasphot</id>
<url>https://repo.spring.io/snapshot</url>
</repository>
</repositories>
Despite of the fact that these so called "missing artifacts" are existed in their corresponding folder in .m2, but I always get
Missing artifact ....
What is wrong with my configurations?
Thanks in advance.
Finally I just figured it out. Having deleted files excluding jar file from corresponding folder, and then updating maven project solved the problem.
The configuration looks ok. But something must be going on...
If you delete those snapshot artifacts from your local repository and retry (for ex: mvn dependency:go-offline) do you see an attempt is made to download the artifact from https://repo.spring.io/snapshot ?
The additional repository seems to contain snapshots but the are not enabled for that repository. But I'm not sure whats the default. The artifacts may be not found because of the update policy. They are locally available but too old so maven tries to update them but fails (have you tried mvn -X ? that may give an indication what fails when resolving those artifacts).
What may be an option is to add the spring snapshots repo to your nexus (snapshot repo enabled) and set the mirrorOf in settings xml to <mirrorOf>*</mirrorOf>.
The mirror of central only might was intended so: just an experiment :)
It is always a good thing to verify the settings maven actually sees are the ones you think they are:
mvn help:effective-settings
mvn help:effective-pom

unable to download maven repositories due to custom settings.xml?

Here is my situation:
I am able to run mvn install on my personal computer and the build successful.
But when I run the same at workstation, I get the following error. This is most likely because I have a settings.xml in ${user.home}/.m2/settings.xml which refers to my company's repo and DOES NOT allow to fetch from remote maven repo. How can I overcome this behavior?
Both my workstation and personal computer runs mac OS X.
Here is the settings.xml(I have replaced real names with dummy ones)
<profiles>
<profile>
<id>dummy</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<dummy-groupId>com.mycompany.mydummy</dummy-groupId>
<dummy-name>my-java-ee-app</dummy-name>
<dummy-Mode>FALSE</dummy-Mode>
</properties>
<repositories>
<repository>
<id>mycompany Release Repository</id>
<name>central maven release repository</name>
<url>
http://maven1.mycompany.com:8080/myartifactories/repo
</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>mycompany Snapshot Repository</id>
<name>central maven snapshot repository</name>
<url>
http://maven1.mycompany.com:8080/myartifactories/repo
</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>mycompany Release Plugin Repository</id>
<name>central maven release repository</name>
<url>
http://maven1.mycompany.com:8080/myartifactories/repo
</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
<pluginRepository>
<id>mycompany Snapshot Plugin Repository</id>
<name>maven snapshot repository</name>
<url>
http://maven1.mycompany.com:8080/myartifactories/repo
</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
Error:
Could not resolve dependencies for project org.glassfish.javaeetutorial:roster-ejb:ejb:7.0.5: Failure to find org.glassfish.javaeetutorial:roster-common:jar:7.0.5 in http://maven1.mycompany.com:8080/myartifactories/repo was cached in the local repository, resolution will not be reattempted until the update interval of mycompany Release Repository has elapsed or updates are forced -> [Help 1]
EDIT:
I DO see the central repo in my effective pom:
Here is the condensed version of it
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
</repository>
Simplest solution is to configure a repository manager on your mac and configure the different repositories in the repository manager. Or you can use git to switch your ${HOME}/.m2/settings.xml to different state.
Update:
Create a git repository in ${HOME}/.m2/ via git init there
add an appropriate .gitignore file which contains a single line
repository. Checkin your settings.xml file. Create a branch
for example git co -b company make the appropriate changes for
your company and check in that state. Afterwards you can simply
switch by changing into the appropriate branch in git.
Setup Repository manager like Nexus (on your machine)
and configure there necessary repositories you need. If you working
on company site you can activate/deactivate the appropriate repository
via the UI of Nexus which means you have no change in your
settings.xml.
My preference is the local git repository which make life easier for me as well.
It seems your repo is cached locally and needs to be updated forcefully.
Try following to force the updates:
mvn clean install -U
I see in your error you have pasted:
"...was cached in the local repository, resolution will not be
reattempted until the update interval of mycompany".
so you want to delete this cache, i.e. to delete it from the local repo. Go to your local repo (usually .m2/...) and delete the "placeholder": go to directory org/glassfish/javaeetutorial/7.0.5 and there you should see roster-common.XXX cached - delete it.
If this keep happening, after you deleted the 'cached' from the repo, it means that maven cannot find it in any repo. So you have to re-check your repositories definitions. For example, why don't you have the "central" repo defined in your settings.xml (like all other repos)?

How to easily swap Maven settings profiles?

At my company we use a Nexus server to fetch the artifacts. Which is fine. But sometimes I want to use Maven at home too, where I cannot access the company Nexus. Is there an easy way to swap Maven settings profiles? And is it easily swappable with m2eclipse?
At the moment I'm using the following settings.xml:
<settings
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>central</id>
<username>company-user</username>
<password>company-user</password>
</server>
<server>
<id>mirror</id>
<username>company-user</username>
<password>company-user</password>
</server>
</servers>
<mirrors>
<mirror>
<id>mirror</id>
<url>https://url.to.company.nexus</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<id>defaultprofile</id>
<repositories>
<repository>
<id>central</id>
<name>Repository for Company artifacts</name>
<url>https://url.to.company.nexus</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Repository for Company artifacts</name>
<url>https://url.to.company.nexus</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>
<activeProfiles>
<activeProfile>defaultprofile</activeProfile>
</activeProfiles>
</settings>
I know i'll probably have to add a new profile to http://repo1.maven.org/, but how to make sure the existing mirrors will not complain with timeouts?
In my experience it is best to have multiple settings file around and swap them as needed. Either by copying the on top of the existing settings.xml from a differently named file or by using the -s option of the mvn command to specify the settings file. If this is too cumbersome to type all the time you can also make an alias for your mvn command with the different settings files. However that breaks bash completion for Maven, which is why I stick to just copying the settings file around with a script.
The same sort of thing actually applies for swapping context e.g. for Git changing the .gitconfig file around so you can pack all those file changes into a script or into different branches in git or whatever..
In addition it can help to run Nexus locally and just connect to it, and let it in turn proxy all the external repos..
The best i can suggest is to use Git/SVN/ and checkin the settings.xml file and use different branches to separate between company and home. Use either
svn switch URL/branches/company
svn switch URL/branches/home
or
git checkout company
git checkout home
A profile will not work cause the mirrorOf part can't be put into a profiles area. Changing in m2e can be done via the configuration dialog. But this might cause inconsistency with the command line.
Unfortunately, mirrors can't be configured in profiles. There's an open request in maven for that. As suggested in JIRA, you could use a script to easily switch between different settings.xml
As for answering to the question in the title : to easily switching between profiles in m2e, I suggest you install JBoss Tools Maven Profile Manager from this update site : http://download.jboss.org/jbosstools/updates/stable/juno/
To enable the same global profile(s) on all your projects :
in the project explorer view : select all maven projects (Ctrl+A)
hit Ctrl+Alt+P to open the Profile Mgmt wizard and select the profiles you want activated.
This is the equivalent to manually set the active maven profiles in each of your project properties page, which is way more tedious.
If you have the artifacts already downloaded in your local repository then you can use mvn -o clean compile .... This will avoid remote repository lookup.

Why is maven looking for artifact in the wrong repo?

I'm defining a dependency in pom.xml in a Maven 3 project. Dependency is as follows:
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>el-impl</artifactId>
<scope>runtime</scope>
<version>2.2</version>
</dependency>
Repostory is described in pom as follows:
<repository>
<id>java.net</id>
<name>java.net</name>
<url>http://download.java.net/maven/2</url>
</repository>
Artifact is indeed present in the repository. It's easy to check. Despite that, Maven is trying to obtain the artifact from repo1.maven.org. What could be the reason of this? Maybe I make some crucial mistake in defining repository access? Other dependencies seem to do fine.
Plugin org.mortbay.jetty:maven-jetty-plugin:6.1.26 or one of its
dependencies could not be resolved: Could not find artifact
org.glassfish.web:el-impl:jar:2.2
in central (http://repo1.maven.org/maven2)
The repository that you have defined is used for dependencies, but not for plugins. Hence the error.
To address this, you need to define pluginRepositories:
<project>
<!-- ... -->
<pluginRepositories>
<pluginRepository>
<id>{repo.id}</id>
<url>{repo.url}</url>
</pluginRepository>
</pluginRepositories>
</project>
As to where you should specify - in pom.xml or settings.xml, read this SO post.
You need to check your maven settings.xml (Look into Maven folder: M2_HOME/conf).
The default repositories are defined there itself, and Maven central repository is taking precedence.
Define your repository in Maven's settings.xml like this:
<profiles>
<profile>
...
<repositories>
<repository>
<id>Java Net</id>
<name>Java Net</name>
<releases>
<enabled>false</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://download.java.net/maven/2</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
...
</pluginRepositories>
...
</profile>
You can maybe overwrite the default Maven central repository location with yours if you don't want to do much configuration.
Cheers!
In my case, the real root issue was that the repo required authentication. However for some reason maven decided that it would be much better to not tell me that, and to instead use the first repo in the <repositories> list, and throw the Could not find artifact error for that repo.
After moving the repo that contained the package so it was the first one in the <repositories> list, it started showing me a "permission denied" message. Once maven was setup for authentication with the repo in question, the issue went away.
I had a similar problem however, another developer had set up a mirror in that I simply copy-pasted into my settings.xml file. Modifying the mirrorOf property to only include specific repos did the trick.
In addition to the above mentioned answers, make sure your settings.xml is saved as an xml file not a text file i.e. its not saved settings.xml.txt.

Resources