Merge parent and child pom during assembly - maven

I have a multi-module maven project. I want to assembly each of the child so when they are uncompressed and executed with maven to not depend on the parent pom.
Is there a way with assembly plugin to kind of "merge" the parent pom and the child pom?
Original project:
├── pom.xml
├── README.md
├── module1
│   ├── assembly.xml
│   ├── pom.xml
│   ├── README.md
│   └── src
└── module2
├── assembly.xml
├── pom.xml
├── README.md
└── src
Assembly package (zip):
moduleX
├── pom.xml <-- merged pom
├── README.md
└── src
The packaged assembly will be used by an external client outside from our organization, so he doesn't have access to our repositories.
Update:
As JF Meier suggested, using flatten-maven-plugin solves my issue.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>flatten</id>
<phase>prepare-package</phase>
<goals>
<goal>flatten</goal>
</goals>
<configuration>
<flattenMode>bom</flattenMode>
<pomElements>
<build>keep</build>
</pomElements>
</configuration>
</execution>
</executions>
</plugin>
And then on my assembly.xml I just add the generated .flattened-pom.xml and rename it to pom.xml:
<files>
<file>
<source>.flattened-pom.xml</source>
<destName>pom.xml</destName>
</file>
</files>

I guess you want something like the
https://www.mojohaus.org/flatten-maven-plugin/
It allows you to "merge" the parent POM into your POM.

Related

Using maven properties plugin to access custom properties

I've created a maven archetype which works just fine, but I would like to set some properties based on who generates the archetype.
This is how I'm incorporating the plugin:
<build>
<extensions>
<extension>
<groupId>org.apache.maven.archetype</groupId>
<artifactId>archetype-packaging</artifactId>
<version>3.2.1</version>
</extension>
</extensions>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-archetype-plugin</artifactId>
<version>3.2.1</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>home/.m2/developer.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
I've created a properties file which looks like this:
developerName=MyName
developerEmail=MyEmail
And I'm trying to access it like this:
<developers>
<developer>
<name>${properties.developerName}</name>
<email>${properties.developerEmail}</email>
<organization>MyOrg</organization>
<organizationUrl>MyOrgUrl>
</developer>
</developers>
I've tried using project.developerName as well but it still doesn't get replaced. I'm starting to wonder if it has something to do with the archetype generation.
This is the layout:
├── pom.xml **<-- This is the pom I'm using for the plugin**
├── readme.md
├── src
│   ├── main
│   │   └── resources
│   │   ├── archetype-resources
│   │   │   ├── ci_settings.xml
│   │   │   ├── mvnw
│   │   │   ├── mvnw.cmd
│   │   │   ├── pom.xml **<-- This is the pom that I want properties to be included in**
│   │   │   ├── src
│   │   │   │   └── main
│   │   │   │   ├── java
│   │   │   │   │   └── Name.java
│   │   │   │   └── resources
│   │   │   │   └── application.yaml
│   │   │   └── system
│   │   │   ├── __artifactId__.yaml
│   │   │   └── image-tag.txt
│   │   └── META-INF
│   │   └── maven
│   │   └── archetype-metadata.xml
I'm not entirely sure what I'm doing wrong, and I find it hard to find a clear answer on how this is done through reading the docs. I feel like this should work, but like I mentioned, I'm not sure if this being an archetype is messing something up.

Missing plugin and feature folders for an update site built with Maven Tycho

I am building an eclipse plugin with Tycho. I want to create an Update Site for it. I have the following components:
parent (pom)
the plugin (eclipse-plugin)
the feature (eclipse-feature)
the update site (eclipse-repository)
But when I run mvn clean package in the target folder of my update site project I have:
├── lorem-ipsum-eclipse-update-1.0.1-SNAPSHOT.zip
├── local-artifacts.properties
├── p2agent
│   ├── org.eclipse.equinox.p2.core
│   │   └── cache
│   │   └── artifacts.xml
│   └── org.eclipse.equinox.p2.engine
│   └── profileRegistry
├── p2artifacts.xml
├── p2content.xml
├── repository
│   ├── artifacts.jar
│   ├── artifacts.xml.xz
│   ├── content.jar
│   ├── content.xml.xz
│   └── p2.index
└── targetPlatformRepository
└── content.xml
As you can see the plugin and feature folders are missing in target/repository.
This is my parent pom:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.lorem.ipsum.eclipse</groupId>
<version>1.0.1-SNAPSHOT</version>
<artifactId>lorem-ipsum-eclipse-parent</artifactId>
<packaging>pom</packaging>
<properties>
<tycho-version>2.2.0</tycho-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modules>
<module>lorem-ipsum-eclipse-feature</module> <!-- packaging: eclipse-feature -->
<module>lorem-ipsum-eclipse-plugin</module> <!-- packaging: eclipse-plugin -->
<module>lorem-ipsum-eclipse-update</module> <!-- packaging: eclipse-repository -->
</modules>
<repositories>
<repository>
<id>2020-12</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/2020-12</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-repository-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<includeAllDependencies>true</includeAllDependencies>
<createArtifactRepository>true</createArtifactRepository>
<compress>true</compress>
</configuration>
</plugin>
<!--Enable the replacement of the SNAPSHOT version in the final product configuration-->
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-packaging-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<phase>package</phase>
<id>package-feature</id>
<configuration>
<finalName>${project.artifactId}_${unqualifiedVersion}.${buildQualifier}</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
What am I doing wrong?
Thanks in advance.
UPDATE: As howlger requested here is update site's category.xml.
<?xml version="1.0" encoding="UTF-8"?>
<site>
<feature id="com.lorem.ipsum.eclipse.feature" version="0.0.0">
<category name="com.lorem.ipsum.eclipse.category"/>
</feature>
<category-def name="com.lorem.ipsum.eclipse.category" label="Lorem Ipsum">
<description>
Contains features for Lorem Ipsum plugin
</description>
</category-def>
</site>
By the way my file is named site.xml because if I named category.xml I have this error when i tried to run any maven goal:
$ mvn clean
...
[ERROR] Cannot resolve project dependencies:
[ERROR] Software being installed: lorem-ipsum-eclipse-update raw:1.0.1.'SNAPSHOT'/format(n[.n=0;[.n=0;[-S]]]):1.0.1-SNAPSHOT
[ERROR] Missing requirement: lorem-ipsum-eclipse-update raw:1.0.1.'SNAPSHOT'/format(n[.n=0;[.n=0;[-S]]]):1.0.1-SNAPSHOT requires 'org.eclipse.equinox.p2.iu; com.lorem.ipsum.eclipse.feature.feature.group 0.0.0' but it could not be found
[ERROR]
[ERROR] See https://wiki.eclipse.org/Tycho/Dependency_Resolution_Troubleshooting for help.
[ERROR] Cannot resolve dependencies of MavenProject: com.globant.augmented.coding.eclipse:lorem-ipsum-eclipse-update:1.0.1-SNAPSHOT # /home/me/workspaces/java/lorem-ipsum-eclipse-project/lorem-ipsum-eclipse-update/pom.xml: See log for details -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MavenExecutionException
I followed the instructions of the book Eclipse 4 Plug-in Development by Example Beginners Guide by Dr Alex Blewitt which uses an old version of tycho (0.18.0) and I have used 2.2.0. Maybe in this version they fixed the fact of renaming site to category since in the same book they mentioned that it was a meaningless change.
I quote:
Rename the site.xml file to category.xml . (This is an entirely
pointless change required by p2 since the files are identical in
format.)
According the the error message (... lorem-ipsum-eclipse-update ... Missing requirement: ... com.lorem.ipsum.eclipse.feature.feature.group ...) the update site category.xml refers a missing feature.
Make sure to use the same feature ID (<feature id="...") in the following two files:
<your-feature>/feature.xml
<your-update-site>/category.xml
See also the vogella tutorial Eclipse Tycho for building Eclipse Plug-ins and RCP applications: in category.xml the feature is referenced via the ID com.vogella.tycho.feature.
com.vogella.tycho.feature

Maven creates class files in wrong directory

I just started learning Maven. I have two java files and they are shown below
I compiled it successfully using 'mvn compile' and able to see the class files
However, I expect 'target/classes/src2/SecProg.class' instead of 'target/classes/SecProg.class'
Output
./target/classes/SecProg.class
./target/classes/src1/FirstProg.class
Please let me know what am I doing wrong
My source tree looks like below
[sathish#oc3855733574 java_tools]$ tree
.
├── pom.xml
├── pom.xml_org
├── src1
│   └── FirstProg.java
├── src2
│   └── SecProg.java
My POM.xml looks like below
<project 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>java_tools</groupId>
<artifactId>first_prog</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<build>
<sourceDirectory>.</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<includes>
<include>src2/*.java</include>
<include>src1/*.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>

How to configure npm to use maven folder structure and war deployment

I began my first pure front end project. I want to deploy it the java/maven. So i set up a normal war project:
│ package.json
│ pom.xml
│ tsconfig.json
│ typings.json
│
│
├───src
│ └───main
│ ├───resources
│ └───webapp
│ │ index.html
│ │
│ ├───app
│ │ app.component.ts
│ │ main.ts
│ │
│ ├───css
│ │ styles.css
│ │
│ └───WEB-INF
│ web.xml
│
My problem is how to set the path to index.html/the source relative to package. json? Since this is an angular/typescript project there is also some typescript specific stuff. but my hope is to set the "source" path once and for all in package json?!
I am also not sure if i want to deploy the stuff in "webapp" directly since there are Compiling steps. So any advice how to structure a pur front end project for maven/war deployment are welcome.
In order to integrate NPM with Maven, you could make use of frontend-maven-plugin which I think will be a great tool for your compiling steps.
So, in order to configure everything together this how your pom.xml should look like:
<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>group.id</groupId>
<artifactId>artifact-id</artifactId>
<version>2.0.14-SNAPSHOT</version>
<name>Artifact Name</name>
<packaging>war</packaging>
<!-- Plug-in definition -->
<build>
<plugins>
<!-- frontend-maven plug-in -->
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>0.0.29</version>
<configuration>
<nodeVersion>v5.10.1</nodeVersion>
<npmVersion>3.8.6</npmVersion>
<installDirectory>target</installDirectory>
<workingDirectory>${basedir}</workingDirectory>
</configuration>
<executions>
<!-- install node & npm -->
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<!--npm install -->
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<!-- npm run build -->
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<!-- Maven WAR plug-in -->
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
As you can see, first we define the usage of frontend-maven-plugin:
we use the most recent stable NodeJS version: v5.10.1;
the most recent version of NPM: 3.8.6;
since the plugin downloads and installs NodeJS and NPM, one needs to declare the installation directory (installDirectory). I've opted to store everything on Maven's target directory;
then it's necessary to define one's working directory (workingDirectory), which basically is the directory where our package.json will be. In your case, it will be at the same level as your pom.xml file, so we use ${basedir} for that;
following, it will be necessary to define the executions: the first two I believe that are quite straightforward; the last one simply assumes that, inside your package.json, there's a script target named build which will, for example, call the browserify command in order to build a bundle.js file:
"scripts": {
"build": "browserify src/main/webapp/app.js -o src/main/webapp/modules/bundle.js"
}
In your case, instead of the app.js, the package.json would interact with your typescript files.
Finally, one has the definition of the Maven WAR plugin. The only configuration made was the mention to the location where the web.xml is.
Notice that, by definition, Maven will package everything that's inside src/main/webapp directory. So, if there are any files (or folders) that you'd like to exclude, you should make use of the configuration parameter <packagingExcludes>:
<!-- Maven WAR plug-in -->
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<packagingExcludes>app/**</packagingExcludes>
</configuration>
</plugin>
The configuration above would exclude the folder app.
Again, this is a starting point. From here, you could play with Maven in order to custom build your application.

Nar dependency in multi-module maven project

I set up a multi module maven project, which is comprised of a module destined to build nar jni library, and a jar packaged module that is dependent on that library.
I am able to install the nar library to my local maven repository, but I fail to use it in dependent module.
For instance, I run mvn nar:nar-unpack and I get:
[INFO] ------------------------------------------------------------------------
[INFO] Building nar-dependent 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- nar-maven-plugin:3.2.0:nar-unpack (default-cli) # nar-dependent ---
[INFO] Unpacking 0 dependencies to /home/przemek/Documents/stimulant/nar-dependent/target/nar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
It seems that there are no nar dependencies, which is obviously not true.
Moreover, trying to execute the main method of the class that makes use of the jni library fails:
mvn exec:java -Dexec.mainClass=App
[INFO] --- exec-maven-plugin:1.4.0:java (default-cli) # nar-dependent ---
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.UnsatisfiedLinkError: no nar-library-1.0-SNAPSHOT in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at jnibook.NarSystem.loadLibrary(NarSystem.java:23)
at jnibook.HelloWorld.<clinit>(HelloWorld.java:10)
at App.main(App.java:9)
... 6 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
The structure of the project looks like this:
.
├── nar-dependent
│   ├── pom.xml
│   └── src
│   └── main
│   └── java
│   └── App.java
├── nar-library
│   ├── pom.xml
│   └── src
│   ├── main
│   │   ├── c
│   │   │   └── HelloWorld.c
│   │   ├── include
│   │   ├── java
│   │   │   └── jnibook
│   │   │   └── HelloWorld.java
│   │   └── resources
│   └── test
│   └── java
├── parent
│   └── pom.xml
Here is the parent 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sidec</groupId>
<artifactId>stimulant</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>../nar-library</module>
<module>../nar-dependent</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
The nar-library module 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>
<parent>
<groupId>sidec</groupId>
<artifactId>stimulant</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>nar-library</artifactId>
<packaging>nar</packaging>
<name>nar-library</name>
<properties>
<skipTests>true</skipTests>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.github.maven-nar</groupId>
<artifactId>nar-maven-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<cpp>
<exceptions>false</exceptions>
</cpp>
<libraries>
<library>
<type>jni</type>
<linkCPP>false</linkCPP>
<narSystemPackage>jnibook</narSystemPackage>
</library>
</libraries>
<javah>
<includes>
<include></include>
</includes>
</javah>
</configuration>
</plugin>
</plugins>
</build>
</project>
The nar-dependent 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>
<parent>
<groupId>sidec</groupId>
<artifactId>stimulant</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>nar-dependent</artifactId>
<packaging>jar</packaging>
<name>nar-dependent</name>
<build>
<plugins>
<plugin>
<groupId>com.github.maven-nar</groupId>
<artifactId>nar-maven-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<!--<executions>-->
<!--<execution>-->
<!--<id>nar-download</id>-->
<!--<goals>-->
<!--<goal>nar-download</goal>-->
<!--</goals>-->
<!--</execution>-->
<!--</executions>-->
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>sidec</groupId>
<artifactId>nar-library</artifactId>
<version>1.0-SNAPSHOT</version>
<type>nar</type>
</dependency>
</dependencies>
</project>
Finally, as a proof that it is really the HelloWorld project, a library class:
package jnibook;
public class HelloWorld {
public native void print();
static {
NarSystem.loadLibrary();
}
}
and a client app:
import jnibook.HelloWorld;
public class App {
public static void main(String ... args){
(new HelloWorld()).print();
}
}
I referenced https://maven-nar.github.io/examples.html with no success.
I have no idea what is going wrong.
Any ideas? Here is zip with project.
This might be an outdated question, but I'll answer all the same :
When running the java JNI app, it must be told where to find the .so library holding the relevant native C code used by JNI.
For example, if you closed your app in the executable jar app.jar :
java -Djava.library.path=[path to the .so native C library] -jar app.jar
PS - you can see that the JVM can't find the native C library thanks to the exception : java.lang.UnsatisfiedLinkError: no nar-library-1.0-SNAPSHOT in java.library.path
I have tried my own variant of your example with version 3.6.0 of the plugin. With that version, I at least get
Unpacking 1 dependencies to /home/karsten/svn/hellotest/target/nar
and the .so gets unpacked when I run mvn nar:nar-unpack in the dependent module.
But the only way I have found to make mvn nar:nar-integration-test work in the dependent module, is by writing
LD_LIBRARY_PATH=target/nar/hellojni-0.0-amd64-Linux-gpp-jni/lib/amd64-Linux-gpp/jni mvn nar:nar-integration-test
I tried several ways of specifying java.library.path, but with no success.

Resources