Question about Maven2 repositories mirroring - maven-2

I have set up a Maven 2 repository (call 'dev repository') using Apache Archiva which holds artifacts of my private projects.
If I build an artifact of my own project, say group1:cat for example, and Cat depends on { group1:dog, commons:collection }. The group1:cat and group1:dog are sit in dev repository, and commons:collection in the Central.
Now, when I build group1:cat, maven will fetch group1:dog and commons:collection, the problem is maven will always search in both dev repository and central repository to find the dependencies, but what I want is it search group1:dog in dev repositories only, and search commons:collection in central repositories only. I have central mirrors say central-mirror1 and central-mirror2, so how to configure maven so it will search commons:collection in default central repository and central-mirror-1,2 etc., and won't bother my dev repositories at all?

(...) what I want is it search group1:dog in dev repositories only, and search commons:collection in central repositories only.
I don't know how to achieve this and I don't think it's possible. How could maven be aware of the "source" repository for a given artifact?
But actually, why don't you make everything go through Archiva? What's the point of not using Archiva for all requests? If you don't want maven to check both repositories for your dependencies, it seems to be a pretty obvious solution. Moreover, people usually don't want to rely directly on central in a corporate environment (e.g. if it goes down you can't work anymore). No, really, I don't get it.
So, I'd just declare Archiva as a mirrorOf all repositories, like this:
<settings>
...
<mirrors>
<mirror>
<id>internal-repository</id>
<name>Maven Repository Manager running on repo.mycompany.com</name>
<url>http://repo.mycompany.com/proxy</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
...
</settings>

My setup uses my local Archiva instance to proxy central (and other 3rd party repositories). In my super pom, I've changed my repositories to only point to my local Archiva, and not search central at all. Everything comes in via my local proxy.
It's not quite what you're asking for, but I think it's an appropriate setup.
You can then use Archiva's black/white lists to tell it where to search for things.

Related

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

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>

How to make a maven project buildable for the customer

We have a project which should be buildable by the customer using maven. It has some open source dependencies that are mavenized (no problem), some that aren't mavenized, proprietary stuff (oracle jdbc driver) and some internal stuff.
Until now we had everything but the first category packaged with the project itself in a local repository (repository with file://path-in-project-folder specified in the projects pom.xml).
We would love to move these out of the project, as we are about to use them in other projects as well. Currently we plan to use nexus as an internal maven repository.
Whats the best practice to make such dependencies/maven repositories available to the customer so he can continue to build the project.
Ideas so far:
Customer sets up a nexus repository as well, we somehow deploy all these non-public dependencies to his repository (like a mirror)
We provide a 'dumb' dump/snapshot of the non-public dependencies, customer adds this snapshot to this settings.xml as a repository, (but how is this possible).
Make our internal nexus repo available to the customers build server (not an option in our case)
I'm wondering how others solve these problems.
Thank you!
Of course, hosting a repository of some kind is a straightforward option, as long as you can cover the uptime / bandwidth / authentication requirements.
If you're looking to ship physical artifacts, you'll find this pattern helpful: https://brettporter.wordpress.com/2009/06/10/a-maven-friendly-pattern-for-storing-dependencies-in-version-control/
That relies on the repository being created in source control - if you want a project to build a repository, consider something like: http://svn.apache.org/viewvc/incubator/npanday/trunk/dist/npanday-repository-builder/pom.xml?revision=1139488&view=markup (using the assembly plugin's capability to build a repository).
Basically, by building a repository you can ship that with the source code and use file:// to reference it from within the build.
There are two options:
Document exactly what artifacts you need to compile which are not
available via Maven Central
Implement Nexus and make a export with Nexus give the export
to customer and they need to do a import of it. I'm not sure
if you come to licenses issues.
I assumed that you already have a Repository Manager already but it reads like you didn't.

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

The plugin 'org.apache.maven.plugins:maven-tomcat-plugin' does not exist or no valid version could be found

I keep getting this error when I call 'tomcat:run'.
The plugin 'org.apache.maven.plugins:maven-tomcat-plugin' does not exist or no valid version could be found
My company hosts mvn repositories locally via 'activeprofile'. Is this preventing mvn from acquiring the plugin from the WWW location? If so, how can I activate that too...
Cleared up after I deleted the repository in ~\.m2 (%userprofile%\.m2). Maybe poor interaction b/t various maven/tomcat eclipse plugin
The company repos (assuming they are using a repo manager) controlles what is in it ...so this has to be changed.
My company hosts mvn repositories locally via 'activeprofile'. Is this preventing mvn from acquiring the plugin from the WWW location?
It's impossible to answer this question, it all depends of the configuration of your maven client and/or the corporate repository.
If so, how can I activate that too...
Assuming your company does not allow accessing the central repository, bypassing this policy is not a good idea. You should discuss your requirement with the people administering the repository.

Maven repository for Google Code project

I'm hosting a small open source project on Google Code, and I have been asked to submit the jar to a publicly accessible Maven repository. I have almost no practical knowledge of Maven. What would be the best way to do this?
Is there some central repository that I can submit to, or can I host my own? What would I need to do when I want to release a new version of the jar?
I've been Googling and found this, which looks nice and simple, but it seems a bit ... contrary to the spirit of Maven, to commit jar files to SVN :).
Also, would there be a way to still keep track of the download count, as Google Code does?
EDIT
I've been getting some answers, some of which containing hints on what to add to my pom.xml. Thanks guys! But obviously I forgot to mention one important thing: my build script is in ANT, and to put it bluntly, I intend to keep it that way :). I just want to make it easier for Maven users to include my jar in their projects.
The solution I went with in the end
In the end, I did use the solution I referenced before, where I simply commit a Maven repo to SVN. I have the ANT script call Maven to set up the local repo, and then call SVN to commit it to Google Code. For those interested: look at my build script here, in the publish-maven target.
There is a guide to the central repository that has a section on uploading projects that may help. If nothing else you can check the naming conventions and minimal information requirements against your project.
Sonatype also do OSS Repository hosting, see their guide for details.
Update: I'm not saying you should change your build process - if Ant works for you stick with it. It's worth following the Maven conventions in your POM regardless of your build method. As the point of putting your jar in a Maven repository is to make it accessible to Maven users, you will therefore need to define a POM for your published artifact. Following the naming conventions will help your users so you might as well do it. For example adding the SCM details to the pom will (amongst other things) allow your users to import the project into their workspace using the IDE integrations for Maven.
Basically, you have 4 options:
Perform a standard Maven build against a Maven repository (already ruled out)
Set up a Maven repository, do your builds with Ant, and use Maven to deploy the jar and POM.
Set up a Maven repository, ad use an Ant HTTP task to publish the artifacts
Use a Subversion "repository", and use the SvnAnt task to publish the artifacts
Option 1
Use Maven to build and deploy the artifacts (see the Maven book and the above links for details).
Option 2
Assuming you have a build process that creates your jar, and you've defined the POM, your best bet is to publish it to the Sonatype OSS repository as above.
Deploying an existing jar to a standard Maven repository is simple with the Maven deploy plugin's deploy-file goal:
Set up your repository (e.g on the Sonatype servers by raising a Jira request)
Build your jar with Ant.
If you have defined a POM, put it in the same directory as the jar.
Run the deploy-file goal:
mvn deploy:deploy-file -Durl=http://path/to/your/repository\
-DrepositoryId=some.id \
-Dfile=path-to-your-artifact-jar \
-DpomFile=path-to-your-pom.xml
Note that the Maven deploy goal will automatically translate the pom.xml to [project-name]-[version].pom. If you are doing either of the other two alternatives, you will need to ensure you commit the POM with the final name, i.e. [project-name]-[version].pom. You'll also need to ensure you compose the relative paths for the artifacts following the Maven conventions.
E.g. for groupId=com.foo.bar, artifactId=my-project version=1.0.0, the path to the files will be:
/com/foo/bar/my-project/my-project-1.0.0.jar
/com/foo/bar/my-project/my-project-1.0.0.pom
Option 3
If you want to use Ant to deploy to a Maven repository, you can use an Ant HTTP library (Note I've not tried this myself) . You would compose two HTTP put tasks, one for the jar and one for the POM.
<httpput url="http://path/to/your/repository" putFile="/path/to/yourproject.pom">
<userCredentials username="user" password="password"/>
</httpput>
<httpput url="http://path/to/your/repository" putFile="/path/to/yourproject.jar">
<userCredentials username="user" password="password"/>
</httpput>
Option 4
If you want to avoid Maven completely and use Ant to deploy to an SVN-backed repository, you can use the SvnAnt Subversion library. you would simply need to do configure the Svn import task to add your artifacts to the Remote Subversion repository.
<import path ="/dir/containing/the/jar/and/pom"
url="svn://your/svn/repository"
message="release"/>
Check wagon-svn. It will allow you to 'deploy' to a Subversion repository. It's a little convoluted, but it's better than nothing. I know of a few projects that use it at java.net, and I also came across some projects using it at code.google.com.
If you want to use it, then you first need to load wagon-svn as an extension:
<build>
...
<extensions>
<extension>
<groupId>org.jvnet.wagon-svn</groupId>
<artifactId>wagon-svn</artifactId>
<version>...</version>
</extension>
</extensions>
Next, you need to set your deployment targets using the svn: protocol identifier. Here's an example I copied from the Internet.
<distributionManagement>
<repository>
<id>maven-config-processor-plugin-repo-releases</id>
<name>Maven Repository for Config Processor Plugin (releases)</name>
<url>svn:https://maven-config-processor-plugin.googlecode.com/svn/maven-repo/releases</url>
<uniqueVersion>false</uniqueVersion>
</repository>
<snapshotRepository>
<id>maven-config-processor-plugin-repo-releases</id>
<name>Maven Repository for Config Processor Plugin (snapshots)</name>
<url>svn:https://maven-config-processor-plugin.googlecode.com/svn/maven-repo/snapshots</url>
<uniqueVersion>false</uniqueVersion>
</snapshotRepository>
</distributionManagement>
Check if the Maven repository support maven deploy plugin. This would be the easiest approach.
Most repositories uses ssh as the transport. See this for details.
Once it's setup, all you have to do is:
mvn deploy:deploy
You can submit your jar to https://clojars.org/
In your pom.xml:
<repositories>
<repository>
<id>clojars.org</id>
<url>http://clojars.org/repo</url>
</repository>
</repositories>