Why does maven use my internal repository before my local repository? - maven-2

when I am doing development I often need to change a dependency, but I'm not ready to deploy my changes. For example, I'm working on project Foo and I realize I need to add a method to the common library. Before deploying this change to our internal repository, I would like to install the changes to common library (mvn install) and recompile Foo to use the common library in the local repository (note that I'm using all SNAPSHOT versions).
However, after I mvn install my common library, when I recompile Foo it doesn't use the new common library--it keeps using the latest SNAPSHOT of common library in the internal repository. If I deploy the changed common library, Foo picks it up immediately.
How can I get maven to look first in the local repository?
UPDATE: when the file is installed into the local repository, it gets a name like foo-1.0.0-SNAPSHOT.jar, but when I deploy it, it gets a timestamp foo-1.0.0-20111104.191316-23.jar. I think this is why the remote artifact gets pulled each time. Any idea why mvn install is not working like mvn deploy? Does it have to do with the fact that I have a snapshot repository set up for deploy?

By default, Maven checks for new versions of SNAPSHOT artifacts once per day. When it does this check, it will download SNAPSHOTS from remote repos that are newer than what you have locally. Either your artifact timestamps are out of sync and you're doing something to override Maven's update policy (like calling it with -U or setting the udpatePolicy to "always"), or else the local repository you're installing the artifact to isn't the same one you're subsequently running Maven against. What you're describing isn't typical Maven behavior. For a better answer, give more details in your question.
One indicator you can look for: after you install your common artifact, when you next compile Foo, does Maven download the common artifact again? If so, then it really is getting it from the remote, and you need to check your update settings. If not, then you have something strange going on locally.

You can try this option. This worked for me.
In your project's main pom.xml change 'snapshots' enabled setting to 'false'.
<repository>
<id>yourRepo</id>
<name>Repository</name>
<url>http://your.repo.com/repo</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>

Related

Creating a link to the latest release with maven's deploy plugin

My pom.xml contains:
<distributionManagement>
<repository>
<id>ssh-myown-repository</id>
<url>scpexe://user#host/path/to/repository</url>
</repository>
</distributionManagement>
So whenever I issue:
mvn deploy
My project is, well, deployed properly on my remote repository, under a name such as this:
http://host/repository/project/0.7.0-SNAPSHOT/project-0.7.0-20120518.212052-3.jar
I know file "maven-metadata.xml" contains information about which file is the latest release, but I'd very much like the mvn deploy stage to create a link to the latest jar file, say:
http://host/repository/project/0.7.0-SNAPSHOT/project-0.7.0-latest.jar
I understand "scpexe" has no way of doing this directly as links are part of the file system on which the web server is running (ie.: they are not represented as uploadable file content).
I have shell access on this remote server, so is there a way to hook on maven's deploy action to execute a script after deployment is complete ?
You know that the -SNAPSHOT is a thing like the "LATEST". Furthermore i recommend to use a repository manager.

Maven is using incorrect location for downloading plugin pom

(This question is asked on Maven User mailing list too)
I have recently faced a strange problem, that I cannot even able to judge the cause or source of problem. It will be great if someone can give me some direction:
(The story may be a bit long)
I am using Nexus 1.8.0 as our company's repository manager. I use it as proxy of external repo, and hosting our own repository.
There are many repositories in Nexus. I have one repository group (let's call it PUBLIC) which groups all public repositories, including maven central, codehaus etc.
There is another repository group (let's call it EXT) which we put 3rd party artifacts.
In our project, we used org.codehaus.mojo:native2ascii-maven-plugin.
Due to a bug at that time, instead of using the publicly available org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1, I have fixed the bug and deploy it to our EXT repository, and called it org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1.1 (i.e. used a new version number 1.0-alpha-1.1 instead of 1.0-alpha-1)
This have been running fine for several years.
However recently a new developer tries to get the code and build, using Maven 2.2.1. Strange things happened: the build failed. By inspecting result of mvn -X clean install, it states that POM of native2ascii-maven-plugin:1.0-alpha-1.1 cannot be downloaded from PUBLIC, therefore it will use a default emtpy POM, which cause the build problem.
By inspecting the local repository, I found that only the JAR of native2ascii-maven-plugin:1.0-alpha-1.1 was downloaded. I am sure that there is no native2ascii-maven-plugin:1.0-alpha-1.1 in PUBLIC repository, and the SHA of the JAR matches with native2ascii-maven-plugin:1.0-alpha-1.1 in EXT. It seems that, Maven is capable to download the JAR correctly from EXT repo, but when it tries to download the POM afterwards, Maven mistakenly think that it should be downloaded from PUBLIC. Because PUBLIC do not contains 1.0-alpha-1.1, Maven assume there is no POM.
I have EXT repo defined before PUBLIC in my settings.xml. What even more strange is, I tried to block accessing in Nexus for native2ascii-maven-plugin from PUBLIC. Maven, instead of getting the POM from repository EXT, it get from central directly. At last I add PUBLIC as mirror for central, and Maven can build correctly, because EXT is the the only repo that contains native2ascii-maven-plugin. Maven seems tries to download the POM from every repository else which contains native2ascii-maven-plugin in despite of the version number, except from EXT
I simply cannot understand why this will happen. This have been used for years, and it used to be fine even several weeks before (I have other new developers, who can correctly download the plugin, several weeks ago). May anyone guide me the possible cause of the problem? I have neither changed anything in my repo, nor changed version of Maven. Why Maven's "download" behavior suddenly changed?
It's hard to say.
First my theory on why it no longer works. I am guessing this "worked for years" because at one time it worked, and afterwards everything was in your local repository (<home>/.m2/repository). Later, something broke, but you never noticed because you had everything local. The new developer did not have a populated local repository so when they built for the first time, they had failures.
Now my suggestion which may not work out for you. When using Nexus, I think its best to create a single "group" repository that links in all other repositories, and configure the group to order the priority of the linked repositories. So for you, in the group, you would list EXT first, then PUBLIC. Your POMs and/or settings would reference only the group repository. This may just duplicate what you are already doing through other means, but at least it is moving the ordering rules up into Nexus. I would rename your local repository (so you can revert back if necessary) and try re-building to see if everything resolves correctly.
You might want to consider a continuous build tool like Hudson that periodically deletes its own local repository so you can catch issues like this sooner.
At last I managed to find out the "cause" of the problem. It is due to my fault, combined with still-unknown behavior of Maven. I add this as an answer to ease future reference for other people.
They key problem is that I missed plugin version for this specific project (I did put corresponding pluginManagement for other projects, and other plugins for this project... I wonder how come I made this mistake this time)
The way to reproduce the problem:
A separate repository to store the plugin (in my case, org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1.1)
In project POM, add plugin, without version. For example,
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>native2ascii-maven-plugin</artifactId>
<plugin>
</plugins>
in settings.xml, avoid defining mirrors (i.e. the settings.xml contains list of repositories and pluginRepositories only)
With such setup, first purge the local repository. Then build the project. After build, inspect the directory in local repository for that plugin (in my case .m2\repository\org\codehaus\mojo\native2ascii-maven-plugin\1.0-alpha-1.1), you will find only the JAR presents, without corresponding POM. (Caused by Maven successfully get the plugin JAR corresponding to the pluginRepositories in settings.xml, but trying to get the POM from a weird location)
With the same setup, put the version in project POM, clean up the local repo, and build again. Everything is fine now.
The reason for work fine even for a recently clean CI environment, is probably due to other "correct" project made the plugin downloaded correctly, which can be used by this "incorrect" project. A periodic purge in local repository in CI won't necessary help much on this too because for that many projects, the chance is always very high for other "correct" project build earlier than that "incorrect" project.
The reason behind such behavior of Maven is still unknown, but at least in a "correct" POM (with plugin version correctly declared), Maven works fine. I will raise this as a issue for Maven though.
I'd start off by agreeing with SingleShot in that Continuous Integration - even a simple smoke test where you simply compile and run unit tests on the trunk - would have prevented you getting into the situation of assuming that the because the build works on one machine, it does not work on the other.
This have been running fine for several years.
That's the kicker with Maven repositories - all you need to do is download it once succesfully, and you'll be forever good to go. Just because it's been working successfully from your local repository doesn't mean it was working.
It is fine several months ago (coz I have migrated our CI server and I have a clean env to build, and everything is fine).
Interesting. So my theory would be then to go and make sure the new developer is set up correctly - that the settings.xml file is in place and is being read (I've had instances that the settings.xml is THERE, but in the wrong place!). It's a simple one, but Maven does not fail if there's no settings.xml, it just uses a default that may have you seeing ghosts.
You mentioned that you use maven 2.2.1 and I can only ask you to doublecheck, we had some strange behavior concerning downloading jars from internal repo that was caused by OSX Lion update that comes with maven3. Our fix was to redeploy affected project.

Maven command to install remote dependency locally

I have a base pom which defines repository locations for the nexus we are running behind our firewall and all of our projects inherit from this base pom. However the base exists in one of the repositories defined in the base, so you can see the circular reference problem. I'd like a maven install:install-file like command I can have new team members run in order to pull down and install the base project locally without having to check the project out from source control and mvn install it.
I'd like a maven install:install-file like command I can have new team members run in order to pull down and install the base project locally without having to check the project out from source control and mvn install it.
The Maven Dependency Plugin and its dependency:get goal might help here, you could do something like this:
mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:get \
-Dartifact=groupId:artifactId:version[:packaging] \
-DrepoUrl=http://repository.mycompany.com/
But let me come back on the following:
However the base exists in one of the repositories defined in the base (...)
Unless this is really what you want (adding a repository for thing not found in central), this is usually not how people declare a Nexus repository in a corporate environment.
People usually want all requests to go though their Nexus repository and store artifacts in it. Storing all the artifacts you need yourself is the only way to be sure that you'll be able to repeat your build in 1, 5, 10 years. Sure, the maven folks are doing a great job with central but are you sure you want to rely on something not under your control? So people usually declare Nexus as a mirror of everything (check the section 4.2. Configuring Maven to Use a Single Nexus Group) in the settings.xml.
And if you don't want every user to add the required snippet in their ~/.m2/settings.xml, the best option is to distribute and use a corporate version of the Maven client and to preconfigure it as required using the conf/settings.xml file.
References
Nexus User Guide
Chapter 4. Configuring Maven to Use Nexus

jetty-blazeds and maven (com.adobe.flex#flex-messaging-core missing)

I want to setup jetty with jetty-blazeds extension. Everything looks fine but when I run maven to get the dependencies, I get:
UNRESOLVED DEPENDENCIES
com.adobe.flex#flex-messaging-core;3.2.0: not found
com.adobe.flex#flex-messaging-common;3.2.0: not found
I've tried many repositories but no success. I am wondering has anyone managed to successfully locate these dependencies through maven ? If yes, could you please share the repository !
Thank you,
-A
If you look at the pom of jetty-blazeds, for example jetty-blazeds-7.0.0.1beta3.pom, you'll see this:
<repositories>
<repository>
<id>project-repo</id>
<name>project repo</name>
<url>file:${basedir}/maven_repo</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
Jetty is using a file based repository. And if you look at this file based repository in their svn repository, you will see that it contains the mentioned artifacts (which are thus very likely not available in any known public repository).
So my suggestion would be to use the same strategy i.e. to install the artifacts locally, either in your local repository or in a file based repository in your VCS (you could also declare https://svn.codehaus.org/jetty/jetty/branches/jetty-7/jetty-blazeds/maven_repo/ as repository but this is extremely ugly).
If you have a corporate repository, the alternative is obvious: deploy the adobe artifacts in it.
It is recommended to set up a central Maven repository for your project/department and configure it in the project pom. Then you can download such dependencies by hand and deploy them manually to the project repo. Although this is a bit more extra work, it eliminates the whole class of problems in the long run.

maven snapshot repositories

My project depends on a 3rd party library that only has snapshots in its maven repository (no releases, which seems strange, but that's how it is). Every time I do a full build (and clean my local .m2 repository) maven will obviously go and grab the latest build.
My repository proxies the one with the snapshots in it, is there anyway to tell my repository to stop pulling new versions and basically just keep the current version? I really don't want to be pulling a new build every night.
The only thought I had is to manually label the current versions, but there quite a few dependencies and they are all dependent on the SNAPSHOT versions. Is there an easier way to do this?
thanks,
Jeff
Take a look at this blog entry from sonatype: Best Practices for 3rd Party Snapshot Dependencies
I usually install the file to my proxy or local repo as a certain version, and then refer to that version. Then you don't risk the snapshot disappearing out from under you.
Do you run the build with the -U ( -update-snapshots ) option ? If so, try without.
Else, if there is only this dependency on the repository, you could just disable this repository, and Maven will keep using the last version it finds on the local repository.
Did you try to specify the <updatePolicy> with the never strategy in the <snapshots> element of your <pluginRepository>? See Plugin Repositories and Repositories.
Use the --no-snapshot-updates option to suppress SNAPSHOT updates.
e.g.
$ mvn --no-snapshot-updates compile