Spring Boot jar executable - How to generate files to different directory similar as maven-dependency-plugin does - maven

As straich question, why spring-boot-maven-plugin works but maven-assembly-plugin not in the pom below?
I have googled few hours and I red somewhere that we don't need maven-assembly-plugin if we use spring-boot-maven-plugin. It doesn't answer my question since I want to have more control in which folder my files are genereated. Along that, if I "mvn clean compile package assembly:single" I get two executable jars, one outcome of spring-boot-maven-plugin and another outcome of maven-assembly-plugin in my project target folder. The one generated by spring-boot-maven-plugin runs as expected when I start via command line (java -jar aws.scheduller-1.jar. On the opposite, if I try java -jar aws.scheduller-1-jar-with-dependencies.jar I get a message complaining that it wasn't possible to load ...config.BootApp (I googled a bit and I guess it is something related to certain default profile in Spring Boot).
That said, how can I use maven to package Spring-boot dependency in different folder than default target directory?
Main Class
#SpringBootApplication
#EnableScheduling
#ComponentScan({ "br.com.mycompany.tasks","br.com.mycompany.utils" })
#PropertySource("file:C:/temp/application.properties")
//#PropertySource("file:/home/ec2-user/JOBs/application.properties")
public class BootApp {
public static void main(String[] args) {
SpringApplication.run(new Object[] { BootApp.class }, args);
}
}
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>grpAwsScheduller</groupId>
<artifactId>aws.scheduller</artifactId>
<version>1</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceencoding>UTF-8</project.build.sourceencoding>
<logback.version>1.1.9</logback.version>
<logstash-logback-encode.version>4.8</logstash-logback-encode.version>
<spring-boot-starter.version>1.4.3.RELEASE</spring-boot-starter.version>
<aws-java-sdk.version>1.11.73</aws-java-sdk.version>
<jdk.version.version>1.7</jdk.version.version>
<project.build.directory>C:/temp</project.build.directory>
<!-- Maven versions -->
<!-- https://maven.apache.org/plugins/ -->
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
<maven-dependency-plugin.version>3.0.0</maven-dependency-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>${aws-java-sdk.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
<version>1.11.73</version>
</dependency>
<!-- <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-sqs</artifactId>
<version>${aws-java-sdk.version}</version> </dependency> <dependency> <groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sns</artifactId> <version>${aws-java-sdk.version}</version>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encode.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<mainClass>br.com.MyCompany.config.BootApp</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>br.com.MyCompany.config.BootApp</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<!-- <excludes> <exclude>**/log4j.properties</exclude> </excludes> -->
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>br.com.MyCompany.config.BootApp</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

Related

How to Create Spring Boot Thin and Fat Jar in Same Spring Boot Maven Project

I am having a need to build my spring boot project as both fat and thin jar,
Expected output: one fat jar and one thin jar
Actual output: both are fat jars. I extracted and checked, it contains BOOT-INF/lib having jars
Following is my build plugin configuration
spring boot version 2.4.3
spring boot thin version 1.0.25.RELEASE
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>create-fat-jar</id>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
<configuration>
<mainClass>com.mycomp.ExampleApplication</mainClass>
<addResources>true</addResources>
<finalName>${project.artifactId}-fat-${project.version}</finalName>
</configuration>
</execution>
<execution>
<id>create-thin-jar</id>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
<configuration>
<executable>false</executable>
<addResources>true</addResources>
<finalName>${project.artifactId}-thin-${project.version}</finalName>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${springboot.thin.version}</version>
</dependency>
</dependencies>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Please help me to resolve this issue.
There is an experimental thin layout project from Spring, try to use the below and it will help you.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>1.0.28.BUILD-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
https://github.com/spring-projects-experimental/spring-boot-thin-launcher
I think creating a Fat jar in spring boot is very easy. The part of creating a Thin jar requires special changes in pom.xml file. Let me describe both scenarios here:
In both cases, the top part will be same:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.package</groupId>
<artifactId>YourApplication</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>YourApplication</name>
<description>Your description</description>
<properties>
<java.version>1.8</java.version>
<mainClass>com.package.YourApplication.Main</mainClass>
</properties>
pom.xml for fat jar:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
...
your other dependencies as well...
</dependencies>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.1</version>
<configuration>
<executable>true</executable>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugins>
The plugins are important. Because they provide specific build commands to maven.
Now, for thin jar creation:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!-- <scope>provided</scope>-->
</dependency>
...
your other dependencies as well...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
Here, you can see that in dependencies, tomcat provided scope is removed. Also, the plugins have changed. Executing mvn package then mvn install will generate the thin jar and copy all the dependencies outside the jar file in lib/ folder.
I hope this helps you. :)

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't build working Java app with gRPC, Protobuf and BoringSSL to JAR using Maven

I have problem with building my Java app to jar file using Maven.
Application is using gRPC and Protobuf.
When I start my app in IntelliJ everything work just fine, problem is when I want to build jar with Maven... I don't have much experience with creating pom files.
I tried to find some solution but nothing works and I ended up with pom.xml as below:
[...]
<properties>
<grpc.version>1.17.1</grpc.version>
<protoc.version>3.5.1-1</protoc.version>
<netty.tcnative.version>2.0.13.Final</netty.tcnative.version>
[...]
</properties>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>${netty.tcnative.version}</version>
<scope>runtime</scope>
</dependency>
[...]
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireUpperBoundDeps/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>pl.test.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
And this is the exception when I try to start gRPC server with SSL context:
Exception in thread "Thread-2" java.lang.UnsatisfiedLinkError: failed to load the required native library
at io.netty.handler.ssl.OpenSsl.ensureAvailability(OpenSsl.java:346)
at io.netty.handler.ssl.ReferenceCountedOpenSslContext.<init>(ReferenceCountedOpenSslContext.java:202)
at io.netty.handler.ssl.OpenSslContext.<init>(OpenSslContext.java:43)
at io.netty.handler.ssl.OpenSslServerContext.<init>(OpenSslServerContext.java:347)
at io.netty.handler.ssl.OpenSslServerContext.<init>(OpenSslServerContext.java:335)
at io.netty.handler.ssl.SslContext.newServerContextInternal(SslContext.java:422)
at io.netty.handler.ssl.SslContextBuilder.build(SslContextBuilder.java:447)
at pl.test.grpc.GrpcServer.start(GrpcServer.java:80)
at pl.test.app.Main.lambda$new$0(Main.java:80)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: io.netty.internal.tcnative.SSL
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at io.netty.handler.ssl.OpenSsl.<clinit>(OpenSsl.java:85)
at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:194)
at pl.test.grpc.GrpcServer.getSslContextBuilder(GrpcServer.java:72)
... 3 more
I'm building it using command:
mvn clean compile assembly:single
Can someone help with creating working pom file? The result doesn't have to be single jar file, it might be multiple jars.
I found solution, maybe it will help someone deal with the same problem.
We have to add dependency io.netty.netty-handler and set compatible versions of io.grpc.grpc-netty, io.netty.netty-tcnative-boringssl-static and io.netty.netty-handler as it is described in table over here https://github.com/grpc/grpc-java/blob/master/SECURITY.md#netty.
Here's my current pom.xml
[...]
<properties>
<grpc.version>1.17.1</grpc.version>
<protoc.version>3.5.1-1</protoc.version>
<netty.tcnative.version>2.0.17.Final</netty.tcnative.version>
<netty.handler.version>4.1.30.Final</netty.handler.version>
[...]
</properties>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
<version>${netty.handler.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>${netty.tcnative.version}</version>
<scope>runtime</scope>
</dependency>
[...]
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireUpperBoundDeps/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>pl.test.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
And now I can build jar using command:
mvn clean compile assembly:assembly

Logback Maven java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

I get the following after running a Jar (Maven project):
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
The error is caused in the declaration of the variable:
private static final Logger logger = LoggerFactory.getLogger("name.log");
This error is caused because I need to add to the project classPath a slf4j implementation (this is what I understood after hours of searching)
The solutions I have read Online suggest adding to the Pom a dependency and that it should solve it. Well, for some reason it does not work for me.
Since it is a Maven project, my pom.xml looks like this:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
</dependency>
May be relevant: When I run the project in Netbeans (IDE), it logs perfectly; but once I build and try to run the jar it throws the exception mention above.
I appreciate the help.
It's not related to this issue, but keep only one slf4 implementation, e.g. slf4j-simple.
Now about the missing LoggerFactory. When running outside an application server, the libraries must be provided, either through an explicit classpath or by embedded the required jar archives in the generated jar (a fatjar).
For the former option, it can be done on the command line or with the jar manifest.
Below is a pom that shows the use of the manifest and the generation of a fatjar:
without packaging, using the maven classpath:
mvn clean compile antrun:run -Pclass-antrun
packaging with a classpath inside the manifest:
mvn clean package antrun:run -Pjar-antrun
packaging a fatjar:
mvn clean package antrun:run -Pfatjar
<?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>dummy-slf4j</groupId>
<artifactId>dummy-slf4j</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<main.class>dummy.App</main.class>
<jdk.version>1.6</jdk.version>
<project.encoding>UTF-8</project.encoding>
<project.build.sourceEncoding>${project.encoding}</project.build.sourceEncoding>
<project.reporting.outputEncoding>${project.encoding}</project.reporting.outputEncoding>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>
<maven.compiler.compilerVersion>${jdk.version}</maven.compiler.compilerVersion>
<maven.compiler.fork>true</maven.compiler.fork>
<maven.compiler.verbose>true</maven.compiler.verbose>
<maven.compiler.optimize>true</maven.compiler.optimize>
<maven.compiler.debug>true</maven.compiler.debug>
<maven.jar.plugin.version>2.6</maven.jar.plugin.version>
<maven.assembly.plugin.version>2.6</maven.assembly.plugin.version>
<maven.dependency.plugin.version>2.10</maven.dependency.plugin.version>
<maven.antrun.plugin.version>1.8</maven.antrun.plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.13</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven.jar.plugin.version}</version>
<configuration>
<archive>
<manifest>
<mainClass>${main.class}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>${maven.antrun.plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven.assembly.plugin.version}</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>${main.class}</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven.dependency.plugin.version}</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/lib/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>jar-antrun</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<configuration>
<target>
<java fork="true"
jar="${project.build.directory}/${project.build.finalName}.jar" />
</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>class-antrun</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<configuration>
<target>
<java fork="true" classname="${main.class}">
<classpath refid="maven.compile.classpath" />
</java>
</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>fatjar</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<configuration>
<target>
<java fork="true"
jar="${project.build.directory}/${project.build.finalName}-jar-with-dependencies.jar" />
</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
With the main app:
package dummy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class App {
private static final Logger logger = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
logger.info("toto");
}
}
UPDATE: add a profile for a fatjar

How can I add classpath location by using mojo appassembler plugin while creating batch file

I am using appassembler plugin from mojo for creating a runnable batch/shell script for my application. I have to add a particular directory to my classpath, so what changes should I do in my pom.xml configuration for mojo's plugin.
Currently classpath is generated with all required library path in my batch file as below
set CLASSPATH=%BASEDIR%\abc.jar;%REPO%\*.properties
All I need to do is add a separate variable like MY_PATH and add it to the classpath as below
set MY_PATH=%BASEDIR%\resources
set CLASSPATH=%BASEDIR%\abc.jar;%REPO%\*.properties;%MY_PATH%
To add to further there is a tag <configurationDirectory> but that I have already provided for a different directory, now if I have to add further more directory then what would be solution?
How can i achieve it? Below is the 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>
<parent>
<artifactId>jgcode-framework-parent</artifactId>
<groupId>com.jaggs</groupId>
<version>1.0.2</version>
</parent>
<groupId>com.jaggs.server</groupId>
<artifactId>jaggs-code-server</artifactId>
<version>1.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jaggs.password</groupId>
<artifactId>mypassword</artifactId>
<version>1.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<configuration>
<repositoryLayout>flat</repositoryLayout>
<installArtifacts>false</installArtifacts>
<assembleDirectory>${project.build.directory}/appassembler</assembleDirectory>
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
<platforms>
<platform>windows</platform>
<platform>unix</platform>
</platforms>
<defaultJvmSettings>
<initialMemorySize>256M</initialMemorySize>
<maxMemorySize>256M</maxMemorySize>
</defaultJvmSettings>
<programs>
<program>
<name>ManualDataEntry</name>
<mainClass>com.jaggs.bean.ManualDataEntry</mainClass>
</program>
</programs>
<configurationDirectory>\..\..\jaggs\sec\configuration\</configurationDirectory>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assemble.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>com.jaggs.bean.ManualDataEntry</mainClass>
</manifest>
<manifestEntries>
<Class-Path>/jaggs/sec/configuration/</Class-Path>
</manifestEntries>
</archive>
<delimiters>
<delimiter>${*}</delimiter>
</delimiters>
</configuration>
<executions>
<execution>
<id>my-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<escapeString>\</escapeString>
</configuration>
</plugin>
</plugins>
</build>

Resources