In my company's parent POM I specify corporate repositories, that we all use. The URLs contain server name and the path of course. Each time I change the POM I publish a new version.
Now imagine, that the server hosting our repos gets renamed. I can change all URLs in the parent POM (not a problem) and publish a new version with fixed URLs. But I can't change URLs in the existing versions of the parent POM.
This means, that I can't rebuild any artifact from the past.
Is there some standard way to get around this problem? Like:
Central property file
A configuration POM with a fixed 1.0.0-SNAPSHOT version, that get republished on any change?
You never put repositories except for distMngt in your POM. Again -- never. You have burned your POMs forever. This exists in Maven because repo managers did not exist back then. It is bad practice for years now and shall be removed.
Always use a Nexus instance with a repo group. This shall be added to your settings.xml which will mirror everything.
For those who don't believe, I am a long year Maven committer.
Another approach that we employ at work is to replace the URLs in the <distributionManagement> with parameters, like so:
<distributionManagement>
<repository>
<id>my-repo</id>
<name>My Release Repo</name>
<url>${url.deploy.releases}</url>
</repository>
<snapshotRepository>
<id>my-repo</id>
<name>My Release Repo</name>
<url>${url.deploy.snapshots}</url>
</snapshotRepository>
</distributionManagement>
This way, we use settings.xml to control where the artifacts should be deployed. This has the advantage that if you ever migrate a repository (which we did) you only need to update settings.xml for new builds/releases.
If you need to go back to an earlier release and republish (for whatever reason) you just checkout the release tag, set up settings.xml to point to the new repo and do a mvn clean deploy.
If you can't modify settings.xml you can always just copy it, change the copy and point out the new settings file with the -s flag.
This approach also works for <scm> tags.
If you use repositories in your parent pom and may change over time, the best strategy is in the URL or it use ALIAS (DNS, Apache redirect, Rewriting) and especially not the IP address directly , and you do not have to change the address of the repository every time.
Example:
<repositories>
<repository>
<id>myrepo</id>
<url>http://myrepo.me/content/repositories/public/</url>
</repository>
</repositories>
and:
http://myrepo.me/content/repositories/public/ => ip address 1.2.3.4/*/*/
Related
I have a maven project, and I have already all my dependencies in my local host. I want to push all these dependencies into nexus/sonartype.
I don't want to push my jar one by one by uploading via nexus interface.
So I copied the content of my maven repository ($MAVEN_HOME/repository) into {nexus-data}/storage/public
Nexus have to recalculate index after restarting?
You might want to use Distribution Management -
<distributionManagement>
<repository>
<id>some-artifactory</id>
<name>Artifactory Name</name>
<url>http://your.artifactory.address/releases</url>
</repository>
<snapshotRepository>
<id>other-artifactory</id>
<name>Other Artifactory Name</name>
<url>http://your.artifactory.address/snapshots</url>
</snapshotRepository>
</distributionManagement>
Repository
Where as the repositories element specifies in the POM the location
and manner in which Maven may download remote artifacts for use by the
current project, distributionManagement specifies where (and how) this
project will get to a remote repository when it is deployed. The
repository elements will be used for snapshot distribution if the
snapshotRepository is not defined.
So I copied the content of my maven repository ($MAVEN_HOME/repository) into {nexus-data}/storage/public
Don't do that. In Nexus 3, Nexus doesn't use raw files so relying on this approach isn't going to work for you anyway.
You should be using distribution management as described by #nullpointer. If you can't for some reason, you could write a script to use Nexus' REST API to upload many artifacts. That's more useful when you aren't building using Maven. For example, maybe you have a whole pile of legacy jar files to upload.
We have a project with multiple parent/child POMs. All the POMs are pointing to a single repository for resolving all Maven dependencies.
Now I have a need like: In a single POM, one jar has to be downloaded from repo1 and rest 4-5 jars from repo2.
How can you do that?
In a word - yes. Maven's dependency resolution mechanism is completely separate from the repository mechanism. Theoretically, you could have every single jar delivered from its own repository (however ridiculous it may to actually do this).
What I have understand the,
I can setup maven repo in artifactory/nexus
e.g. http://localhost:18081/artifactory/ --> L1
1. create remote(R1) repository in artifactory, which can point URL to outside repository, hosted by artifactory/nexus
e.g http://remotehost:18081/artifactory/remote-repo1
2. create a "virtual" repository(V1) in my artifactory and add remote(R1) in to this V1.
3. Let all my poms points to my local artifactory virtual repository(V1),
e.g.>http://localhost:18081/artifactory/virtual
that way, maven will look
a. local .m2 folder
b. then look for jars in virtual repo of my artifactory
hence virtual will look
b1. all local repo
b2. all remote cache repo
b3. all remote repo --> e.g.http://remotehost:18081/artifactory/remote-repo1
I am experimenting this,once succeed, i will update
EDIT :
This has worked for me, the only hiccup I faced was my ~/.m2/settings.xml
the snapshot was false, and my jar in remote repo is a snapshot jar.
After changing this value to true, now its fetching the jars :)
</profile>
<profile>
<id>virtual-repo</id>
<repositories>
<repository>
<id>central</id>
<url><repo_url></url>
<snapshots>
**<enabled>true</enabled>**
</snapshots>
</repository>
</repositories>
I have copied all contents from an old Nexus server to a new server. I am able to login to the new server, see all the uploaded artifacts, etc.
On the Jenkins build master, the maven builds are running obviously as the jenkins user. The home directory for that user is /var/lib/jenkins. Under there, I have copied the .m2 folder and changed all the old URL's in the settings.xml to point to the new URL.
However, when I run a maven deploy, while the build downloads some dependencies from the new nexus server, at the end of the build comes the mvn-deploy plugin and that tries to upload to the old server.
Do the artifacts, war, jar files have a record of the nexus server? Is there some setting in Jenkins that I'm missing? I did a grep for the old nexus address in /var/lib/jenkins folder and none of the config xml's have any mention of the old nexus.
Is the URL hardcoded in your pom? Maybe the pom is not using the params you set in the settings.xml?
The repositories configured in the settings.xml are the source of Maven artifacts. The destination for new artifacts is in the distributionManagement block. This is usually somewhere in your POM, or in a parent POM. The block will look something like the below. Chances are, the old URL is there.
<distributionManagement>
<repository>
<id>releases</id>
<name>Release Repository</name>
<url>${repository.url}/nexus/content/repositories/releases</url>
<layout>default</layout>
<uniqueVersion>true</uniqueVersion>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Snapshot Repository</name>
<url>${repository.url}/nexus/content/repositories/snapshots</url>
<layout>default</layout>
<uniqueVersion>true</uniqueVersion>
</snapshotRepository>
</distributionManagement>
I am in the process of learning maven and setting up a build environment. One thing I can't figure out, how to set up a project such that it finds a company-wide parent pom. I would like this to work:
$ git clone some_project
$ cd some_project
$ mvn install some_project
The some_project/pom.xml should reference a company-wide pom which it could get from a company maven repository. But where do I specify the company repository?
Putting it in some_project/pom.xml would probably do but then the location is hardcoded in many projects, which could lead to quite some trouble down the road should the server location change.
Having it in settings.xml could work I guess but would break the above requirement.
Edit
Thanks for the answers. I am going with the settings.xml solution although it won't allow the above sequence of commands. Seems like there is no solution that does not require some sort of initial manual setup and of the proposed solutions settings.xml is the simplest to me. Therefore I can't decide which of the two answers to accept. Both are equally good.
Here's the part from settings.xml I came up with:
...
<profiles>
<profile>
<activation>
<property>
<name>!skip</name>
</property>
</activation>
<repositories>
<repository>
<id>internalrepo</id>
<name>Central Internal Maven Repository</name>
<url>http://server.company.example.com/mvnrepo</url>
</repository>
</repositories>
</profile>
</profiles>
...
I'd recommend putting it in settings.xml.
If your company runs its own maven repo, it makes sense to have this configured in settings.xml - especially as you may need to add things like access credentials, which of course should never appear in a (shared) project pom. The only downside is that each user will have to jump through one additional (one-time) hoop when first installing their maven client.
An alternative is to not actually get the root pom from the company maven repo initially, but instead install it directly into your local repo from git. If your root pom is itself a maven project (which is not uncommon) and is available in git, simply clone it and run mvn install.
Putting the company repository URL in settings.xml is considered a good practice. You can also have associated username/password needed for repository upload.
If you care about repository relocation, you must rely on a good DNS choice (repository.mycompany.com is generaly fine) and a good usage of web servers rewrite rules.
I am trying to configure the deploy step in a Maven 3.0.4 POM using the <distributionManagement> tag. From XSD for POMs (line 1389), it suggests that merely providing the id should allow Maven too look up the corresponding values from the settings.xml file. I have the desired server listed (which is configured correctly since I can pull dependencies from it and see it mentioned when running in -X debug mode: [DEBUG] Repositories (dependencies): [archiva.snapshots (http://snap-mvnrepo.initech.com/archiva/repository/snapshots, releases+snapshots)]) in the settings.xml. However, when I just provide the <id> in my POM and try to deploy, I get an error that Maven is missing the URL for the repository, but when I explicitly provide the <url> the deploy works.
Does anyone know what I should do to get it working by id only? I don't want to hard code the URL.
DISCLAIMERS: Typos are likely the result of anonymization, but it is possible that they are "real" so feel free to point away at any.
About the <id> child tag of <repository> from the XSD for POMs (line 1389):
A unique identifier for a repository. This is used to match the repository to configuration in the settings.xml file, for example.
From my settings.xml:
<profile>
<id>archiva_dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>archiva.snapshots</id>
<name>Initech Internal Snapshot Repository</name>
<url>http://snap-mvnrepo.initech.com/archiva/repository/snapshots</url>
</repository>
</repositories>
</profile>
From my (failing) pom.xml:
<distributionManagement>
<repository>
<id>archiva.snapshots</id>
<!--
<name>Initech Internal Snapshot Repository</name>
<url>http://snap-mvnrepo.initech.com/archiva/repository/snapshots</url>
-->
</repository>
</distributionManagement>
The error:
Caused by: java.lang.IllegalStateException: Failed to create release distribution repository for com.initech.ws:initechws:pom:1.0-SNAPSHOT
at org.apache.maven.project.MavenProject.getReleaseArtifactRepository(MavenProject.java:1853)
at org.apache.maven.project.MavenProject.getDistributionManagementArtifactRepository(MavenProject.java:1377)
at org.apache.maven.plugin.deploy.DeployMojo.getDeploymentRepository(DeployMojo.java:227)
at org.apache.maven.plugin.deploy.DeployMojo.execute(DeployMojo.java:118)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
... 20 more
Caused by: org.apache.maven.artifact.InvalidRepositoryException: URL missing for repository archiva.snapshots
at org.apache.maven.repository.legacy.LegacyRepositorySystem.buildArtifactRepository(LegacyRepositorySystem.java:775)
at org.apache.maven.project.MavenProject.getReleaseArtifactRepository(MavenProject.java:1843)
... 24 more
The /project/distributionManagement/id value defines the /settings/servers/server/id to match against in order to identify the credentials to use when connecting to the url specified by /project/distributionManagement/url
Because the URL for deployment is very often different from the URL for read access, and the same credentials may apply to multiple URLs, there is no looking up of /project/repositories/repository or /project/pluginRepositories/pluginRepository.
The short answer is thus that you must specify /project/distributionManagement/url in order to be able to deploy, and if you need credentials in order to deploy to that URL you need to specify /project/distributionManagement/id and ensure that the matching credentials exist in your settings.xml
How could we update the documentation to make the above clearer and prevent future users from becoming confused in the manner you have been?
Update
The modello toolchain is generating the XSL with only some of the sentences, so
A unique identifier for a repository. This is used to match the repository to configuration in the settings.xml file, for example.
Is actually
A unique identifier for a repository. This is used to match the repository
to configuration in the settings.xml file, for example.
Furthermore, the identifier is used during POM inheritance and profile
injection to detect repositories that should be merged.
Source
Finally in order to fully make sense of the sentence, you need to be aware that the settings.xml file is just the source of settings when Maven is invoked from the command line. Maven Embedder may actually mean that the settings provided to Maven come from some other source entirely (think, e.g. from the configuration database of Eclipse or another IDE) which is the reason for some of the fun in MRELEASE-577.
A better way to read the first sentence might be
A unique identifier for a repository. This is used to match the repository to configuration, for example in the settings.xml file.
But if you can suggest something even better I will update the docs accordingly