Replacing variables when packaging the pom.xml into JAR - java

I have a Java Maven project with several modules. When referencing to the parent module from the individual modules, the following information is added to project A\module-sample-app\pom.xml:
<groupId>org.apache.maven</groupId>
<artifactId>module-sample-app</artifactId>
<packaging>jar</packaging>
<name>module-sample-app</name>
<parent>
<groupId>org.apache.maven</groupId>
<artifactId>sample-app-parent</artifactId>
<version>1.0-${buildLifeId}</version>
</parent>
The parent application A has the following entry in A\pom.xml:
<artifactId>A</artifactId>
<packaging>jar</packaging>
<name>A</name>
<version>1.0-${buildLifeId}</version>
To run the build, the following is executed on the parent directory of project A:
Example: mvn clean install -DbuildLifeId=1001
The JAR file generated has an embedded pom.xml with string ${buildLifeId} and not the value 1001.
When trying to use on the module sample-app in another application, B, as the runtime variable was not replaced with the actual value, it is failing to fetch the dependency. Just to highlight, B is not a module of A.
In B\pom.xml:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>module-sample-app</artifactId>
<version>1.0-1001</version>
</dependency>
With this dependency, as the pom.xml embedded within the module-sample-app-1.0-1001.jar would have the parent version defined as <version>1.0-${buildLifeId}</version>, the dependency fails to load.
So my questions is - does Maven support a plugin that can replace the run time variables before packaging the pom.xml into the JAR? Or is there a workaround. Can I use Ant plugins to replace the buildLiefeId variable in the version node to actual value when JAR is built?

I was already using ${revision} - I just had to use the Maven Flatten plugin in both the parent and child poms to fix this issue.

Related

Add maven project as dependency in maven project

I have two Maven projects, both created from the default Maven structure in Eclipse.
Project A is dependant on Project B. In order to utilise classes from A in B, I can add B to A's build path.
How can I achieve the same effect using Maven?
Currently, I have both of the projects on my file system, but I would like to add this dependency in as similar a way as possible to, for example, adding GSON from a remote repository (Fig. 1), as that is how I would like to handle my own repositories in future.
Currently, when I try this:
<dependency>
<groupId>vision.voltsofdoom</groupId>
<artifactId>voltsofdoom</artifactId>
<version>0.0.1</version>
<type>pom</type>
</dependency>
... and remove any other projects from the build path, Eclipse is unable to resolve any of my imports (everything works fine when I add Project B (voltsofdoom) to A's (casketofazamgarath) build path.
B's (voltsofdoom) basic pom looks like this.
<groupId>vision.voltsofdoom</groupId>
<artifactId>voltsofdoom</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
B (voltsofdoom) does not appear in the "Local Repository" tab in the "Maven Repositories" View, instead appearing in "Workspace Projects".
Figure 1 (Adding GSON):
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
</dependency>
==
Answer:
Follow the correct marked answer.
The amended snippet is:
<dependency>
<groupId>vision.voltsofdoom</groupId>
<artifactId>voltsofdoom</artifactId>
<version>0.0.1</version>
</dependency>
You can run the maven clean install goal on the project that has no dependency on the other (i.e. the "dependency"), which will "export" your project to your local .m2 directory in your users directory.
After that, you should be able to access it from the depending project with the code snippet you mentioned in your question (although I'm not quite sure what the <type> tag does).

How to include the modules in a top-level POM in another project?

I've googled and stack-overflowed everything, but maybe not enough as I'm still not clear how one adds a module of a Maven project as a dependency in another.
So for example let's say we've got:
MajorPager
|___ POM.xml
|___ chuck-commons-core
| |____POM.xml
|____rajni-commons-core
|____POM.xml
Now I want to add chuck-commons-core but not rajni-commons-core. If I do it directly, it can't find the module. So I ran across the following discussions on stack-overflow and my old friend Guggal:
In summary, the below discussions talk of how to create multi-module projects but not really how to include the sub-modules in a top-level POM into another project.
Useful discussions for context
SO Adding a reference to a parent POM project
SO How to add a parent POM as dependency to a different maven project
SO Adding a reference to Parent POM
SO Maven Parent POM vs Modules POM
SO Depend on multi-module aggregator project
SO How to add dependency in Eclipse?
SO How do I configure Maven multi-module-dependency on sub project with different package?
SO How to add a module in parent projects POM as dependency?
SO How to add a dependency in Maven?
Maven dependency mechanism
Maven POM aggregation
Baeldung Multi-module project
Codetab Maven multi-module
Howtodoinjava Maven parent child POM example
Mastertheboss Maven multi-module tutorial
Codetab Multi-module hierarchical project
Sonatype How to share resources across projects
Spring Multi-module project
Concretely, I'd just like a summary from an expert how they add a sub-module of a Parent POM as a dependency to another project.
As of now, I think this is the best solution - to add the following ccodee to the POM.xml of the MajorPager.
Code block 1 incoming
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.teachme.how</groupId>
<artifactId>MajorPager</artifactId>
<version>0.6-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Code block 2 incoming
<dependencies>
...
<dependency>
<groupId>com.teachme.how</groupId>
<artifactId>norris-commons-core</artifactId>
<version>0.6</version>
</dependency>
...
</dependencies>
When you do so enables Maven to find out where the dependency are - and so Maven picks them up with mvn clean -U install or mvn package -U -DskipTests. And I should like to be educated if this isn't the most effective pattern. Or if any of the fields above are optional that Maven doesn't want me to specify because it can derive it on it's own (say for example, version tag?) - please let me know if that's case as well.

Pom tag <finalName> is not working correctly

My project has pom.xml which builds up ear. I have added the finalName tag in pom.xml e.g. test-ear-${parent.version}-${region}. I am using following command -> mvn clean install -Dregion=QA. In my local workspace ear is formed with correct name as test-ear-3.5.23.0-QA.ear. However when it installs in the repository its build like test-3.5.23.0.ear. Means it is ignoring the finalName when installing in local repository.
What I understand is, maven is ignoring tag and using ArtifactName + Version to build name of artifact. Also I am not able to override version of artifact test-ear, because I suppose I am using the relative path in parent tag. Here is my sample pom.xml:-
<parent>
<groupId>com.proj</groupId>
<artifactId>test-parent</artifactId>
<relativePath>../test-parent/pom.xml</relativePath>
<version>${pom.version}</version>
</parent>
<groupId>com.proj.child</groupId>
<artifactId>test-ear</artifactId>
<packaging>ear</packaging>
<build>
<finalName>test-ear-${parent.version}-${region}</finalName>
<plugins>
<plugin>
.................
It works for me if I provide artifact version and versions of all the dependencies for test-ear artifact. Can someone guide, what is wrong with my pom.
Where is the properties label? you must put the field in this label,then get it use ${fieldname}.

Maven Modules with Variable as Version number

I got a Maven project with the following structure:
Module A (parent), Submodule B and Submodule C
In the parent pom.xml I am using a variable for settings the version of all projects:
...
<version>${revision}</version>
...
<properties>
<revision>1.1</revision>
</properties>
...
<modules>
<module>moduleB</module>
<module>moduleC</module>
</modules>
</project>
Module C is my distribution package which uses the shade plugin for packaging everything into one single jar.
In the submodules I set the parent like this:
<parent>
<groupId>group</groupId>
<artifactId>moduleA</artifactId>
<version>${revision}</version>
</parent>
Now I want to use Module C in another project, however I only get the following error when doing so:
Failed to execute goal on project newProject: Could not resolve dependencies for project group:newProject:jar:0.0.1-SNAPSHOT: Failed to collect dependencies at group:moduleC:jar:1.1: Failed to read artifact descriptor for group:moduleC:jar:1.1: Could not find artifact group:parent:pom:${revision} in nexus (NEXUS_URL)
I assume the problem is, that the variable value is not filled in when referencing Module C as dependency. How can I solve this issue? I already tried to clean the project before building and forcing to update all artifacts without success.
Maven expects all modules to have a hard version.
To avoid editing lots of poms, use the versions plugin, example:
mvn versions:set -DnewVersion=1.0.1
If you run the above command on the parent it will fix all the child poms.
See here for documentation.
Thanks to the comment of hadu.mansouri I could fix it. I used flatten-maven-plugin for flattening the pom.xml files. However, it seems to have a problem with the shade plugin, as the shaded module was the only module where it did not work. Thus, in the released shade module pom it said:
<version>${revision}</version>
for referencing the parent. I used the approach of the article linked in the comment. There, this extension was used: https://github.com/jcgay/unique-revision-maven-filtering
Using this instead of the flatten-maven-plugin, Maven builds the multi module project correctly with the single version property, and I can also use the shaded module in other projects properly.

How to store runtime variables in a Maven project and access it from a different module during build

I have a multi-module maven project ,where the modules call java classes.I want to store a variable and access it from other module.Can it be done using MavenProject? if yes how can I use it
If you are referring to sharing variables across pom.xml, You can set the variables in the tag in the parent pom.xml and reference it from other modules.
something like
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.version>0.0.1-SNAPSHOT</project.version>
</properties>
and refer in the modules as ${project.version}
When I had the same issue, I installed one module as a jar inside the other one.
Let's say I have a module A, and the Module B wants to access runtime variables in module B.
In module A I would put this line in the pom.xml
<packaging>jar</packaging>
In module B I would import module A as a dependency
<dependency>
<groupId>com.my.module.A</groupId>
<artifactId>my-module-A</artifactId>
<version>modueAversion</version>
</dependency>
Then I would run a maven install in module B, which installs the module B in my repository.
After that update the dependencies in project A. In the maven dependencies section you should see an entry such as "moduleA.jar".
In this way, you can access all the runtime variables, classes, and methods of module A from module B.
I don't know if this is what you needed. I hope to have been of some help

Categories