Executable jar with javaFX and maven (ikonli project) [duplicate] - java

I'm trying to create a JFX11 self-containing jar using maven dependencies. From the research I've done, it seems the best way to do this is through the maven shade plugin. However, When I run it, I get the this error:
Error: JavaFX runtime components are missing, and are required to run this application
I don't understand why this is happening. What am I messing up? Is there a better way to do this? I've also tried the maven assembly plugin with the same message.
pom file for reference
<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>Application</groupId>
<artifactId>Main</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpaceRunner</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>10</release>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>Application.Main</mainClass>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>
Application.Main
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>Application.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

UPDATE 10/2021
Since JavaFX 16 a warning is displayed when JavaFX doesn't run on the module path, which is the case of an uber/fat jar:
$ java -jar myFatJar-1.0-SNAPSHOT.jar
Oct 02, 2021 1:45:21 PM com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module #14c24f4c'
Also, you get a warning from the shade plugin itself:
[WARNING] Discovered module-info.class. Shading will break its strong encapsulation.
While these warnings can be initially ignored, there is a reason for them.
As explained in this CSR:
JavaFX is built and distributed as a set of named modules, each in its own modular jar file, and the JavaFX runtime expects its classes to be loaded from a set of named javafx.* modules, and does not support loading those modules from the classpath.
And:
when the JavaFX classes are loaded from the classpath, it breaks encapsulation, since we no longer get the benefit of the java module system.
Therefore, even this widely accepted answer explains how can an uber/fat jar can be created on Maven projects, its use is discouraged, and other modern alternatives to distribute your application, like jlink, jpackage or native-image, should be used.
ORIGINAL ANSWER
This answer explains why a fat/uber jar fails on JavaFX 11. In short:
This error comes from sun.launcher.LauncherHelper in the java.base module. The reason for this is that the Main app extends Application and has a main method. If that is the case, the LauncherHelper will check for the javafx.graphics module to be present as a named module. If that module is not present, the launch is aborted.
And already proposes a fix for Gradle.
For Maven the solution is exactly the same: provide a new main class that doesn't extend from Application.
You will have new class in your application package (bad name):
// NewMain.java
public class NewMain {
public static void main(String[] args) {
Main.main(args);
}
}
And your existing Main class, as is:
//Main.java
public class Main extends Application {
#Override
public void start(Stage stage) {
...
}
public static void main(String[] args) {
launch(args);
}
}
Now you need to modify your pom and set your main class for the different plugins:
<mainClass>application.NewMain</mainClass>
Platform-specific Fat jar
Finally, with the shade plugin you are going to produce a fat jar, on your machine.
This means that, so far, your JavaFX dependencies are using a unique classifier. If for instance you are on Windows, Maven will be using internally the win classifier. This has the effect of including only the native libraries for Windows.
So you are using:
org.openjfx:javafx-controls:11
org.openjfx:javafx-controls:11:win
org.openjfx:javafx-graphics:11
org.openjfx:javafx-graphics:11:win <-- this contains the native dlls for Windows
org.openjfx:javafx-base:11
org.openjfx:javafx-base:11:win
Now, if you produce the fat jar, you will bundle all those dependencies (and those other regular third party dependencies from your project), and you will be able to run your project as:
java -jar myFatJar-1.0-SNAPSHOT.jar
While this is very nice, if you want to distribute you jar, be aware that this jar is not cross-platform, and it will work only on your platform, in this case Windows.
Cross-Platform Fat Jar
There is a solution to generate a cross-platform jar that you can distribute: include the rest of the native libraries of the other platforms.
This can be easily done, as you just need to include the graphics module dependencies for the three platforms:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics </artifactId>
<version>11</version>
<classifier>win</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics </artifactId>
<version>11</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics </artifactId>
<version>11</version>
<classifier>mac</classifier>
</dependency>
</dependencies>
Size
There is a main issue with this approach: the size. As you can see in this other answer, if you use the WebView control, you will be bundling around 220 MB due to the WebKit native libraries.

Related

Package JavaFX into an executable fat JAR with Maven not generating valid classpath [duplicate]

I'm trying to create a JFX11 self-containing jar using maven dependencies. From the research I've done, it seems the best way to do this is through the maven shade plugin. However, When I run it, I get the this error:
Error: JavaFX runtime components are missing, and are required to run this application
I don't understand why this is happening. What am I messing up? Is there a better way to do this? I've also tried the maven assembly plugin with the same message.
pom file for reference
<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>Application</groupId>
<artifactId>Main</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpaceRunner</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>10</release>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>Application.Main</mainClass>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>
Application.Main
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>Application.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
UPDATE 10/2021
Since JavaFX 16 a warning is displayed when JavaFX doesn't run on the module path, which is the case of an uber/fat jar:
$ java -jar myFatJar-1.0-SNAPSHOT.jar
Oct 02, 2021 1:45:21 PM com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module #14c24f4c'
Also, you get a warning from the shade plugin itself:
[WARNING] Discovered module-info.class. Shading will break its strong encapsulation.
While these warnings can be initially ignored, there is a reason for them.
As explained in this CSR:
JavaFX is built and distributed as a set of named modules, each in its own modular jar file, and the JavaFX runtime expects its classes to be loaded from a set of named javafx.* modules, and does not support loading those modules from the classpath.
And:
when the JavaFX classes are loaded from the classpath, it breaks encapsulation, since we no longer get the benefit of the java module system.
Therefore, even this widely accepted answer explains how can an uber/fat jar can be created on Maven projects, its use is discouraged, and other modern alternatives to distribute your application, like jlink, jpackage or native-image, should be used.
ORIGINAL ANSWER
This answer explains why a fat/uber jar fails on JavaFX 11. In short:
This error comes from sun.launcher.LauncherHelper in the java.base module. The reason for this is that the Main app extends Application and has a main method. If that is the case, the LauncherHelper will check for the javafx.graphics module to be present as a named module. If that module is not present, the launch is aborted.
And already proposes a fix for Gradle.
For Maven the solution is exactly the same: provide a new main class that doesn't extend from Application.
You will have new class in your application package (bad name):
// NewMain.java
public class NewMain {
public static void main(String[] args) {
Main.main(args);
}
}
And your existing Main class, as is:
//Main.java
public class Main extends Application {
#Override
public void start(Stage stage) {
...
}
public static void main(String[] args) {
launch(args);
}
}
Now you need to modify your pom and set your main class for the different plugins:
<mainClass>application.NewMain</mainClass>
Platform-specific Fat jar
Finally, with the shade plugin you are going to produce a fat jar, on your machine.
This means that, so far, your JavaFX dependencies are using a unique classifier. If for instance you are on Windows, Maven will be using internally the win classifier. This has the effect of including only the native libraries for Windows.
So you are using:
org.openjfx:javafx-controls:11
org.openjfx:javafx-controls:11:win
org.openjfx:javafx-graphics:11
org.openjfx:javafx-graphics:11:win <-- this contains the native dlls for Windows
org.openjfx:javafx-base:11
org.openjfx:javafx-base:11:win
Now, if you produce the fat jar, you will bundle all those dependencies (and those other regular third party dependencies from your project), and you will be able to run your project as:
java -jar myFatJar-1.0-SNAPSHOT.jar
While this is very nice, if you want to distribute you jar, be aware that this jar is not cross-platform, and it will work only on your platform, in this case Windows.
Cross-Platform Fat Jar
There is a solution to generate a cross-platform jar that you can distribute: include the rest of the native libraries of the other platforms.
This can be easily done, as you just need to include the graphics module dependencies for the three platforms:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics </artifactId>
<version>11</version>
<classifier>win</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics </artifactId>
<version>11</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics </artifactId>
<version>11</version>
<classifier>mac</classifier>
</dependency>
</dependencies>
Size
There is a main issue with this approach: the size. As you can see in this other answer, if you use the WebView control, you will be bundling around 220 MB due to the WebKit native libraries.

Multi-module JavaFX maven project packaging issue

This is an attempt to create a multi-module JavaFX application with maven.
Given the following structure of the project:
project
| pom1.xml
|_____ Word Generator (Folder)
| pom2.xml
|_____logic (folder)
| WordGenerator
|_____UI (folder)
| pom3.xml
|_____marty
| App
| PrimaryController
| SecondaryController
We have the following structure of the pom files in order of the scheme above:
pom1.xml
<?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>org.games.marty</groupId>
<artifactId>words</artifactId>
<packaging>pom</packaging>
<version>0.1</version>
<modules>
<module>UI</module>
<module>Word Generator</module>
</modules>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
pom2.xml
<?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">
<parent>
<artifactId>words</artifactId>
<groupId>org.games.marty</groupId>
<version>0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>word.generator</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>org.games.marty.logic.WordGenerator</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
pom3.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>
<artifactId>UI</artifactId>
<version>0.1</version>
<parent>
<artifactId>words</artifactId>
<groupId>org.games.marty</groupId>
<version>0.1</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>16</version>
</dependency>
<dependency>
<groupId>org.games.marty</groupId>
<artifactId>word.generator</artifactId>
<version>0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>16</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<!-- Default configuration for running -->
<!-- Usage: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>org.games.marty.App</mainClass>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>org.games.marty.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
The way we have attempted to build the application in order for the UI to have access to the WordGenerator logic is to maven package the result from the pom1.xml directive
We get the above error as mentioned earlier:
Error: Could not find or load main class org.games.marty.App
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application
As far as my understanding goes, the JavaFX dependencies are installed throught maven and should be available but they are missing?
Packaging via mvn package using the maven-jar-plugin is not enough
mvn package, by default, is just going to package the jar for your application code, it isn't going to include all of the dependant library code (which is why the dependent code cannot be found when you attempt to run your application).
You could package your application code and dependant libraries using an assembly, as detailed in How can I create an executable JAR with dependencies using Maven?, though that approach is not the only one to solve your problem.
You need to build some kind of runtime image
There are numerous options for building runtime images and I don't know your requirements, so I can't recommend what you should do instead. Example options are:
A zip/tar of your application plus libraries in a separate directory.
The creation of a single jar that includes all dependant code.
Either of solutions 1 or 2, plus the inclusion of a packaged JRE.
A runtime image with your code and libraries which also uses just the custom runtime portions of the JRE and JavaFX modules you need (using jlink).
A native installer for either 3 or 4 (using jpackage + a native installer creation tool, e.g. WIX, RPM, DEB installer creators).
The last method (native installer), is the packaging, distribution, and installation method I would recommend for most non-trivial applications.
You need to research how to do this
To get your solution, you will need to do your own research, and, once you have chosen an approach and toolset, you could create a new question regarding the implementation of that approach, if you continue to have difficulties.
Related resources
How can I create an executable JAR with dependencies using Maven?
openjfx Runtime images documentation
maven shade plugin
Maven Shade JavaFX runtime components are missing
openjfx JavaFX maven plugin
badass runtime plugin
badass jlink plugin
jlink guide
jpackage script
JEP 392: packaging tool
Warning for shaded jars
If you bundle all JavaFX code into a single jar using the maven shade plugin, you will get a warning like the following when you run your application from Java 16+:
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module #28c71909'
This indicates that such a configuration is not supported, and may (and probably will) break in future and perhaps current JavaFX platform revisions. Thus, shaded jars that include JavaFX platform code are not recommended by me, even though such jars might currently work for your deployments.
JavaFX 11+ is built to be used as a set of modules. Configurations are not supported if they do not run the JavaFX platform off of the module path but instead run the platform code off of the classpath (as a shaded jar would).

Maven-compiler-plugin throws wanted compile errors but deny the compile progress

A few days ago i started with Maven. I have to put only a few of my dependencies in my generated jar file. This is needed because my code is only a plugin (Minecraft Plugin) executed by an api (Minecraft Server Software Spigot). Now the Problem is, that my Plugin depends on an other api (json-simple-1.1).
The last days i tried to edit the maven shade plugin to get the wished result. I failed, and now i did it in this way:
maven include the json-simple-1.1 api, i needing for my plugin
eclipse include the spigot api (Minecraft server software), which will executing my plugin
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>de.falco.essentialsXXX</groupId>
<artifactId>EssentialsXXX-bungeecord</artifactId>
<version>0.0.1-SNAPSHOT</version>
<description>Basic class for every Plugin
</description>
<build>
<sourceDirectory>src</sourceDirectory>
<!-- COMPILE -->
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- BUILD -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-json</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</project>
When i now execute 'mvn clean install' (in the right directory) i get many many errors. That make completely sense. Maven can not find types or classes and everything else comeing from the spigot-api.
My Problem is, that this isnt a real error because when the spigot-api execute my plugin i have the classes and types i need. Maven dont know that and dont compile my Programm :(
At this point a have no idea what to do. I read so many articles but i couldnt find a solution. Every article say ohhh an error here try to use tags and the right api values. That isnt what i need.
I need something like a "bypass" attribute for the compiler so the compiler know "yes this is an error but the coder knows what he does"
If you need something for compilation, it needs to be a Maven dependency.
So take that artifact, install it in your local repository and add it as dependency.
Then your compilation process will probably work.
Note that using a dependency does not mean that you have to include the dependency into the resulting jar.

How to add a local JNI jar in a pom file properly?

I have a SpringbootApplication that provides a REST API, let's call it fetchPrediction.
This fetchPrediction API uses some classes defined inside a JAR file, which is a JNI.
My application compiles and starts, however, if I call the fetchPrediction API it fails.
When I do jar -xvf on the created jar after mvn clean install, I do not see the classes that should be picked up by including the jar dependency.
Also, when I try to run the Jar file I see ClassNotDefinedException for the classes inside the JAR.
How can I do this properly?
Currently I am importing the JAR dependency as follows:
<dependency>
<groupId>jarcom.jarlib</groupId>
<artifactId>jarname</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/jarname.jar</systemPath>
</dependency>
In an spring boot application you usually do not have JNI parts. Furthermore the spring-boot-maven-plugin by default does not include dependencies with <scope>system</scope> that's the reason why you do not see the jar file in the resulting jar.
You have to have to configure the spring-boot-maven-plugin and set the includeSystemScope to true as described in the docs for the plugin.
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.4.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</execution>
</executions>
...
</plugin>
...
</plugins>
...
</build>
...
</project>

How to include opencv in an intellij sub module (maven)

I'm using IntelliJ IDE with maven. I have a project (main module) with a parent pom, that includes 2 sub modules, each with their own pom.
<!-- main pom module part -->
<packaging>pom</packaging>
<modules>
<module>ModuleA</module>
<module>ModuleB</module>
</modules>
<!-- example for sub module pom -->
<parent>
<artifactId>main-module</artifactId>
<groupId>my.main.module</groupId>
<version>0.5.0</version>
</parent>
Image ModuleA includes the OpenCV Java wrapper and ModuleB is an executable java program (having the main class) using ModuleA.
The compiling works fine, but when I run ModuleB with having set the library path in the launcher, I'll get the following error for ModuleA:
java.lang.NoClassDefFoundError: org/opencv/core/Core
Any suggestions how to fix this?
Ok, I found a solution my self. The problem was, that the opencv java wrapper was included with a system path. Now I use the maven install plugin within the validate live cycle step instead.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>org.opencv</groupId>
<artifactId>opencv</artifactId>
<version>3.3.0</version>
<packaging>jar</packaging>
<file>${project.basedir}/../lib/opencv/opencv-330.jar</file>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Works fine for me, but was not the way I wanted it to be... The system-path type dependency seems to be buggy in maven.
Try to add the following dependency to your ModuleA:
<dependency>
<groupId>nu.pattern</groupId>
<artifactId>opencv</artifactId>
<version>2.4.9-7</version>
</dependency>

Categories

Resources