Maven server authentication as profile properties - authentication

I am trying to setup a shared authentication system on a build server.
We have several maven projects that declares how the deployment should be done regarding the different teams that we have (each team has its own authentication user/password):
<profile>
<id>release-profile</id>
<distributionManagement>
<repository>
<id>rep-releases</id>
<name>rep-releases</name>
<url>http://somewhere-releases</url>
</repository>
<snapshotRepository>
<id>rep-snapshots</id>
<name>rep-snapshots</name>
<url>http://somewhere-snapshots</url>
</snapshotRepository>
</distributionManagement>
</profile>
Then I declare in the settings.xml the authentification to the declared servers as following:
<servers>
<server>
<id>rep-releases</id>
<username>${release.user.name}</username>
<password>${release.user.password}</password>
</server>
<server>
<id>rep-snapshots</id>
<username>${release.user.name}</username>
<password>${release.user.password}</password>
</server>
</servers>
Finally, depending on the projects I want to deploy I have several profiles defined in the settings.xml of the build server:
<profile>
<id>dep-team1</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<release.user.name>team1-user</release.user.name>
<release.user.password>team1-password</release.user.password>
</properties>
</profile>
The problem is that when doing a deploy of the project I got an authentication error (HTTP 401) like the following:
Error deploying artifact: Failed to transfer file: http://......./my-project-0.2-20090423.123247-3.pom. Return code is: 401
If I modify the server authentication by replacing the properties with the user/password of the team, all is working fine.
Don't the tags <servers><server> accept values as properties?
How do others setup their build system in order to achieve the same?
Thanks for your help.
Edit: I am using hudson, a solution for me can be to install several time maven2 and have duplicated settings (except user/password) for each team and tie each project to the good maven installation. I must admit that this solution does not enchant me...

The easiest and most direct method if you have multiple teams and thus multiple auth schemes, is just use a different id in the distributionManagement. So instead of rep-releases/rep-snapshots, you can have team1-repo / team2-repo (there's generally no value in separating the auth between release and snapshots...particularly if you use a repo manager with good security controls)
Then in the settings of your build machine, just define a user and password for each team for the build server.
This approach does have a draw back that it would mess up inheritence if you defined the repos in a single corporate pom...but if you have a team level pom it would be easy.
Another thought is why does the same build machine need to login as a different person when doing builds? Shouldn't that build machine have mostly full access?

First of all, I do not see how dep-team1 profile is connected to the distributionManagement tag - it seems to need release-profile to be active.
Second, I have my profile element structured a bit differently (see, there is no distributionManagement tag within). Not sure if it makes the difference.:
<profile>
<id>release-profile</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
</profile>
Here is the distribution management:
<project>
<distributionManagement>
<repository>
<id>releases</id>
<url>http://myurl/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://myurl/snapshots</url>
</snapshotRepository>
</distributionManagement>
</project>

Related

maven setup another repository for certain dependency

I have Maven2 project. All dependencies except one are downloaded from public repository http://repo.maven.apache.org/maven2/.
But I have 1 dependency which I need to download from internal company's repository (we use Sonatype Nexus to store this dependency).
Also, I don't want to create full copy of public repo on my internal repo.
At this moment I have in pom.xml:
<url>http://maven.apache.org</url>
and
<repositories>
<repository>
<id>thirdparty</id>
<url>http://<my_nexus_server_ip>:8081/nexus/content/repositories/thirdparty</url>
</repository>
</repositories>
So, during build I see a lot of trash messages (in this case first line is a trash):
Downloading: http://<my_nexus_server_ip>:8081/nexus/content/repositories/thirdparty/ant/ant/1.6.5/ant-1.6.5.pom
Downloading: http://repo.maven.apache.org/maven2/ant/ant/1.6.5/ant-1.6.5.pom
Downloaded: http://repo.maven.apache.org/maven2/ant/ant/1.6.5/ant-1.6.5.pom (861 B at 3.2 KB/sec)
I want to clearly point Maven for which dependency it have to use internal repository and ignore it for others dependencies (and point that for others dependencies Maven2 have to use public repository).
Could you please help to implement such behavior in Maven?
Thanks In Advance!
According to this answer, it is not possible to set a specific repository for for some of the declared dependencies.
You need to configure the public repository group in Nexus to be used the only one in your Maven builds like the following:
<settings>
<mirrors>
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/nexus/content/groups/public</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<!--Enable snapshots for the built in central repo to direct -->
<!--all requests to nexus via the mirror -->
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<!--make the profile active all the time -->
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
You have to setup a separate repository in nexus like you described a repo called ThirdParty and add this repository into the configuration of the public repository group. Furthermore you need to upload the one dependency into that particular repository. Apart from that you should have to use the release and SNAPSHOT repository which means you need to configuration your distributionManagement accordingly in your company master pom file.

How to setup and use internal Maven repository?

Good day, everyone.
I'm trying to setup an internal repository that I can share with some people within a local network with no access to the Internet. So far, I have setup Archiva in my local machine and point the repository to my ~/.m2/repository. I asked those people to setup their Maven settings.xml and add the following profile:
<profile>
<id>archiva</id>
<repositories>
<repository>
<id>archiva</id>
<url>http://mymachine:8087/archiva/repository/internal/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>archiva</id>
<url>http://mymachine:8087/archiva/repository/internal/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
I've also asked them to set this profile as always active. However, when they try to generate a new Java project using mvn archetype:generate, they always get an error. I actually forgot what the error was but it had something to do with the goal. They can download the jars from Archiva but the generation still fails. I also gave them a copy of the archetype catalog but it's still failing. What am I missing?
I have setup Archiva in my local machine and point the repository to my ~/.m2/repository
I think that this is a wrong idea. You mix two concepts together. Archiva is a foreign repository, while ~/.m2 is a local repository. They should be kept separately, even if the physical machine is the same.
Are you familiar with archetypes? They are project templates, and you need to create an archetype project (and mvn deploy it to your server) so that they can initialize first. Then, they'll pull with code like,
mvn archetype:generate -DarchetypeGroupId=edu.berkeley.cs.sketch -DarchetypeArtifactId=skalch-archetype2 ...
See full example at ntung.com/mvn. I have an example of an archetype project here (github). They're pretty basic and easy to read. Note that the archetype project is a maven project itself, so the top level pom.xml is for the archetype, and the src/main/resources/archetype-resources/pom.xml is where you want to put your above code referencing your server.
Maybe you mean to type archetype:create instead of archetype:generate? See http://maven.apache.org/guides/getting-started/index.html#How_do_I_setup_Maven if that's the case.
BTW, since Maven uses so many plugins, good luck getting it to work without an internet connection! You might try buildr instead.

Maven Profile - Activate Profile depending on packaging

I have a POM which declares web application stuff that is common to my projects. I use this as the parent for all web applications.
Is it possible to activate a profile only when the packaging is war? I have tried the property approach, but that doesn't work (as it isn't a system/environment property).
Since this fails the build, I can simply disable that profile when installing the POM, but I'd like it to be more intelligent on its own.
Walter
You can simply check the existence of src/main/webapp. Each web application that uses the Maven standard directory layout should contain this folder. So you avoid unnecessary dummy files.
<profile>
<id>custom-profile-eclipse-project-generation-webapp</id>
<activation>
<file>
<exists>${basedir}/src/main/webapp</exists>
</file>
</activation>
<build>
</build>
</profile>
More precise you can also check for the the existence of ${basedir}/src/main/webapp/WEB-INF/web.xml. That should definitively identify a war-project.
For myself I use this configuration in my common super-pom to configure the maven-eclipse-plugin for different project types. Thats very handy to get homogenous eclipse-configurations over the same project type in our organization, especially when developers straightforwardly run eclipse:eclipse on multi-module-projects.
I know this isn't answering your question directly, but the usual workaround for problems like this is to just use specialization (as with classes).
So you have your MasterPom with all common behavior.
MasterWarPom that extends MasterPom (is it's parent), and put any 'packing is war' specializations in here.
Likewise you could have MasterJarPom, etc ...
That way the differences are split out nicely.
There's no clean way to do that, the parent module has no way of knowing the child's packaging. (Non-clean solutions would involve creating a plugin that parses the child module's pom etc.)
The best I've been able to come up with for these sorts scenarios has been to use a file-based activation trigger.
eg my parent pom has
<profile>
<id>maven-war-project</id>
<activation>
<file><!-- add a file named .maven-war-project-marker to webapp projects to activate this profile -->
<exists>${basedir}/.maven-war-project-marker</exists>
</file>
</activation>
<build>
<plugins>
<!-- configuration for webapp plugins here -->
</plugins>
</build>
and webapp projects that inherit from this parent contain a file named
'.maven-war-project-marker'
that activates the profile
This looks pretty obtuse but works fairly reliably whereas
- using property-activation is unreliable if a different person or system does the build,
- inheriting from type-specific parents became a bit cumbersome for me as the grandparent-pom changes version relatively frequently as it is used to define 'standard' or preferred versions of common dependencies which in turn required corresponding releases of all of the type-specific parents with no change other than the grandparent version
Try in this way ?
mvn package -Dmaven.test.skip=true -Dwar
<project ×××××>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>××××</groupId>
<artifactId>×××××</artifactId>
<version>×××××</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>×××××</artifactId>
<name>${project.artifactId}-${project.version}</name>
<description>${project.artifactId}-${project.version}</description>
<properties>
<packaging.type>jar</packaging.type>
</properties>
<profiles>
<profile>
<activation>
<property>
<name>war</name>
</property>
</activation>
<properties>
<packaging.type>war</packaging.type>
</properties>
<build>
<finalName>ROOT</finalName>
</build>
</profile>
</profiles>
<packaging>${packaging.type}</packaging>
<dependencies>
<dependency>
... ...
</dependency>
... ...
</dependencies>

what's wrong with my profiles.xml?

This is a portion of my profiles.xml for mvn:
<profilesXml>
<profiles>
<profile>
<id>production</id>
<build>
<plugins> .. </plugins>
</build>
</profile>
</profiles>
</profilesXml>
This is what mvn says:
Caused by: org.codehaus.plexus.util.xml.pull.XmlPullParserException:
Unrecognised tag: 'build' (position: START_TAG seen ...</id>\n
<build>... #32:20)
What's wrong here?
The error message is giving you the correct feedback here, you cannot specify a <build/> section in an external profile, you are only allowed to specify <properties>, <pluginRepositories>, and <repositories>. From the Introduction to Build Profiles:
Profiles in external files
Profiles specified in external files
(i.e in settings.xml or
profiles.xml) are not portable in
the strictest sense. Anything that
seems to stand a high chance of
changing the result of the build is
restricted to the inline profiles in
the POM. Things like repository lists
could simply be a proprietary
repository of approved artifacts, and
won't change the outcome of the build.
Therefore, you will only be able to
modify the <repositories> and
<pluginRepositories> sections, plus
an extra <properties> section.
The <properties> section allows you
to specify free-form key-value pairs
which will be included in the
interpolation process for the POM.
This allows you to specify a plugin
configuration in the form of
${profile.provided.path}.
If your snippet is coming from a book, the book should be fixed.
You can not have <build> area in your profile. Only plugins etc. You can configure the plugins etc.

Missing maven dependency using nexus setup

I am trying to build a maven project to test out some testing software - Arquillian.
I setup nexus and added the jboss repositories to the bottom of the public group.
When i run mvn test i get this error:
Missing:
----------
1) com.sun.istack:istack-commons-runtime:jar:1.1-SNAPSHOT
Try downloading the file manually from the project website.
Then, install it using the command:
mvn install:install-file -DgroupId=com.sun.istack -DartifactId=istack-commons-runtime -Dversion=1.1-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file
Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=com.sun.istack -DartifactId=istack-commons-runtime -Dversion=1.1-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
Path to dependency:
1) org.jboss.arquillian.sandbox.showcase:arquillian-sandbox-showcase-jsf:jar:1.0.0-SNAPSHOT
2) org.jboss.jbossas:jboss-as-client:pom:6.0.0.20100721-M4
3) org.jboss.jbossas:jboss-as-iiop:jar:client:6.0.0.20100721-M4
4) org.jboss.jbossts:jbossjts:jar:4.11.0.Final
5) org.jboss.ws.native:jbossws-native-core:jar:3.3.0.CR1.SP2
6) com.sun.xml.ws:jaxws-rt:jar:2.2
7) com.sun.xml.ws:policy:jar:2.0-b01
8) com.sun.istack:istack-commons-runtime:jar:1.1-SNAPSHOT
I checked the java.net maven 2 repository and it is definately there.
However when i navigate to my local nexus public group, it is not there.
How can i solve this problem? And what is the cause of this problem? I am in way over my head with this, as I am more accustomed to using ant+ivy.
The full output from mvn is here.
I had apparently the exact same problem. I solved it.
In my case, the problem was that the repository that was hosting istack-common-runtime-1.1.0-SNAPSHOT was flagged "release" in the configured nexus proxy repo. So nexus was ignoring all snapshots in that repository.
I just configured another proxy repository pointing on the same one that contains istack-common-runtime-1.1.0-SNAPSHOT, but flagging it to "SNAPSHOT" when configuring it. I then added this new proxy to my "SNAPSHOT" group.
In my settings.xml, I have a repository on the public nexus group and another on the snapshots group :
<profiles>
<profile>
<id>nexus</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>release</id>
<url>http://nexus-server/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>snapshots</id>
<url>http://nexus-server/nexus/content/groups/public-snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
Hope this help
Does it show up if you use the nexus web interface to search for it? I've seen cases in our nexus install where an artifact looks like it's missing like this, but shows up in the search results. If I then download it via my browser from the search results, it magically starts working at the maven command line.
Not the robust solution you want to hear, I'm sure, but it's at least worth a try.
If you've added the JBoss repository to Nexus, did you remember to configure your Public Repositories group to include it?
Here's a screenshot:
Are you behind a corporate firewall? Perhaps a HTTP proxy needs to be configured within Nexus (See the Server admin screen)
Ended up being a bad dependency. I had to add it manually to get it all working. Terrible!