Invoke a jar file in the M2 repository - maven

I have a project, in which I want to invoke another Jar file in M2 repo during the post execution phase of the current project.
Sample skeleton of my POM
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>exec-one</id>
<phase>verify</phase>
<configuration>
executable>java</executable>
<arguments> <argument>-jar</argument>
<argument>JarToInvoke.jar</argument>
</arguments>
<**workingDirectory**>/C:/path to repo</workingDirectory>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<dependencies> <dependency>
<groupId>GroupId of JarToInvoke</groupId>
<artifactId>JarToInvoke</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
I tried with maven-exec-plugin, but having the following issues;
Where I need to specify to JarToInvoke dependency ? As a project dependency or as a exec-plugin dependency ?
With hard coding the working directory(/C:/path to repo), I am able to invoke the JarToInvoke artifact. But it is not a good solution, because finally this project should run in any m/c with different OS's. So how can I make the exec-plugin to search for the JarToInvoke artifact in the M2 repo of the project(default classpath) ?
3.While hard coding the M2 repo path in the working directory, I was able to invoke the JarToInvoke artifact. But while running the JarToInvoke artifact, it throws another dependency issue, some of the log4j dependencies to the JarToInvoke could not find. I made the JarToInvoke as a shaded jar and it work as expected. But it is not a permanent or good solution(Because the shaded jar size is of 35 MB). How can I instruct the exec-plugin to look for the dependent Jars in M2 repo.
Please share your suggestions. Thanks in Advance.

This example page from the Exec plugin's documentation describes what you want I think.
If you could use the exec:java goal instead of exec:exec, finding the JVM is taken care of for you. You can also pull in either plugin dependencies or project dependencies by changing the includeProjectDependencies and includePluginDependencies configuration options of the plugin.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>exec-one</id>
<phase>verify</phase>
<configuration>
<includeProjectDependencies>false</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<executableDependency>
<groupId>GroupId of JarToInvoke</groupId>
<artifactId>JarToInvoke</artifactId>
</executableDependency>
<!-- Look up the main class from the manifest inside your dependency's JAR -->
<mainClass>com.example.Main</mainClass>
<arguments>
<!-- Add any arguments after your JAR here --->
</arguments>
</configuration>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>GroupId of JarToInvoke</groupId>
<artifactId>JarToInvoke</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
The only disadvantage is that you have to explicitly specify the main class in the JAR to run. You can look this up by opening up the manifest in the dependency JAR and read the Main-Class attribute.
If you really need to use exec:exec, you could use the Maven Dependency Plugin's copy-dependencies goal to copy dependencies from your local repository to a predefined location (such as ${project.build.directory}/exec-jars) and then you can feed this directory in the exec plugin's workingDirectory configuration option.

Probably an easier way to locate the absolute path to the jar file would be to use maven-dependency-plugin with properties goal.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>exec-one</id>
<phase>verify</phase>
<configuration>
<executable>java</executable>
<arguments>
<argument>-jar</argument>
<argument>${GroupIdofJarToInvoke:JarToInvoke:jar}</argument>
</arguments>
<workingDirectory>/C:/path to repo</workingDirectory>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<dependencies>
<dependency>
<groupId>GroupIdofJarToInvoke</groupId>
<artifactId>JarToInvoke</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependencies>

Related

Exclude Test dependencies and plugin dependencies in maven copy dependencies command

Maven copy dependencies command is not excluding the dependencies mentioned as part of plugins. Is there a way to exclude them? I am using the following command?
One such plugin in pom.xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.1.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
</execution>
</executions>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
</plugin>
mvn clean dependency:copy-dependencies -DincludeScope=runtime -Dmdep.skip=true
-Dsilent=true
The objective is to copy only the jars and transitive jars shipped in a spring boot jar. Are there any alternate ways to do this?

Use dependency command line parameters with maven build

I am using findbugs-maven-plugin in the verify phase of the maven life cycle. i.e. it runs on mvn clean install. This is the code I have in my parent pom.xml (in a multi-module project).
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>findbugs</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<findbugsXmlOutputDirectory>target/findbugs</findbugsXmlOutputDirectory>
<failOnError>false</failOnError>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>target/findbugs</dir>
<outputDir>target/findbugs</outputDir>
<stylesheet>plain.xsl</stylesheet>
<fileMappers>
<fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
<targetExtension>.html</targetExtension>
</fileMapper>
</fileMappers>
</transformationSet>
</transformationSets>
</configuration>
<dependencies>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
</plugin>
This is working fine and html files are being generated in each module target. However I want to take this a step further by being able to use parameters allowed by findbugs during the maven build (for example onlyAnalyze). I do not want to add configuration in the pom.xml.
I want the build process to remain the same unless I specify by some command that I want to analyze only one class, for example by running:
mvn clean install -Dfindbugs:onlyAnalyze=MyClass
Do you know of a way I can do this?
This is how you can call a standalone goal:
plugin-prefix:goal or groupId:artifactId:version:goal to ensure the right version.
In your case: findbugs:findbugs
With -Dkey=value you can set plugin parameters if they are exposed. http://mojo.codehaus.org/findbugs-maven-plugin/findbugs-mojo.html doesn't show that option. Just to compare: http://mojo.codehaus.org/findbugs-maven-plugin/help-mojo.html does have such options. Here it is still called Expression with ${key}, nowadays it's generated as User property with just key.
If you want onlyAnalyze to be set from commandline, either ask the mojo-team to fix that, or do the following:
<project>
<properties>
<findbugs.onlyAnalyze>false</findbugs.onlyAnalyze> <!-- default value -->
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<configuration>
<onlyAnalyze>${findbugs.onlyAnalyze}</onlyAnalyze>
</configuration>
</plugins>
</build>
</project>
Now you can call mvn findbugs:findbugs -Dfindbugs.onlyAnalyze=true

exec-maven-plugin doesn't use third-party repos

I have a couple of third-party repos configured. I know they're configured correctly because it's downloading artifacts from them. But exec-maven-plugin doesn't seem to recognize those third-party repos. It looks for its dependency in Maven Central and then tells me the POM doesn't exist there. Of course it doesn't; it's in the third party repo! Do I need to do something special to tell exec-maven-plugin to use the third-party repo?
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>emulation</id>
<phase>generate-sources</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>krum.jplex.JPlex</mainClass>
<arguments>
<argument>${basedir}/src/main/jplex/EmulationLexer.jplex</argument>
<argument>${project.build.directory}/generated-sources/jplex</argument>
<argument>${project.build.directory}/generated-resources/jplex</argument>
</arguments>
<sourceRoot>${project.build.directory}/generated-sources/jplex</sourceRoot>
<includePluginDependencies>true</includePluginDependencies>
<classpathScope>compile</classpathScope>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.chalcodes.jplex</groupId>
<artifactId>JPlex</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
</plugin>
A reading of Using Plugin Dependencies instead of Project Dependencies, indicates you will need to specify the following (in addition to what you have)
<configuration>
<includeProjectDependencies>false</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<executableDependency>
<groupId>com.chalcodes.jplex</groupId>
<artifactId>1.2.1</artifactId>
</executableDependency>
...
</configuration

remove jar created by default in maven

I am using maven assembly plugin. in my pom.xml, pakaging type: jar and i dont use maven jar plugin.
Whenever i run mvn clean package, it create 2 jar files: one is from maven assembly, another one is created by default (due to packaging type =jar). I want to keep only the jar file created by assembly plugin only. How to do that?
You may have your reasons but I doubt that it is a good solution to skip the default jar being built and deployed.
Anyhow here is how you can disable the default jar being built.
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<id>make-assembly</id>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- some configuration of yours... -->
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<!-- put the default-jar in the none phase to skip it from being created -->
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>

maven exec:java run class file within jar

I have my code packaged into a jar
The jar is packaged ok.
jar -tfv target/test-1.0-SNAPSHOT.jar
com/
com/codevalid/
com/codevalid/App.class
log4j.xml
META-INF/maven/com.codevalid/test/pom.xml
META-INF/maven/com.codevalid/test/pom.properties
I can execute them when they are present as individual class files using exec:java
How to run class file within jar using maven exec:java?
Ok, this is what i finally ended up doing.
I built the jar using
mvn assembly:single
and used
java -jar ./target/App-1.0-SNAPSHOT-jar-with-dependencies.jar com.codevalid.App
I did see an alternative where i could have used
mvn exec:java -Dexec.mainClass="com.codevalid.App"
But i was not sure how pass the name of the jar as a classpath
You can run a jar file using the exec:java goal by adding some arguments:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<mainClass>org.example.Main</mainClass>
<arguments>
<argument>-jar</argument>
<argument>target/myJar-1.0-SNAPSHOT.jar</argument>
</arguments>
</configuration>
</plugin>
If you have an executable jar and don't want to define the entry point, you need to set the executable and use the exec:exec goal:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<executable>java</executable>
<arguments>
<argument>-jar</argument>
<argument>target/myJar-1.0-SNAPSHOT.jar</argument>
</arguments>
</configuration>
</plugin>
You need to include your jar file as a dependency to the exec plugin, e.g. like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.codevalid.App</mainClass>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>myGroup</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
You can skip the dependency declaration if the com.codevalid.App class is compiled as part of your current project.
You have to specify classpathScope and includePluginDependencies or includeProjectDependencies parameters to pickup jar files on the classpath.
Here is an example:
<configuration>
<executable>java</executable>
<mainClass>com.google.jstestdriver.JsTestDriver</mainClass>
<classpathScope>test</classpathScope>
<includePluginDependencies>true</includePluginDependencies>
<includeProjectDependencies>true</includeProjectDependencies>
<commandlineArgs>--port 9876</commandlineArgs>
</configuration>

Resources