Java11 / JavaFX and Maven will not run outside of NetBeans IDE 9 - maven

As per JavaFX deployment library not found in active JDK
I used José Pereda Maven approach and it works well in NetBeans but as soon as I try and run it outside with "java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar" I get the following error
"Error: JavaFX runtime components are missing, and are required to run this application"
The "md.mavenproject1.MainApp" is just a temp name while I try and figure this out.
My pom file looks like:
<?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>md</groupId>
<artifactId>mavenproject1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mavenproject1</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mainClass>md.mavenproject1.MainApp</mainClass>
</properties>
<organization>
<!-- Used as the 'Vendor' for JNLP generation -->
<name>Your Organisation</name>
</organization>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11-ea+25</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11-ea+25</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>11</release>
</configuration>
<dependencies>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>6.1.1</version>
<!-- Use newer version of ASM -->
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>md.mavenproject1.MainApp</mainClass>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>md.mavenproject1.MainApp</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>
And my nbactions.xml file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action>
<actionName>run</actionName>
<goals>
<goal>clean</goal>
<goal>package</goal>
<goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:java</goal>
</goals>
<properties>
<runfx.args>-jar "${project.build.directory}/${project.build.finalName}.jar"</runfx.args>
</properties>
</action>
<action>
<actionName>debug</actionName>
<goals>
<goal>clean</goal>
<goal>package</goal>
<goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:java</goal>
</goals>
<properties>
<runfx.args>-Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -Dglass.disableGrab=true -jar "${project.build.directory}/${project.build.finalName}.jar"</runfx.args>
<jpda.listen>true</jpda.listen>
</properties>
</action>
</actions>
Any help you can give me will be of great help as I am thinking of switching my highschool programming kids from ant to maven with the change in JavaFX but they will want to be able to take there programs home to use. I am running OpenJDK 11 on my system.
**edit **
I changed the line to run the program to:
java --module-path c:\javafx-sdk-11\lib --add-modules javafx.controls -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar
and now I get:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module #0x11a24f71) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module #0x11a24f71
at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
at md.test33.MainApp.start(MainApp.java:15)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
... 1 more
Exception running application md.mavenproject1.MainApp
I though with using maven's dependencies that I wouldn't need to use the local jdk. Any help anyone could give would be really helpful. If I take out the dependencies and use Oracle java 10 jdk the program and run outside of netbeans but with java 11 it only runs inside. Please help.
** EDIT **
By editing the pom file and removing:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>md.mavenproject1.MainApp</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
and instead using:
<!-- Used to make dependencys needed to run the program -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<!-- makes the JAR file to run the program outside -->
<plugin>
<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>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
I was now able to change the start up line to use the attached JavaFX lib that I added instead of having to use the SDK that I downloaded.
java --module-path lib --add-modules javafx.controls --add-exports=javafx.graphics/com.sun.javafx.util=ALL-UNNAMED --add-exports=javafx.base/com.sun.javafx.reflect=ALL-UNNAMED --add-exports=javafx.base/com.sun.javafx.beans=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.glass.utils=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED -jar mavenproject1-1.0-SNAPSHOT.jar
I would like to make it include the jre instead of using the local one. If anyone has any idea how it would be great.

One way to fix that would be to append the following args to the command line
--add-exports=javafx.graphics/com.sun.javafx.util=ALL-UNNAMED

I've got similar issue when doing default hello world javafx project in the IntelliJ IDEA with openjdk 11 and openjfx 11. The work around is to use offered CLI in the project configuration.
But in this case the solution is kind of hack instead of proper configuration fix.
My problem was that I hadn't any module-info.java to initialize proper java platform module. Therefore the IntelliJ module is actually unnamed module. After create proper module descriptor the project is not unnamed platform module any more.
Next issue what I got is related to using external java platform module as a jar file (openjfx libs to be specific). This need to be solved by adding libraries in the project structure settings.
And then it will work without any additional CLI arguments.

Related

No error in netbeans ide but java.lang.ClassNotFoundException: org.netbeans.lib.awtextra.AbsoluteLayout ERROR when java -jar jarfilename.jar

the maven app is running with no error on netbeans ide and the clean and build are running also without errors , the dependencies i didnt mention are :(mongodb,mongodb driver,mysql,itext) i tried launch4j , the .exe file didnt open.
this is the POM file :
<?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>com.mycompany</groupId>
<artifactId>billing-system</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<repositories>
<repository>
<id>unknown-jars-temp-repo</id>
<name>A temporary repository created by NetBeans for libraries and jars it could not identify. Please replace the dependencies in this repository with correct ones and delete this repository.</name>
<url>file:${project.basedir}/lib</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.netbeans.external</groupId>
<artifactId>AbsoluteLayout</artifactId>
<version>RELEASE120</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<itext.version>7.1.13</itext.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>login</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
i tried creating a awtextra folder in lib/ and copy absolutelayout folder in it from external/ and it did not work .and this the command line error :
OneDrive\Desktop\billing-system\target>java -jar billing-system-1.0-SNAPSHOT.jar
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/netbeans/lib/awtextra/AbsoluteLayout
at login.initComponents(login.java:41)
at login.<init>(login.java:21)
Problem solved
1.installed maven
2.added configuration to java JAVA_HOME
3.added configuration to maven MAVEN_HOME
4.added plugin with goals to pom file
5.added built with dependencier to jar file
6.used launch4j for an exe file
my pom file :
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>login</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>login</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>login</mainClass>
</configuration>
</plugin>
</plugins>
<defaultGoal>install</defaultGoal>
<!-- Source directory configuration -->
<sourceDirectory>src</sourceDirectory>
</build>

Why do I get "Exception in thread "main" java.lang.NoClassDefFoundError: org/openqa/selenium/WebDriver"?

I tried some of the advices given on other similar questions here, but failed to overcome the problem.
I am getting this error when trying to execute the jar by:
java -jar AutoHotRouter-1.0.jar
Given the following pom.xml, what am I missing here??
<?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>com.ttt</groupId>
<artifactId>AutoHotRouter</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>AutoHotRouter</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>2.53.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>2.53.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
First I added:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>com.ttt.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
I built the jar using
mvn clean install
then on
java -jar AutoHotRouter.jar
I got:
Exception in thread "main" java.lang.NoClassDefFoundError:
org/openqa/selenium/WebDriver
Then I removed the previous plugins and added firstly maven-assembly-plugin and because it didn't work for me, I replaced it with maven-shade-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.ttt.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer implementation=
"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.ttt.App</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
after
mvn clean install
and then
java -jar AutoHotRouter-1.0.jar
I get:
no main manifest attribute
I also tried
mvn clean compile assembly:single
with
maven-assembly-plugin.
Then I got:
Error reading assemblies: No assembly descriptors found.
Thanks!
This is just an assumption since the pom looks good so far. The part that's a bit suspicious is the jar plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.1</version>
<configuration>
...
It looks like you later on try to execute the created jar file with java -jar? In that case all the dependencies you define in the pom will be missing. Either use the dependency-plugin to collect the dependency jar files and use the classpath option when running the jar or use the shade-plugin to create an uber-jar that will contain your classes as well as the dependencies.
Using your pom allowed me to start Chrome, so the dependencies look good. So I think the way you start it causes that exception.
Update: since you use this setup to automate chrome, the shade plugin seems the best way to go. I am able to start chrome with this pom and main class in src/main/java
<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.example</groupId>
<artifactId>HotRouter</artifactId>
<version>1.0-SNAPSHOT</version>
<name>HotRouter</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.example.StartMain</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Main-Class
package org.example;
import org.openqa.selenium.chrome.ChromeDriver;
public class StartMain {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:/Program Files/Google/Chrome/Application/chrome.exe");
ChromeDriver driver = new ChromeDriver();
}
}
Then mvn package and java -jar ./target/HotRouter-1.0-SNAPSHOT.jar opens chrome. Your config is almost the same (I think only the phase config for the shade plugin is missing)
Its important to have the shade plugin within the <plugins> section of the pom, as it is not part of the default jar life-cycle. The <pluginManagement> section is just there to configure defaults for versions and configuration. See pom reference. So additional plugins will not be automatically enabled if only in that section.

Can I use Maven to generate a Jar that i can run my different Selenium TestNG tests using different testng xmls

I can use Maven to generate a directory containing my tests and dependencies and run them from the command line using "java -cp" . But I cannot get this to work in a single jar, without recreating a testng main and needing to pass testng xmls in and such. Thinking this is a simple thing being overlooked.
fundamentally I believe this may be a question of, can you create a jar that runs a main in an included package dependency? I may not be asking or stating correctly, if so, some help with that would also be appreciated.
precon, Maven 3.5.4 and Java 1.8 installed
I HAVE been able to "copy dependencies" and run the following usual TestNG command line:
java -cp %CD%\target\*; org.testng.TestNG TestTest.xml
but this is not as nice as just getting everything into one jar.
If possible, I don't want to have to recreate the TestNG main and further pass xmls etc. which I have done. I want to just use TestNG as is and package it with my tests in a single jar, and run like this:
java -jar %CD%\target\myproj-0.0.1-jar-with-dependencies.jar TestTest.xml
from My POM file pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<skipTests>true</skipTests>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0-beta3</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<!-- Source directory configuration -->
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>org.testng.TestNG</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- // Following plugin executes the testng tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14.1</version>
<configuration>
<!-- // Suite testng xml file to consider for test execution -->
<suiteXmlFiles>
<suiteXmlFile>testtest.xml</suiteXmlFile>
</suiteXmlFiles>
<skipTests>${skipTests}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
my testNG xml TestTest.xml
<groups>
<run>
<include name="basic"/>
</run>
</groups>
<classes>
<class name="myproj.TestTest"/>
</classes>
my tests in TestTest.java
package myproj;
import org.testng.annotations.Test;
public class TestTest{
#Test(groups = { "basic" })
public void Test05BasicPASS() {
System.out.println("This is test 5, Basic Pass");
}
}
directory structure:
-testproj
pom.xml
TestTest.xml
-src
-myproj
TestTest.java
Jars get output to:
-testproj
-target
On command line I can successfully run:
mvn package -DskipTests=false
to build, run tests and generate jars with maven
After running and the jar exists, I believe I should be able to run the following and have the tests run as well:
java -jar %CD%\target\myproj-0.0.1-jar-with-dependencies.jar TestTest.xml
however I get:
Error: Could not find or load main class org.testng.TestNG
Net goal, to be able to build a project using testng and run my tests with testNG xmls on the command line.
This should work independent of any IDE.
If you want to build so callled "fat jar" - a single executable .jar containing all dependencies and invoking TestNG main class I would recommend going for Maven Shade Plugin:
Remove the following lines from your pom.xml
<scope>provided</scope>
Add the following Maven Shade plugin definition to create an executable jar:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.testng.TestNG</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Package the jar
Once done you should be able to invoke your test as jar -jar myproj-0.0.1.jar
Full pom.xml just in case:
<?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>com.example</groupId>
<artifactId>myproj</artifactId>
<version>0.0.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<skipTests>true</skipTests>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0-beta3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
</dependencies>
<build>
<!-- Source directory configuration -->
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>org.testng.TestNG</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- // Following plugin executes the testng tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14.1</version>
<configuration>
<!-- // Suite testng xml file to consider for test execution -->
<suiteXmlFiles>
<suiteXmlFile>testtest.xml</suiteXmlFile>
</suiteXmlFiles>
<skipTests>${skipTests}</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.testng.TestNG</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

How to pack a JMeter test plan built from code into a jar using Maven?

I'm attempting to build a JMeter test plan in Java. I can't seem to find much documentation on this process, and the resources I can find all use Maven to build the jar. I have no prior experience with Maven and cannot get my pom configuration right.
Main points of confusion:
If my jar goes in jmeter_home/lib/ext, does that make dependencies like ApacheJMeter_core and ApacheJMeter_http a provided situation?
There seem to be multiple Maven plugins (maven-jar, maven-assembly) with a similar purpose? Is there one that best suits my needs?
If I want to reference a non java resource in a place outside of the jar (somewhere else in the JMeter directory), does that require special consideration when configuring your POM?
Am I supposed to configure the jar to be executable, or does JMeter provide like a script to work with lib/ext jars?
Any insight on any of these points would be greatly appreciated.
These resources have guided me along, but I've wasted hours trying to solve this seemingly menial piece of the process..
https://bitbucket.org/blazemeter/jmeter-from-code/
https://github.com/piotrbo/jmeterpoc
If anyone has more resources on building JMeter test plans in code, PLEASE feel free to share!
Here's my pom.xml, I understand that there's probably some redundancy in my use of plugins and such, but that happens when you've been attacking the same problem for hours with no progress :)
<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>com.sweber</groupId>
<artifactId>jmeter-plugin</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>jmeter-plugin</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>
com.sweber.Main
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
com.sweber.Main
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>5.0</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>5.0</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_http</artifactId>
<version>5.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>kg.apc</groupId>
<artifactId>jmeter-plugins-casutg</artifactId>
<version>2.7</version>
</dependency>
</dependencies>
</project>
You need to add com.lazerycode.jmeter in the POM.
https://github.com/jmeter-maven-plugin/jmeter-maven-plugin
So you add this to your pom :
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>2.9.0</version>
<executions>
<!-- Run JMeter tests -->
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
<!-- Fail build on errors in test -->
<execution>
<id>jmeter-check-results</id>
<goals>
<goal>results</goal>
</goals>
</execution>
</executions>
Also, if you're going to do in IDE testing, not just mvn clean verify, you'll have to unpack Jmeter dependencies to the target dir.
Using this in the project root directory : mvn com.lazerycode.jmeter:jmeter-maven-plugin:2.9.0:jmeter
Equivalent statement for any other mvn plugin : mvn groupId:artifactId:version:goal (based on POM structure of plugin)

Retrieve svn last changed revision number with the buildnumber-maven-plugin

I'm currently developing a microservice based architecture for my application. I've got a maven multi-module project which has many services, so I can easily deploy them to the docker hub using the maven deploy command and also a maven docker plugin.
Still, the docker image tags are based in the project version number, while I would like to have them tagged with each repository's last changed revision number. From the time being, I'm trying just to add this field as a manifest entry using the buildnumber-maven-plugin:
Let's say that's my multi-module project:
<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>
...
<modules>
<module>module-a</module>
<module>module-b</module>
</modules>
...
</project>
And the model for module-a would be:
<?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">
...
<scm>
<connection>scm:svn:http://myrepo.com/svn/application/module-a</connection>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>false</doCheck>
<doUpdate>true</doUpdate>
<useLastCommittedRevision>true</useLastCommittedRevision>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<SCM-Revision>${buildNumber}</SCM-Revision>
</manifestEntries>
</archive>
</configuration>
</plugin>
....
</plugins>
</build>
<dependencies>
...
</dependencies>
</project>
The issue is that {buildNumber} evaluates to my working copy number, which is the one referring to the last commit made to the repository and not to the scm:svn:http://myrepo.com/svn/application/module-a location. To explain it better, when I display the properties of module-a from tortoise I've got this:
What I want is to retrieve 3248 which refers to the last real change made to module-a, instead of 3257 (working copy), which is what I'm getting from the plugin. That way the docker plugin would know if it's a different image tag and push it only if changes were made to the module in the repo.
I couldn't get buildnumber-maven-plugin to work for this same scenario either. <useLastCommittedRevision> does not work in v1.4 and in v1.3 it does not return the last changed revision but the penultimate one in some situations.
There is a crafty workaround you can do to get the last changed revision number from svn info command output. Two options depending on your SVN version:
For SVN v1.9 or newer versions, use maven-antrun-plugin to run svn info --show-item=last-changed-revision and save the output into a property.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<exportAntProperties>true</exportAntProperties>
<target>
<exec executable="svn" outputProperty="svn.info">
<arg value="info"/>
<arg value="--show-item=last-changed-revision"/>
</exec>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<SCM-Revision>${svn.info}</SCM-Revision>
</manifestEntries>
</archive>
</configuration>
</plugin>
For SVN versions older than v1.9 (v1.8.13 in my case) you can use maven-antrun-plugin to run svn info --xml and save the output into a property, and build-helper-maven-plugin to parse the contents of that property with a regular expression, matching the last changed revision number and saving it into a second property.
I chose to add the --xml parameter because basic svn info output is translated depending on the language of the installation, but the xml output format is always the same.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<exportAntProperties>true</exportAntProperties>
<target>
<exec executable="svn" outputProperty="svn.info">
<arg value="info"/>
<arg value="--xml"/>
</exec>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>regex-svn-last-rev</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<!-- Output property -->
<name>svn.last.rev</name>
<value>${svn.info}</value>
<regex>^[\s\S]*?commit[\s\S]*?revision=\"(\d+?)\"[\s\S]*?$</regex>
<replacement>$1</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<SCM-Revision>${svn.last.rev}</SCM-Revision>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>false</doCheck>
<doUpdate>true</doUpdate>
<useLastCommittedRevision>true</useLastCommittedRevision>
</configuration>
</plugin>
This worked for me.
I think the only thing you missed here is
<doCheck>false</doCheck>
I think it should be true.
Having stumbled upon this issue as well, I felt compelled to get to the bottom of it:
This seems to be a rather old issue in buildnumber-maven-plugin itself:
Implement "Last Changed Rev" instead of "Revision" field
A fix was actually committed, but no new version has been released since then.
The easiest option would be to checkout/download the code and build it locally, making sure to put it into the central repository of your organization.
If this is not an option try jitpack to get the latest version as maven dependency directly:
Can I use a GitHub project directly in Maven? =>
https://stackoverflow.com/a/28483461/167865
...
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
...
<dependency>
<groupId>com.github.mojohaus</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>e74e373</version>
</dependency>
...
This is well-known bug in maven-scm-provider-svnexe. Still not fixed.

Resources