How to specify maven's distributionManagement organisation wide? - java

I'm trying to figure out how to organize many (around 50+) maven2 projects, so that they can deploy into a central nexus repository. When using the mvn deploy goal, one does need to specify the target in the distributionManagement tag like this:
<distributionManagement>
<repository>
<id>nexus-site</id>
<url>http://central_nexus/server</url>
</repository>
</distributionManagement>
Now, i don't want every single pom.xml (of those 50+) to contain this block over and over again. My first though would be the settings.xml file, but it seems it is not possible (by design) to define it there.
So, the first question would be, why is that the case ? If it would be possible i could specify it in the settings.xml in the maven2 distribution, which could be distributed to all developers.
The only possible solution i've found was to create an organisation-wide master-pom project, that does contain these settings, and make all other pom.xml depend on this master-pom via <parent> tag. But this looks kind of strange in multi-module builds:
- master configuration POM (pm)
- Project 1 parent pom (p1 with module 1 and module 2 as modules)
- Project 1 module pom (with pm as parent)
- Project 2 module pom (with pm as parent)
Usually i read in all documentation that the module poms should use the parent pom, not some different one. But after reading the maven website about Inheritance v. Aggregation it is written that it is indeed possible.
One problem i found was with the maven site generation, which does seem to have problems with this setup (modules does not get linked correctly if they have no direct back-reference)
So, is this a valid approach ? Any other, more obvious, simpler solution to the problem ?

The best solution for this is to create a simple parent pom file project (with packaging 'pom') generically for all projects from your organization.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>your.company</groupId>
<artifactId>company-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<distributionManagement>
<repository>
<id>nexus-site</id>
<url>http://central_nexus/server</url>
</repository>
</distributionManagement>
</project>
This can be built, released, and deployed to your local nexus so everyone has access to its artifact.
Now for all projects which you wish to use it, simply include this section:
<parent>
<groupId>your.company</groupId>
<artifactId>company-parent</artifactId>
<version>1.0.0</version>
</parent>
This solution will allow you to easily add other common things to all your company's projects. For instance if you wanted to standardize your JUnit usage to a specific version, this would be the perfect place for that.
If you have projects that use multi-module structures that have their own parent, Maven also supports chaining inheritance so it is perfectly acceptable to make your project's parent pom file refer to your company's parent pom and have the project's child modules not even aware of your company's parent.
I see from your example project structure that you are attempting to put your parent project at the same level as your aggregator pom. If your project needs its own parent, the best approach I have found is to include the parent at the same level as the rest of the modules and have your aggregator pom.xml file at the root of where all your modules' directories exist.
- pom.xml (aggregator)
- project-parent
- project-module1
- project-module2
What you do with this structure is include your parent module in the aggregator and build everything with a mvn install from the root directory.
We use this exact solution at my organization and it has stood the test of time and worked quite well for us.

There's no need for a parent POM.
You can omit the distributionManagement part entirely in your poms and set it either on your build server or in settings.xml.
To do it on the build server, just pass to the mvn command:
-DaltSnapshotDeploymentRepository=snapshots::default::https://YOUR_NEXUS_URL/snapshots
-DaltReleaseDeploymentRepository=releases::default::https://YOUR_NEXUS_URL/releases
See https://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html for details which options can be set.
It's also possible to set this in your settings.xml.
Just create a profile there which is enabled and contains the property.
Example settings.xml:
<settings>
[...]
<profiles>
<profile>
<id>nexus</id>
<properties>
<altSnapshotDeploymentRepository>snapshots::default::https://YOUR_NEXUS_URL/snapshots</altSnapshotDeploymentRepository>
<altReleaseDeploymentRepository>releases::default::https://YOUR_NEXUS_URL/releases</altReleaseDeploymentRepository>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
Make sure that credentials for "snapshots" and "releases" are in the <servers> section of your settings.xml
The properties altSnapshotDeploymentRepository and altReleaseDeploymentRepository are introduced with maven-deploy-plugin version 2.8. Older versions will fail with the error message
Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter
To fix this, you can enforce a newer version of the plug-in:
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8</version>
</plugin>
</plugins>
</pluginManagement>
</build>

Regarding the answer from Michael Wyraz, where you use alt*DeploymentRepository parameters in your settings.xml or command line, the format has changed in version 3.0.0 of the maven-deploy-plugin
In the value:
releases::default::https://YOUR_NEXUS_URL/releases
you need to remove the default section, making it:
releases::https://YOUR_NEXUS_URL/releases

Related

How to build/run a maven project as both a .war and .jar? [duplicate]

I have a project which I compile with maven. I have different profiles declared in pom.xml.
For some of these profiles, I prefer building a war, and for other profiles I prefer a jar. I use to manually edit the pom.xml file and change packaging variable to either
<packaging>war</packaging>
or
<packaging>jar</packaging>
before doing a
$ mvn clean package -Pchosenprofile
How can I tell mvn the packaging corresponding to each profile so I don't need to edit pom.xml?
If you want to use profile you can use something like:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
..
<packaging>${packaging.type}</packaging>
<profiles>
<profile>
<id>webapp</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<packaging.type>war</packaging.type>
</properties>
</profile>
<profile>
<id>batch</id>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
</profiles>
</project>
Have you looked at the attachClasses configuration setting of the war plugin? This simple setting would let you build both a war and a jar (by default with the classifier "classes") in a single maven execution.
I don't think you can.
Two alternatives I can think of:
have two separate modules for packaging, and call one of those depending on profile
have your module in war and tweak the lifecycle (include/exclude build steps) depending on profile to produce your jar or your war
I like the second approach better - a build server would probably build both, and a developer would use the proper profiles/settings to skip the unwanted type.

POM maven Parent issue HOW to

this is my first Maven plugin project and I am following this guide
http://wiki.eclipse.org/OM2M/one/Developer
yet , I am having similar issue with this thread
Convert java plugin into maven project with eclipse-plugin packaging
he said "Edit 3 : I managed to remove the error by setting the main pom.xml as a parent but now when i try to build i have the following error :", I do want to know how he did that
here is my pom
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.om2m.sample.ipe</groupId>
<artifactId>org.eclipse.om2m.sample.ipe</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
build properties
source.. = src/main/java
output.. = bin/
bin.includes = META-INF/,\
Location:
C:\Users\Ahmad\workspace\org.eclipse.om2m.sample.ipe
.
Path:
/org.eclipse.om2m.sample.ipe
the error is on POM
eclipse-plugin
it says Unknown packaging
thanks
Take a look at this question. The most voted answer states that:
The packaging type eclipse-plugin is defined by a Maven build extension called Tycho.
In order to use Tycho's packaging types, you need to configure Tycho as a build extension:
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
You might also want to take a look at this post in the Eclipse Community Forum.
The user Francois Assoui states that:
The "eclipse-plugin" packaging is not available in the standard set of
maven packaging. It is provided by the Maven plugin Tycho made for
handling OSGi plugins compilation and creation of sites (project that
gather a set of plugins for a specific configuration).
At the state where you have to enter the packaging, the IDE can not
give you the right choice as it does not know that we are going to use
Tycho. You have to type it manually and you will have an error at that
time. But you just have to make the link to the parent project in the
next step to solve this error. In fact, the parent project imports the
Tycho plugin.

Maven project with "war" packaging: how to create JAR with maven-jar-plugin? [duplicate]

I have a project which I compile with maven. I have different profiles declared in pom.xml.
For some of these profiles, I prefer building a war, and for other profiles I prefer a jar. I use to manually edit the pom.xml file and change packaging variable to either
<packaging>war</packaging>
or
<packaging>jar</packaging>
before doing a
$ mvn clean package -Pchosenprofile
How can I tell mvn the packaging corresponding to each profile so I don't need to edit pom.xml?
If you want to use profile you can use something like:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
..
<packaging>${packaging.type}</packaging>
<profiles>
<profile>
<id>webapp</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<packaging.type>war</packaging.type>
</properties>
</profile>
<profile>
<id>batch</id>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
</profiles>
</project>
Have you looked at the attachClasses configuration setting of the war plugin? This simple setting would let you build both a war and a jar (by default with the classifier "classes") in a single maven execution.
I don't think you can.
Two alternatives I can think of:
have two separate modules for packaging, and call one of those depending on profile
have your module in war and tweak the lifecycle (include/exclude build steps) depending on profile to produce your jar or your war
I like the second approach better - a build server would probably build both, and a developer would use the proper profiles/settings to skip the unwanted type.

best practice for making a maven parent project

I developped a multi-module project which is a kind of java web framework.
One of the submodules is a parent pom that I provide for the users of my framework. This parent configures plugins and dependencies for them.
My problem is that this parent pom must refers the sibling modules with their version, which is ${project.version}, and because of the maven project inheritance, the ${project.version} is not the one I want.
To illustrate, my framework projects structure looks like :
my-framework/
|_pom.xml
|_parent/
|_pom.xml
|_server/
|_pom.xml
|_ui/
|_pom.xml
and my parent pom looks like :
<project
....
<!-- General information -->
<modelVersion>4.0.0</modelVersion>
<artifactId>my-framework-parent</artifactId>
<packaging>pom</packaging>
<parent>
<groupId>my.framework</groupId>
<artifactId>my-framework</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<my.framework.version>${project.version}</my.framework.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>my.framework</groupId>
<artifactId>my-framework-server</artifactId>
<version>${my.framework.version}</version>
</dependency>
<dependency>
<groupId>my.framework</groupId>
<artifactId>my-framework-ui</artifactId>
<version>${my.framework.version}</version>
</dependency>
</dependencyManagement>
...
</project>
Then, if a user uses this parent, as maven resolves ${project.version} in the context of the user's project, ${my.framework.version} will be the user's project version instead my framework's version.
To solve this I generated the parent pom I want thanks to the maven-resources-plugin and I overrided the maven-install-plugin behaviour to install the generated pom.
My solution looks tricky and I would like if someone who faced the same problem has a better solution?
I finally found a solution thanks to the flatten-maven-plugin.
But I had to post a pull request to support the pluginManagement section.
https://github.com/mojohaus/flatten-maven-plugin/pull/10
So the solution was to modify my parent pom thanks to this plugin before publishing it. As a result I can set the version I want instead of using ${project.version}.

Looking for a Maven shortcut -- including a jar file in a Maven build

I've inherited a Maven project. I'm just using it as a build tool and I'd like to disturb things as little as possible. I have to make a slight addition to one of the Java files and that addition requires that I include a new jar on the build path. How do I say: here a jar, just use it. It doesn't have to be versioned or depended or downloaded or anything, just use it. Any help would be appreciated.
EDIT: I found this, which actually works (!). If someone who knows about such things could read this answer and if it seems reasonably correct, please close this question as a dup.
EDIT: Nope, I misinterpreted my results. It doesn't seem to work.
By far the best way to manage your dependencies with maven is to get them from a repository, but four total options spring to mind, in order from most desirable to least:
If the jar is a common third-party library, you'll almost certainly find it in some repository somewhere. You just have to add a <dependency> element and possibly a <repository> as well so it knows where to get the dependency from.
A home-grown jar not available in any repo should be deployed to a local repository, like Nexus, which is available to your whole team/company. Then add the dependency to your project just like in option 1. This way it only has to be dealt with once, and everyone else can get the jar via the normal Maven mechanism.
To only deal with the problem locally and not give any reusability of the artifact, you can install it into your local repo (meaning your local cache at ~/.m2/repository) using the install:install-file goal.
Finally, and least desirably, you can use a system-scoped dependency. This means you have the jar file available somewhere in your file system, set the <scope> element of your <dependency> to the value "system", and add a <systemPath> element that contains the full path to the jar in question.
Edit: Since option 4 seems right for you, just put the jar into your project and commit it to your version control. Then, assuming the jar is at lib/foo.jar in your project, add this to your POM's dependencies:
<dependency>
<groupId>some-group</groupId>
<artifactId>some-artifact</artifactId>
<version>1.2.3.4</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/foo.jar</systemPath>
</dependency>
That's all from memory, but it sounds right.
Here are some related answers:
Maven: keeping dependent jars in project version control
I would not recommend using install:install-file from a POM - if it's a once off requirement you're better using that from the command line and documenting it as a preparation step. However, making the build self-contained or providing a repository with the required artifacts are certainly better options.
Here is how to proceed. Create a separate maven project inspired from the following pom.xml.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.dwst</groupId>
<artifactId>MavenMissingJars</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>Maven Missing Jars</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>dProguard-4.6</id>
<phase>generate-sources</phase>
<goals>
<goal>install-file</goal>
</goals>
<inherited>false</inherited>
<configuration>
<file>toinstall/4.6/proguard.jar</file>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard</artifactId>
<version>4.6</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Assuming there is a /toinstall/4.6/ directory relative to your pom.xml and that a jar called proguard.jar is in there, calling this plugin will copy the jar from your local directory to your maven local repository.
This has to be executed once, that's why it is preferable to have a separate small maven project for injecting missing jars.
Then, add a dependency in your project using the coordinates (artifactid, version and packaging) you have defined in the above pom.xml.

Categories