How to build an executable jar with embedded jetty containing tld files using maven shade - maven

I want to make executable jar file using apache shade plugin. The project is a webapp with a bunch of jsp s. We are using embedded jetty with jasper jsp engine. Some jstl tag are used in these jsp's. So I need to properly pack all the tld files in my resulting jar.
Now we are using a custom transformer for maven shade plugin to place all tld files into WEB-INF/META-INF root directory.
I wonder if there is a way of doing it without using a custom transformer. Can it be done with standard shade transformers?
UPD.
Jetty, apache-jsp, apache-jstl libs version 9.2.13.v20150730
maven shade config :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>shade-resource-transformers</artifactId>
<version>1.0.2</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>shade</shadedClassifierName>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.company.application.Server</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer
implementation="com.company.build.maven.shade.transformer.TldResourceTransformer">
<tldDestFolder>WebRoot/WEB-INF/META-INF/</tldDestFolder>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
As you can see we use custom tranformer here.
Enabling jsp support:
Configuration.ClassList classlist = Configuration.ClassList
.setServerDefault(server);
classlist.addBefore(
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration");

Related

Cannot find 'manifestEntries' in class org.apache.maven.plugins.shade.resource.ServicesResourceTransformer

I am trying to create a FAT jar and combine entries in META-INF/services/io.vertx.config.spi.ConfigProcessor from vertx-config and vert-config-yaml JAR files. I do not see a need for mainfest entry options for ServicesResourceTransformer, but I am experiencing the error:
Unable to parse configuration of mojo org.apache.maven.plugins:maven-shade-plugin:3.2.1:shade for parameter manifestEntries: Cannot find 'manifestEntries' in class org.apache.maven.plugins.shade.resource.ServicesResourceTransformer -> [Help 1]
At first, I did not add the line
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
and the manifest entries did not get merged and one of the class from vert-config-yaml is missing. Now I add the line as below, and I see the error. I am using maven-shade-plugin plugin version 3.2.1. What am I doing wrong here?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven.shade.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/.SF</exclude>
<exclude>META-INF/.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Launcher</Main-Class>
<Main-Verticle>${main.verticle}</Main-Verticle>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/io.vertx.core.spi.VerticleFactory</resource>
</transformer>
</transformers>
<artifactSet>
</artifactSet>
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
Try adding <id> to your execution:
<execution>
<id>shade-my-jar</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
explanation (kinda symmetric question): https://stackoverflow.com/a/56154292

Submitting spring boot application jar to spark-submit

I am pretty new to spark, and i am trying to try out spark submit. I created an application in spring boot , used mvn package to create a jar . But when i am trying to submit the jar to spark-submit , it is not able to find the Main class . But the main class is present in the jar.
spark-submit --class com.dip.sparkapp.SparkappApplication --master local target/sparkapp-0.0.1-SNAPSHOT.jar
We ran into the same problem, actually, on the same day you posted this. Our solutions was to use the shade plugin for maven to edit our build a bit. We found that when packaging with the spring-boot-maven plugin it nested our classes in BOOT-INF/classes which spark didn't like. I'll paste the relevant section so you can try it out on your own application -- good luck!
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot-version}</version>
</dependency>
</dependencies>
<configuration>
<keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${start-class}</mainClass>
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
I have found that simply skipping the class name from spark-submit works, i.e. --class com.dip.sparkapp.SparkappApplication
If your are using gradle this will work for shadow plugin:
import com.github.jengelman.gradle.plugins.shadow.transformers.*
...
plugins {
id 'com.github.johnrengelman.shadow' version '2.0.4'
}
...
shadowJar {
zip64 true
mergeServiceFiles()
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
transform(PropertiesFileTransformer) {
paths = ['META-INF/spring.factories' ]
mergeStrategy = "append"
}
}
Taken from here: https://github.com/spring-projects/spring-boot/issues/1828#issuecomment-607352468
This works for me
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>packagename.classname</Main-Class>
</manifestEntries>
</transformer>

How to build a jar from a module of maven with dependencies from other module?

I have some modules in maven, and I want to build a jar of a module which has a dependency of just other module.
How can I include in the jar both modules?
Edit:
I have the followings modules:
myproject-core/
myproject-api/
myproject-dependencie/
myproject-api-web/
And I want to build a jar in myproject-api with myproject-dependencie. I have more dependencies in myproject-api and I only need to have in this jar myproject-api and myproject-dependencie.
Thanks!
I guess the maven-shade-plugin will be your friend:
https://maven.apache.org/plugins/maven-shade-plugin/
In you plugins section Something like:
...
<properties>
<shade-main-class>{your-main-class}</shade-main-class>
</properties>
...
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<includes>
<include>com/yourcompany/**</include>
</includes>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${shade-main-class}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
...

Maven Shade Plugin not including resources of dependency

I'm using the Maven Shade Plugin to include all dependencies during package phase.
That works fine for classes, but dependent resources aren't included.
Here's the layout of the dependent jar:
./config.properties <-- this is the missing resource
./META-INF
./META-INF/MANIFEST.MF
./META-INF/maven
./META-INF/maven/com.example
./META-INF/maven/com.example/bar
./META-INF/maven/com.example/bar/pom.properties
./META-INF/maven/com.example/bar/pom.xml
Here's the shade plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.example.foo.Foo</Main-Class>
<!-- <X-Compile-Source-JDK>${maven.compile.source}</X-Compile-Source-JDK>.
<X-Compile-Target-JDK>${maven.compile.target}</X-Compile-Target-JDK> -->
</manifestEntries>
</transformer>
</transformers>
<filters>
<filter>
<!--
Exclude files that sign a jar
(one or multiple of the dependencies).
One may not repack a signed jar without
this, or you will get a
SecurityException at program start.
-->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.INF</exclude> <!-- This one may not be required -->
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
It's embarrasing, but there was a typo in the version of the dependency and that version didn't have the file.

Packaging camel project with cxf jars

I just started looking into Camel, and started off with some out of the box examples. It works great when using mvn camel:run. I am also trying to package this as one uber jar and be able to execute it from the command line.
I am using the Maven shade plugin to build the jar. When I try to execute it, I get this error:
Caused by: org.apache.cxf.BusException: No DestinationFactory was found for the namespace http://cxf.apache.org/transports/http.
at org.apache.cxf.transport.DestinationFactoryManagerImpl.getDestinationFactory(DestinationFactoryManagerImpl.java:126)
at org.apache.cxf.endpoint.ServerImpl.initDestination(ServerImpl.java:88)
at org.apache.cxf.endpoint.ServerImpl.<init>(ServerImpl.java:72)
at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:149)
I have these dependencies along with some others:
<properties>
<camel.version>2.8.0-fuse-04-01</camel.version>
<cxf.version>2.4.3-fuse-02-02</cxf.version>
</properties>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
Here is how the transformers are defined within the maven shade plugin:
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.apache.camel.spring.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
I don't know what I am missing. Can someone help me fix this issue? Please let me know of any alternative approaches.
You might not have cxf.xml in your created jar.
It should be located in META-INF/cxf/cxf.xml .
Shade might need a more complete configuration (see this question for instance)
<configuration>
<transformers>
...
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/cxf/cxf.extension</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/extensions.xml</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/cxf/extensions.xml</resource>
</transformer>
</transformers>
</configuration>
I had the same issue. I solved it by adding an org.apache.maven.plugins.shade.resource.AppendingTransformer for bus-extensions.txt.
This worked for me:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactId>${ivyExecutable}</shadedArtifactId>
<finalName>${ivyExecutable}</finalName>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>exec</shadedClassifierName>
<artifactSet>
<includes>
<include>*:*</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/cxf/bus-extensions.txt</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${mainClass}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-buildtools</artifactId>
<version>2.2.12</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
</plugin>

Resources