Build war file from Vertx project using Maven - maven

I've created a Vert.x project referring this. Also created a run configuration in eclipse referring this. The project successfully run as an application project in Eclipse and http://localhost:8080 is accesible.
As per the document it uses maven shade plugin to build a fat-jar (if I build it using Maven via terminal), which I only copy pasted, not understood much.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</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>io.vertx.core.Launcher</Main-Class>
<Main-Verticle>${main.verticle}</Main-Verticle>
</manifestEntries>
</transformer>
<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>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<configuration>
<mainClass>io.vertx.core.Launcher</mainClass>
<arguments>
<argument>run</argument>
<argument>${main.verticle}</argument>
</arguments>
</configuration>
</plugin>
</plugins>
Every examples says to create the jar file and run it on terminal. But I need to deploy this project into a tomcat server, as a WAR file. This server system is not accessible for me, so I must hand over the WAR to admin.
How can a WAR file be produced from this ? Please help!

A Vert.x application, although may be embedded into existing applications, is meant to be executed on its own (which may help you avoid many issues including ClassLoader ones).
Following the mentioned guideline, you should have created a Web API using Vert.x and which runs under the hood by an embedded server which prevents you from using Tomcat as a runtime container.

Related

Running maven-shade and dockerfile-maven in different phases

My app uses maven-shade-plugin to pack things into single fatjar and then I would like to build a docker image using dockerfile-maven-plugin, my problem is that I can set the pom file properly so it would work.
What happens is that the docker plugin runs before the jar file was created...
I've tried to force the jar creation on prepare-package and the docker image build on package but it didn't work as expected...
any ideas?
EDIT: added pom snippet
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-maven.version}</version>
<configuration>
<repository>test-docker-image</repository>
<tag>${docker.tag}</tag>
<buildArgs>
<JAR_FILE>${project.artifactId}-${project.version}-fat.jar</JAR_FILE>
<CONFIGURATION_FILE>configuration.json</CONFIGURATION_FILE>
</buildArgs>
</configuration>
<executions>
<execution>
<goals>
<goal>build</goal>
<!-- <goal>push</goal> -->
</goals>
<phase>install</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven.shade.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Launcher</Main-Class>
<Main-Verticle>MyVerticle</Main-Verticle>
</manifestEntries>
</transformer>
</transformers>
<minimizeJar>false</minimizeJar>
<outputFile>${project.build.directory}/deploy/${project.artifactId}-${project.version}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I had both of these same plugins listed in the same order you have (docker-maven-plugin before maven-shade-plugin) and was seeing the same issue. I discovered that Maven executes plugins in the same phase in the order that they are listed, so moving maven-shade-plugin to be first resolved the issue for me locally. (Older versions of Maven don't order plugins this way, so use the latest if possible.)
This doesn't explain why it is not working for you when you change them to use different phases, but I'd suggest at least trying it out that reordering. Also be sure that you are using the latest versions of related plugins, like maven-release-plugin.
I was still seeing the undesired behavior in my build environment after doing all of the above, due to the parent of my project containing an execution for docker-maven-plugin; the fact that I was customizing it and reordering it in my own project didn't help, although it is unclear why it worked locally. Maven build profiles can also have a similar impact on ordering. My solution there was to bind the docker-maven-plugin:build execution to the install phase.
The output of mvn help:effective-pom should let you see the exact listing of plugins, executions, and profiles so that you can see exactly what the ordering will be for your project. Note that profiles are executed bottom-to-top, which is the opposite of plugins!

How to package config.yml and resources in $project--0.0.1-SNAPSHOT.jar

I've a drop wizard project which has the following directory structure:
basedir
pom.xml
config.yml
src
main
resources
myresource.xml
The build portion of
<build>
<finalName>project-${version}</finalName>
<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>
<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>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>project-package.App</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When I run my code from Eclipse, I use command as follows:
$mypackage.App server config.yml
It works fine and I can read the file under resources directory.
When I use mvn to build, in the snapshot jar created, it does not include config.yml and the path to "myresource.xml" is missing even though it is included in the snapshot.jar in the basedir. So, when I run it from my jar file, my code does not find it as resources.
How should I change the pom.xml to include config.yml and package the resource directory such a way that it is accessible as resource.
It is really strange that
this.getClass().getResource("myresource.xml")
does work in IDE but NOT when you run it from a jar.
this.getClass().getResourceAsStream("myresource.xml")
works both inside IDE and from jar.
That resolves the resources issue. However, I need an answer for how to package config.yml file. Should I supply separately in addition to the jar file?

How can I specify a custom MANIFEST.MF file while using the Maven Shade plugin?

When a project uses the Maven-jar-plugin, it's easy to include a custom manifest file in the jar, but I can't find a way to do the same thing with Maven shade. How can I use my own manifest file while using the "Maven-shade-plugin"?
Additional details:
My custom manifest file is located in "src/main/resources/META-INF/MANIFEST.MF".
Maven is not including my file, instead it is being replaced in the final jar with a default Maven manifest file.
The reason I need a custom manifest file is to specify some JavaBeans classes in my manifest, for a swing component library. Multiple JavaBeans classes should be specified in the manifest file in the following format, as described here. Note that the empty lines (and the line grouping) are important for marking JavaBeans classes in the manifest.
Name: SomeBean1.class
Java-Bean: True
Name: SomeBean2.class
Java-Bean: True
Name: SomeBean3.class
Java-Bean: True
A list of attempted solutions (these did not work):
This code only works when using the Maven jar plugin (not shade).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
This link says "As with all the examples here, this configuration can be used in all plugins that use Maven Archiver, not just Maven-jar-plugin as in this example." Based on that advice, I tried the following code, but this did not work either. (Maven still replaced my manifest file with the default manifest file.)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>core</shadedClassifierName>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
I cannot use the shade "ManifestResourceTransformer" as described here to do the job, for the following reason. I need to add JavaBeans classes to my manifest file as described above under "additional details". However, if I add manifest entries using the shade ManifestResourceTransformer, those entries are inserted into the manifest file in an unpredictable (random-seeming) ordering. For specifying JavaBeans classes, the ordering of the manifest entries (the line order) is important.
I attempted to use IncludeResourceTransformer, but the below code produces the following error: "Error creating shaded jar: duplicate entry: META-INF/MANIFEST.MF".
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>core</shadedClassifierName><createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
<resource>META-INF/MANIFEST.MF</resource>
<file>src/main/resources/META-INF/MANIFEST.MF</file>
</transformer>
</transformers>
</configuration>
The following pom configuration allows the programmer to replace the manifest file created by Apache Maven Shade plugin, with a custom manifest file. The custom manifest file should be placed in this directory in the maven project: "src/main/resources/META-INF/MANIFEST.MF"
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
...
<transformers>
<!-- Don't do this: Avoid adding anything that makes shade create or modify a manifest file.
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mypackage.MyMainClass</mainClass>
</transformer>
-->
<!-- Add a transformer to exclude any other manifest files (possibly from dependencies). -->
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>MANIFEST.MF</resource>
</transformer>
<!-- Add a transformer to include your custom manifest file. -->
<transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
<resource>META-INF/MANIFEST.MF</resource>
<file>src/main/resources/META-INF/MANIFEST.MF</file>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

Maven shade plugin does not merge files

My goal is to merge two XML files (both named info.xml) which are in src/main/resources of two Maven modules (packaging:jar) into a target WAR archive.
proj1: contains src/main/resources/info.xml
proj2: contains src/main/resources/info.xml
web: web project which should contain a merged info.xml from proj1 and proj2. I declared the plugin in the web project:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>info.xml</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
To build the web project and its modules I have a build project with:
<modules>
<module>proj1</module>
<module>proj2</module>
<module>web</module>
<modules>
I tried using a mvn clean package command in the build project and as result my web/target/web.war contains the unpacked libs (ueber.jar which I don't really want) and NO merged info.xml files.
What am I doing wrong?!
You have to configure Transformers to merge files, since it often requires extra logic, especially XML. See Resource Transformers for the details.

Usage of the maven-shade plugin's AppenderTransformer

Okay, I am running into the typical problem in which I need to create a uber jar, but my project dependencies has multiple spring.handlers and spring.schemas files. I have search around and figured out that my problem required me to use the maven-shade plugin, along with it's AppendingTransformer. The problem is that when I add the configuration and run the goal it does not merge the files; what's more, I can put a bogus classpath in for the appender or resource file and it does not complain, which lead me to believe that it is not even attempting to execute the transformer.
execute- mvn compile package shade:shade
<build>
<finalName>mongo-dictionary</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
I had my plugins configured as children of the pluginManagement element, once I got rid of the pluginManagement tag everything works as advertised.
where is this plugin configuration, can you ensure that it is in the right place - build -> plugins element of the project for which you are creating uber jar. I have the same configuration which works for me.
Also you don't need to execute shade:shade separately. Running mvn package will do that for you.

Resources