Running an Executable Jar using Maven - java

Is it possible to run an executable jar file using Maven?
A brief introduction to setup:
Environment is running on Centos
I have included the exec plugin into my maven POM and have it running a shell script that is meant to run the jar file and works fine using the terminal but I get Unable to access jarfile error when run in maven.
I have chmod the jar, shell and other files to 777
I have editted the sudoers file as suggested by other posts
I have also given maven and Jenkins root access
All of these changes still result in the above error and I have run out of ideas.
HELP!!!
POM File
<pluginRepositories>
<pluginRepository>
<id>smartbear-sweden-plugin-repository</id>
<url>http://www.soapui.org/repository/maven2/</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<executions>
<execution>
<!-- Run our Password Checker script -->
<id>Password Checker</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>src/pass/passCheck.sh</executable>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>eviware</groupId>
<artifactId>maven-soapui-plugin</artifactId>
<version>4.5.1</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>test</goal>
</goals>
<id>MPesa-Tests</id>
<configuration>
<projectFile>src/test/GenericAPI-G2-soapui-project.xml</projectFile>
<outputFolder>SoapUI-Results/</outputFolder>
<junitReport>true</junitReport>
<exportwAll>true</exportwAll>
<printReport>false</printReport>
<projectProperties>
<value>message=Tests Completed</value>
</projectProperties>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<configuration>
<outputDirectory>/usr/share/Surefire/</outputDirectory>
<reportDirectories>
<reportDirectories>/usr/share/Surefire/reports/</reportDirectories>
</reportDirectories>
</configuration>
</plugin>
</plugins>
</build>
</project>

I had this exact same need to execute a Spring Boot packaged application and solved it by using the maven dependency plugin to copy the artifact to /tmp (or anywhere for that matter) and then using the maven exec plugin to execute that jar using the exec:exec goal.

Related

Maven : Download of executable zip based on OS

I want to download a zip file via mavens POM.XML, but based on the OS i need different URLs (Linux/Windows).
How can I change the URL based on the OS maven is executed? (locally, its Windows, on Jenkins its then Linux)
This is how the plugins part of my POM.XML looks like:
<build>
<plugins>
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<executions>
<execution>
<!-- the wget goal actually binds itself to this phase by default -->
<phase>process-resources</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://test/chromedriver_win32.zip</url>
<unpack>true</unpack>
<outputFileName>chromedriver</outputFileName>
<outputDirectory>${project.build.directory}/chromeDriver</outputDirectory>-->
<outputDirectory>${user.home}/localdata/tools/chromeDriver</outputDirectory>
<overwrite>true</overwrite>
<skipCache>true</skipCache>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

spring-boot-maven-plugin doesn't create fat jar

I'm using spring-boot-maven-plugin to package my REST service. I'm building the jar using mvn clean install or mvn clean package. After I decompile the jar, I don't find any of the dependencies added (I was expecting it to be a fat jar with all dependencies)
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.9.RELEASE</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
<finalName>myapp</finalName>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
When I run the spring boot using java -jar myapp.jar -Drun.jvmArguments="-Dspring.profiles.active=qal" I'm getting ClassNotFoundException for many of the classes. It's clear that artifact didn't build as expected. However, if I start spring boot application using maven ./mvnw spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=qal" I guess, it finds all the dependencies in target folder hence works fine. How can I fix the build issue so that I can start app using java -jar command.
EDIT: It's multi-module maven project
it seems you are using a wrong command. mvn clean package is maven command, you should use command 'repackage', it used for
Repackages existing JAR and WAR archives so that they can be executed
from the command line using java -jar
as it mentioned here https://docs.spring.io/spring-boot/docs/current/maven-plugin/repackage-mojo.html
Or probably it's plugin configuration issue. Just checked: it works with spring-boot-maven-plugin-2.0.0.RELEASE
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
Use this one
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${start-class}</mainClass>
<executable>true</executable>
<fork>true</fork>
<!-- Enable the line below to have remote debugging of your application on port 5005
<jvmArguments>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</jvmArguments>
-->
</configuration>
</plugin>

With maven, how to modify deploy files just prior to deploy phase?

I have a maven project with one war and several ear projects. Each ear project requires a slightly different war/WEB-INF/web.xml. Each ear's pom.xml uses com.google.code.maven-replacer-plugin:replacer and org.codehaus.mojo:truezip-maven-plugin to replace tokens in the web.xml, and then place that new web.xml in the final <project>-app.ear/web.war/WEB-INF. This all works great with building and creating the final EAR artifacts.
The problem I'm having is that when I run (using Netbeans, but that shouldn't matter), the web.xml used for deployment (<project>/target/gfdeploy/first-app/web_war/WEB-INF/web.xml) is the tokenized version. I tried adding execution phases for deploy, but that doesn't work.
How can I ensure that the run deploy has the modified web.xml so I can test my app during development?
Here is the relevant parts of the ear pom.xml:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<id>package-replace</id>
<phase>package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
<execution>
<id>deploy-replace</id>
<phase>deploy</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>${project.parent.basedir}/${web.xml}</file>
<outputFile>${project.build.directory}/${web.xml}</outputFile>
<replacements>
<replacement>
<token>#REALM_NAME#</token>
<value>${web.realm}</value>
</replacement>
</replacements>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>package-replace-web-xml</id>
<goals>
<goal>copy</goal>
</goals>
<phase>package</phase>
<configuration>
<files>
<file>
<source>${project.build.directory}/${web.xml}</source>
<outputDirectory>${project.build.directory}/${project.build.finalName}/${web.zip}/WEB-INF</outputDirectory>
</file>
</files>
</configuration>
</execution>
<execution>
<id>package-replace-web</id>
<goals>
<goal>copy</goal>
</goals>
<phase>package</phase>
<configuration>
<files>
<file>
<source>${project.build.directory}/${project.build.finalName}/${web.zip}</source>
<outputDirectory>${project.build.directory}/${project.build.finalName}.ear</outputDirectory>
</file>
</files>
</configuration>
</execution>
<execution>
<id>deploy-replace-web-xml</id>
<goals>
<goal>copy</goal>
</goals>
<phase>deploy</phase>
<configuration>
<files>
<file>
<source>${project.build.directory}/${web.xml}</source>
<outputDirectory>${project.build.directory}/gfdeploy/${project.artifactId}/web-${project.version}_war/WEB-INF</outputDirectory>
</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
I suggest you to keep your default src/main/webapp/WEB-INF/web.xml fully functional for running during development. Then, keep a similar file called src/main/webapp/WEB-INF/web-ear.xml with all the replacement preparation.
Wrap all your replacement plugin strategy inside a maven profile and targeted to the web-ear.xml file. Add to this profile a maven-war-plugin configuration that will use the alternative web-ear.xml file during build, instead of the default web.xml (check: http://maven.apache.org/plugins/maven-war-plugin/):
<profiles>
<profile>
<id>change-war-profile</id>
<build>
<plugins>
<!-- all your replacement plugins here -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>src/main/webapp/WEB-INF/web-ear.xml</webXml>
</configuration>
</plugin>
<plugins>
</build>
</profile>
</profiles>
Make sure to activate this profile during the EAR maven build:
mvn package -Pchange-war-profile
you can run your war with the jetty-maven-plugin choosing the run-war goal.
That goal run the packaged war.
See: https://www.eclipse.org/jetty/documentation/9.4.x/jetty-maven-plugin.html#running-assembled-webapp-as-war
First of all, deploy phase (of the build lifecycle) means deployment a production ready artifact to the remote Maven repository (e.g., Nexus or Artifactory). Roughly speaking, artifact deploy can be treated as copying the artifact. Read the Introduction to the Build Lifecycle for more details.
Secondly, Apache Maven does not support application deploy to the application server out-of-the-box. However, there are several ways to do it, depending on the application server you use. Which one do you use?
Special plugin can be found for JBoss Application Server - jboss-as-maven-plugin. See usage example:
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.9.Final</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
...
</project>
Similar plugin can be found for GlassFish Server: glassfish-maven-plugin.
Also, if this is acceptable for you, you can perform 2-steps deploy from Netbeans:
Build the project: run mvn package with all your plugins are configured at package phase.
Deploy the project: run application on the app server from Netbeans if it is supported (See NetBeans Java EE Servers Support page).
Hope this helps.

How to deploy war to Tomcat from child pom using maven tomcat plugin?

I have a maven project with the following plugin in the pom
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/casemanager</path>
<update>true</update>
</configuration>
</plugin>
When I do a mvn tomcat7:run, my war is deployed just fine. But I have the following configuration in one of the modules of my maven project
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<executions>
<execution>
<id>tomcat-run</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<fork>
true
</fork>
</configuration>
</execution>
<execution>
<id>tomcat-shutdown</id>
<goals>
<goal>shutdown</goal>
</goals>
<phase>post-integration-test</phase>
</execution>
</executions>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
I want tomcat to run in the pre-integration-test phase. Now when I do a mvn verify, it starts the server but does not deploy my war. I have even tried providing the warSourceDirectory. Am I missing something here?
I figured it out. Seems like when I execute a goal in a child pom, tomcat does not search for wars in other modules on the same level. I had to use webapp
<webapps>
<webapp>
<groupId>com.fico.fos.casemanager</groupId>
<artifactId>casemanager.ui</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
<asWebapp>true</asWebapp>
</webapp>
</webapps>
I had to use this within the configuration tags

Attaching maven-exec-plugin to initialize

I am trying to attach an exec process to a maven build. I want to build a secondary dependency (that is actually a Clojure project build with maven) every time I build the maven project.
Currently, I have the pom.xml below, but the exec process is just not running. The maven documentation is not that much help.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>compile-with-lein</id>
<phase>initialize</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>lein</executable>
<commandlineArgs>install</commandlineArgs>
<workingDirectory>../nrepl-clojure</workingDirectory>
</configuration>
</plugin>

Categories