multi artifact id in one pom - maven

There is a maven project(jar), but now it needs to be spilt into two artifacts
I want to have two maven artifact like following
<groupId>xxx</groupId>
<artifactId>xxx-client</groupId>
<groupId>xxx</groupId>
<artifactId>xxx-impl</groupId>
But all the code is in one single project.
My question would be, How can I package the tow required artifacts without changing the project too much.
Then ,
mvn package deploy
will auto deploy these two artifacts into repository
Actually I don't want to split these project into two maven project.

I am not sure if there is a possibility of having two <artifactId> tags in one POM, since it is unique. What you may do is, you can have two pom files, say, pom.xml, and pom_impl.xml, now
to deploy client do, mvn package deploy
to deploy impl do, mvn -f pom_impl.xml package deploy
Never tried though.
Clarification: The question seem ambiguous, seems like you have one project but you wanted to generated two artifacts (client, and impl) of the same code-base. On reading it again, I feel like you have two projects (two different code base) but you just wanted to unify it so that it behaves as two modules of the same project. My answer assumes the first case.

If I understood the question correct, you need to have a super pom (xxx/pom.xml) and two different poms for both of your projects (xxx-client and xxx-impl). The structure of your super pom will be like this:
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<packaging>pom</packaging>
<modules>
<module>xxx-client</module>
<module>xxx-impl</module>
</modules>
</project>
Then when you deploy your main pom, it will deploy it's modules as well.
Here are references if you want to read more about super pom and modules.

This is called "multi module project" in the Maven world. You can find information on how to do this e.g. here. Indeed you need two separate POMs and an additional one to combine both.

specify pom
Make two pom ,then specify the pom in command line, that is the easiest way.

Related

Intellij - Add project as dependency to another project

I am trying to make my project work on intellij (it works with eclipse). I have a project with this in 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>com.fitnetapplication</groupId>
<artifactId>fitnet-common</artifactId>
<version>6.0.2-Final</version>
<packaging>war</packaging>
<name>FitnetCommon</name>
<description>Socle Commun FitnetManager / SyrhaLogic</description>
Now i have another project which needs to be linked to this one, so I had:
com.fitnetapplication
fitnet-common
6.0.2-Final
runtime
war
<dependency>
<groupId>com.fitnetapplication</groupId>
<artifactId>fitnet-common</artifactId>
<version>6.0.2-Final</version>
<type>jar</type>
<scope>provided</scope>
<classifier>classes</classifier>
</dependency>
The problem is that on Intellij, the version is not accepted for some reason, I don't know why, it tells me that the version 6.0.2-Final is not found for the artifact fitnet-common
To confirm - you are actually running mvn clean install (or similar) on the first project before trying to resolve the dependency in the second project?
If you are, it sounds like you're installing the project using one Maven repo location, and then in the other project it is looking in a completely different location. Are your .m2 location settings identical for both projects?
Edit:
Is it because you're specifying the first project as a war packaging, but in the dependency declaration you are looking for a jar? They would essentially be two different artefacts:
.war - com.fitnetapplication:fitnet-common:6.0.2-Final:war
.jar - com.fitnetapplication:fitnet-common:6.0.2-Final:jar
Check in your .m2/com/fitnetapplication/fitnet-common/6.0.2-Final to see what you have there, likely it is just the war file.

What are .pom files in Maven build artifacts?

You can see from browsing any repository that Maven build artifacts contain .pom files. The contents of these files look a whole lot like pom.xml files. Where do these files come from? What are they used for? Additionally, build artifacts have maven-metadata.xml files, at least on search.maven.org, and these files have substantially the same content as the .pom files. What's the deal with that?
The files are the pom files from within the project. Those are deployed to the maven repository during the release build or by other build tools as well (gradle, ivy, etc.).
Those files are needed to describe the dependencies of the appropriate artifact otherwise you have no other opportunity to store such kind of information.
In your particular example (really old 2005) this is a pom file which is created at a time of times where maven was not such distributed. In this case the file does not contain any dependencies.
If you take a look here:
http://search.maven.org/#browse%7C-77609479
you see a number of versions of a single artifact. If you now take a look into the maven-metadata.xml you will see list of available versions.
The best answer I have found so far is in this SO thread. Here is an exact quote, highlighting the crux of the explanation:
Every jar needs to have a pom file describing it, you can just add something simple like this:
<?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>aGroup</groupId>
<artifactId>aArtifactId</artifactId>
<version>aVersion</version>
<packaging>jar</packaging>
<name>a Name</name>
</project>
Another good explanation:
POM that is installed to Nexus will describe the jar. Used to pull the
dependencies that are associated to corresponding jar. When we add the
jar as dependency to our project, all the jars required for the
included jar will be identified through the corresponding pom.

Automate creation of pom file dependencies based on the jar file

I have hundreds of jar files scattered across different projects that I need to create pom file dependencies files for. I'd really like to avoid manually searching for every jar file and adding the dependency manually. Is there an API I can use to accomplish this task or some other way ?
Ive tried using a generic pom as described : http://maven.apache.org/plugins/maven-install-plugin/examples/generic-pom-generation.html
Using this command - mvn install:install-file -Dfile=spring-webmvc-portlet-3.0.6.RELEASE -DgroupId=test -DartifactId=test -Dversion=version -Dpackaging=jar-DgeneratePom=true
But should the generated pom not match the jar file ? Or do I need to add this myself
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>version</version>
<packaging>jar-DgeneratePom=true</packaging>
<description>POM was created from install:install-file</description>
</project>
I wrote a script that generates an ivy file. It uses the jar checksums to identify the matching modules in Maven central.
https://github.com/myspotontheweb/ant2ivy
This solution could be adapted to generate a Maven POM.
You may create a bash script which uses the Maven Install plugin to produce a generic POM.
See http://maven.apache.org/plugins/maven-install-plugin/examples/generic-pom-generation.html

Why Maven is looking for .pom file when .jar is present in the repository?

I have the following dependency in my pom.xml
<dependency>
<groupId>aGroup</groupId>
<artifactId>anArtifact</artifactId>
<version>aVersion</version>
</dependency>
I also have the anArtifact-aVersion.jar file in ~/.m2/repository/aGroup/anArtifact/aVersion directory.
When I start building the project, maven looks for a .pom file instead of using the .jar file and attempts to download the following
http://repo1.maven.org/maven2/aGroup/anArtifact/aVersion/anArtifact-aVersion.pom
How can I configure maven to use the existing .jar file?
Every jar needs to have a pom file describing it, you can just add something simple like this:
<?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>aGroup</groupId>
<artifactId>aArtifactId</artifactId>
<version>aVersion</version>
<packaging>jar</packaging>
<name>a Name</name>
</project>
Run your build using the "-o" switch to use Maven in offline mode. In offline mode, Maven will not check for updates of snapshot dependencies in remote repositories.
the best way to install an artifact to the local repository which were not built by Maven ist to use
mvn install:install-file ...
have a look at the install:install goal.
POM that is installed to nexus will describe the jar. Used to pull the dependencies that are associated to corresponding jar. When we add the jar as dependency to our project, all the jars required for the included jar will be identified through the corresponding pom.
It is looking for the pom to, among other things, resolve the transitive dependencies.

Maven: Selecting Parent Project Based On Profile

I have a maven project - it is a plugin for jenkins. It's parent should be a:
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.414</version>
</parent>
But at the same time this plugin can be also used for hudson, without changing any line of code. But the parent project for it should be:
<parent>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>hudson-plugin-parent</artifactId>
<version>2.0.1</version>
</parent>
Can I specify 2 different profiles for that and use them to build plugin for jenkins or hudson accordingly? So that I call something like that:
mvn package -P jenkins
or
mvn package -P hudson
I have tried to specify properties in profiles, but those are not replaced by their values inside the <parent> tag. So is there any other possibility to build plugin for both, but with as much as possible common code and files?
Added: So, if I cannot do that, what should I do then? How to refactor? What the new structure should be?
As already mentioned, this is not possible.
Also, it is not possible to set a property for the parent's version as the interpolation for that happens a lot earlier than the handling of the profiles.
I would suggest that you create a masterbuild project as follows:
master
|-plugin-jenkins
|-plugin-hudson
|-plugin-assembly
The master should build all three as usual. However, in the assembly, you could add each of the two plugins as dependencies in separate profiles. And... each of these plugins can have the parent you like.
This is obviously somewhat a deviation from the Maven convention, but I believe it is a solution to your problem.
It's not possible because the tag "parent" is not available in the profiles section of the pom.
Currently we decided to stick with 1 repository and 2 separate pom.xml files, giving maven key which pom.xml use to build the project.
mvn package -f pom-jenkins.xml
mvn package -f pom-hudson.xml
No you cannot do that. you will have to refactor somehow to avoid the necessity.
As mentioned already not possible. I would suggest to make separate projects for jenkins plugin and hudson plugin. I assume that in not that far future that will not work anymore cause Hudons and Jenkins will diverge.
In general, you should be able to set the {group,artifact}Id and version of the parent POM via Java System Properties or Environment Variables, but it seems there is a Bug in Maven which will only be fixed in 4.x:
https://issues.apache.org/jira/browse/MNG-624
Another solution is to delegate the inclusion of the parent POM to your own parent POMs which you reference in the relativePath element, and change the content of the target e.g. via a symlink or cp command.
So in the main POM you would write:
<parent>
<groupId>org.mycompany.project</groupId>
<artifactId>foo-artifact</artifactId>
<version>1.0.0</version>
<relativePath>./my-parent.pom</relativePath>
</parent>
And in my-parent-jenkins you would just put:
<groupId>org.mycompany.project</groupId>
<artifactId>foo-artifact</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.414</version>
</parent>
The same project information with the block for hudson you put in my-parent-hudson.pom.
No you can either use
ln -s my-parent-jenkins.pom my-parent.pom
or
ln -s my-parent-hudson.pom my-parent.pom
to include the respective parent POM without the need to maintain two different main POM files for your project.
In case POM does not exist at the place referenced in relativePath, Maven will look up the POM in the remote repository[1], which is also an easy way to overwrite a parent POM locally.
[1] http://maven.apache.org/components/ref/3.3.9/maven-model/maven.html#class_parent

Resources