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

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

Related

Merge parent and child pom during assembly

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.

docker multistage spring boot build pom + inner dependencies

I am trying to make a spring boot multistage build, I have a spring boot project X that contains two util projects as dependencies in other folder, when I try to make the build it fails because this dependencies does not exist.
I tried using multi module maven project but this utils will be used in other projects.
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 08:23 min
[INFO] Finished at: 2019-09-27T01:29:09Z
[INFO] Final Memory: 44M/228M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project projectX: Could not resolve dependencies for project com.demo:projectX:jar:0.1: The following artifacts could not be resolved: com.util:util1:jar:0.1, com.util:util2:jar:0.1: Could not find artifact com.util:util1:jar:0.1 in spring-milestones (https://repo.spring.io/milestone) -> [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/DependencyResolutionException
ERROR: Service 'projectX' failed to build: The command '/bin/sh -c ./mvnw dependency:go-offline -B' returned a non-zero code: 1
(edit) Here is dockerfile for multistage maven build
(edit) the docker build command and context path is from parent folder
FROM openjdk:8-jdk-alpine as build-util1
WORKDIR /util1
COPY ./components/util1/mvnw .
COPY ./components/util1/.mvn .mvn
COPY ./components/util1/pom.xml .
COPY ./components/util1/src src
RUN ./mvnw clean install
FROM openjdk:8-jdk-alpine as build-util2
WORKDIR /util
COPY --from=build-util1 /root/.m2 /root/.m2
COPY ./components/util2/mvnw .
COPY ./components/util2/.mvn .mvn
COPY ./components/util2/pom.xml .
COPY ./components/util2/src src
RUN ./mvnw clean install
FROM openjdk:8-jdk-alpine as build
WORKDIR /app
COPY --from=build-util2 /root/.m2 /root/.m2
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
RUN ./mvnw dependency:go-offline -B
COPY src src
RUN ./mvnw -X package -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
FROM openjdk:8-jre-alpine
ARG DEPENDENCY=/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.demo.projectx.ProjectX"]
Here is the pom.xml for the project X
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>projectX</artifactId>
<version>0.1</version>
<name>projectX</name>
<description>projectX</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<docker.image.prefix>jxssw</docker.image.prefix>
<docker.image.name>${project.artifactId}</docker.image.name>
<docker.image.tag>${project.version}</docker.image.tag>
</properties>
<dependencies>
<!-- utils -->
<dependency>
<groupId>com.util</groupId>
<artifactId>util1</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>com.util</groupId>
<artifactId>util2</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Dockerfile Maven -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.10</version>
<configuration>
<googleContainerRegistryEnabled>false</googleContainerRegistryEnabled>
<repository>${docker.image.prefix}/${docker.image.name}</repository>
<tag>${project.version}</tag>
</configuration>
<executions>
<execution>
<id>build</id>
<phase>clean</phase>
<goals>
<goal>build</goal>
<goal>tag</goal>
</goals>
</execution>
<execution>
<id>push</id>
<phase>deploy</phase>
<goals>
<goal>push</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Dockerfile Maven -->
</plugins>
<finalName> ${project.artifactId}</finalName>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
(edit) add the folder structure:
.(parent)
├── projects
| └── projectX
│ ├── pom.xml
│ ├── Dockerfile
│ └── src
│ └── main
├── components
| └── util1
│ ├── pom.xml
│ └── src
│ └── main
| └── util2
│ ├── pom.xml
│ └── src
│ └── main

Spring boot test multi module maven application

I have a multi-module maven application which uses Spring boot:
- spring boot parent
- myproject parent (both parent and module pom)
- module1
- module2
- module-it (integration tests)
In my module-it, I add the other modules as dependencies.
When I build my project with maven, I get "Build Success":
mvn clean install
So far so good.
Yet I would like each of my modules to be an executable jar at the end of the build. With the above settings, the manifest is not defined and the jar is not executable.
To fix this issue, I've added the following in my module1 and module2 pom files:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
With this setting, my jar file is executable but I cannot build anymore. Classes that I use in my module-it are not found.
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project module-it: Compilation failure: Compilation failure:
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/greeting/GreetingControllerIT.java:[20,17] cannot find symbol
[ERROR] symbol: class GreetingController
[ERROR] location: class com.mycompany.testing.greeting.GreetingControllerIT
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/hello/HelloControllerIT.java:[20,17] cannot find symbol
[ERROR] symbol: class HelloController
[ERROR] location: class com.mycompany.testing.hello.HelloControllerIT
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/greeting/GreetingControllerIT.java:[16,27] cannot find symbol
[ERROR] symbol: class GreetingController
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/hello/HelloControllerIT.java:[16,27] cannot find symbol
[ERROR] symbol: class HelloController
Can you please help me understand why spring-boot-maven-plugin makes my build fail and how I can solve the issue?
Thanks in advance for your help.
To solve this issue, we can add a classifier as described in the documentation custom repackage classifier
The plugin then becomes:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
Also you could set repackage goal parameter attach to false:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
At least for the spring-boot-starter-parent:2.6.0 pom the configuration for the spring-boot-maven-plugin contains an <id>repackage</id> for the execution of the repackage goal
So I had to add the line <id>repackage</id> too.
Full configuration:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
Late answer to an old question but i've just been working on this for the past hours. Even though the previous answers were helpfull they don't explain why this problem is happening.
For others that may comes accross this issue here is a detailed explnation why it's not working
In a Nutshell
Usualy Maven package your application as a regular .jar with all compiled class being in a well known location in the .jar file.
So it's pretty straighforward for a compiler to import the .jar as a library and to load the available .class.
But the spring-boot-maven-plugin is actually modifying the .jar structure to leverage spring-boot logic when you start the .jar application.
In short, the .class are not available to be imported as a "library" from the resulting .jar, because the spring class have took the well known location for itself.
Detailed explanation
Let's explore the problem with an example
Project structure
Let's imagine a project with multiple maven modules like so
my-app/ -- The parent project
├─ pom.xml
├─ application/
│ ├─ pom.xml
├─ integration-tests/
│ ├─ pom.xml
Given the following pom.xml files:
my-app/pom.xml:
<project [...]>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/>
</parent>
<groupId>com.me</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>application</module>
<module>integration-tests</module>
</modules>
</project>
my-app/application/pom.xml:
<project [...]>
<parent>
<groupId>com.me</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>application</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
my-app/integration-tests/pom.xml:
<project [...]>
<parent>
<groupId>com.me</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>integration-tests</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.me</groupId>
<artifactId>application</artifactId>
</dependency>
</dependencies>
</project>
Why is it not building
Let's try to package our app
/my-app$ mvn package
Of course it will miserably fail with an error cannot find symbol, but why is it so?
Let's take a look at our architecture after the failed build:
my-app/ -- The parent project
├─ pom.xml
├─ application/
│ ├─ pom.xml
│ ├─ target/
│ │ ├─ application-1.0.0-SNAPSHOT.jar
│ │ ├─ application-1.0.0-SNAPSHOT.jar.original
├─ integration-tests/
│ ├─ pom.xml
│ ├─ target/
The spring-boot-maven-plugin has done several things to the application module output:
renamed the compiled application-1.0.0-SNAPSHOT.jar to application-1.0.0-SNAPSHOT.jar.original
created it's own .jar with the name of application-1.0.0-SNAPSHOT.jar
Let's explore the structure of the application-1.0.0-SNAPSHOT.jar:
BOOT-INF/
├─ classes/
│ ├─ com/
│ │ ├─ me/ -- The compiled .class of your project reside here
META-INF/
org/
├─ springframework/
│ ├─ boot/ -- contains the spring boot loader classes
As you can see the .class files at the root of your .jar are the spring boot loader classes, not our own .class that are relegated to the BOOT-INF/classes/ folder.
This is not conventional, and when the .jar is imported as a dependency it won't search here for class to import.
Because of that, when maven try to package the integration-tests module, it fails because the class present in the application-1.0.0-SNAPSHOT.jar are actually a bunch of spring class instead of the one you are trying to import from application module.
If you were to look at the structure of the application-1.0.0-SNAPSHOT.jar.origial it would be something like so:
META-INF/
com/
├─ me/ -- contains the spring boot loader classes
Solution
Getting rid of spring-boot-maven-plugin is not an acceptable solution; Of course your project will be buildable, but the resulting .jar won't be a spring boot standalone running .jar.
Instead you can instruct the spring-boot-maven-plugin to not replace the original jar and to build to spring boot jar with another name.
To do so you'll need to configure the spring-boot-maven-plugin in the application module:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Now when you build your project you'll have something like that:
my-app/ -- The parent project
├─ pom.xml
├─ application/
│ ├─ pom.xml
│ ├─ target/
│ │ ├─ application-1.0.0-SNAPSHOT.jar -- the original untouched .jar
│ │ ├─ application-1.0.0-SNAPSHOT-exec.jar -- the spring boot executable .jar
├─ integration-tests/
│ ├─ pom.xml
│ ├─ target/
│ │ ├─ integration-tests-1.0.0-SNAPSHOT.jar

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>

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