My project is consisted of two modules, one is common, the other let's call it X.
When using maven to "clean install" module X, it complained:
You have 50 Checkstyle violations.
Looking into the pom.xml I didn't see any checkstyle maven plugin, but in the "common" module I did find it in "common"'s pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.9.1</version>
</plugin>
Since module X depends on module "common", I updated common's checkstyle plugin in pom.xml like this:
<configuration>
<skip>true</skip>
</configuration>
and rebuilt the common module before I ran the "clean install" on X module.
To play safe, I added one more setting on the mvn command when running X module:
mvn clean install -DskipTests -Dcheckstyle.skip
However, it looks that neitherthe change in "common"'s pom.xml w.r.t checkstyle plugin nor the additional setting on mvn command had any effect on the running - it still complained the same.
I tried with, pluginManagment and it works fine. You need to add this in your parent pom file.
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</pluginManagement>
It turned out that there are two places in the pom.xml that involve checkstyle plugin: one is under the tag
<pluginManagement>
, in which I added:
<skip>true</skip>
However it's not sufficient (at least in my case), I found the checkstyle was also registered under:
<build><plugins>
it looks like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>6.1.1</version>
</dependency>
</dependencies>
<configuration>
<skip>true</skip>
....
</configuration>
<plugin>
Now after I added skip being true to both places and rebuilt the project modules, the errors were gone.
I have a Spring Boot application and I have created a Jar out of that. Following is my pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- WebJars -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
I want to use this Jar in my other application so added this jar to my application. But when I am calling a method in that Jar, it is throwing a ClassNotFoundException.
How can I fix this issue? How can I add a dependency to a Spring Boot JAR?
By default, Spring Boot repackages your JAR into an executable JAR, and it does that by putting all of your classes inside BOOT-INF/classes, and all of the dependent libraries inside BOOT-INF/lib. The consequence of creating this fat JAR is that you can no longer use it as a dependency for other projects.
From Custom repackage classifier:
By default, the repackage goal will replace the original artifact with the repackaged one. That's a sane behaviour for modules that represent an app but if your module is used as a dependency of another module, you need to provide a classifier for the repackaged one.
The reason for that is that application classes are packaged in BOOT-INF/classes so that the dependent module cannot load a repackaged jar's classes.
If you want to keep the original main artifact in order to use it as a dependency, you can add a classifier in the repackage goal configuration:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.1.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
With this configuration, the Spring Boot Maven Plugin will create 2 JARs: the main one will be the same as a usual Maven project, while the second one will have the classifier appended and be the executable JAR.
Tunaki's answer is correct but doesn't work in Spring Boot 2.
Spring Boot 1.x
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.20.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
...
</plugin>
Read more
Spring Boot 2.x
If you are using spring-boot-starter-parent, the repackage goal is executed automatically in an execution with id repackage. In that setup, only the configuration should be specified as shown in the following example:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
...
</plugin>
Read more
For Spring Boot 2 #Tunaki's answer must be modified a bit according to the documentation if spring-boot-starter-parent is used as parent :
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
Take note of the extra <id>repackage</id> necessary to overwrite to execution from the spring-boot-starter-parent.
if you want to use the spring-boot project as a dependency and same time want to run as a spring-boot jar then use the below configuration. by the below configuration, you can achieve two goals.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build information</id>
<goals>
<goal>build-info</goal>
</goals>
</execution>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
This configuration creates two jars as shown below example screenshot:
What #Tunaki stated was mostly correct but the one missing part based on your original question was:
This throwing ClassNotFoundException. The External jar's used in
spring boot application is missing.
This is due to the fact that the FatJAR created from the maven packaging has the dependent libraries specified in a specific location that works for how Spring Boot executes the application. If you are just adding the JAR to another application's classpath then you should do what #Tunaki said and also include the dependent JAR files to the classpath. The best way to work with this is to use the Maven Dependency Plugin specifically targetting the dependency:copy-dependencies mojo to download all the dependencies into a folder that you can then specify as a library path when compiling the other application.
You can extend your project by maven-assembly-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
After the build you will get 3 jars. The main one will be the same as a usual Maven project, while the second one will have the classifier appended with exec and be the executable JAR. The third jar name will be appended by jar-with-dependencies and will contain your classes with classes added as dependencies in your spring boot application(spring-boot-starter-web, thymeleaf,...), so into the pom of the application where you want to add that project as dependencie you won't have to add dependencies from spring boot project.
Use the build section provided below, it will do three things:
Create the spring boot jar using spring-boot-maven-plugin
Create a normal jar with your source code compiled classes using maven-assembly-plugin
Install the normal jar into the m2 folder locally
If you want to deploy the normal jar into a remote repository, configure the deploy plugin
<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">
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>true</appendAssemblyId>
<descriptors>
<descriptor>src/main/resources/sources-jar-build.xml</descriptor>
</descriptors>
<finalName>${pom.artifactId}-${pom.version}</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-file</id>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>${pom.artifactId}-${pom.version}</file>
<artifactId>${pom.artifactId}</artifactId>
<groupId>${pom.groupId}</groupId>
<version>${pom.version}</version>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Place the below content in a file named "sources-jar-build.xml", into resources folder:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>sources</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>jar</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}/target/classes</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>
use below plugin for spring boot version 2.*
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.1.RELEASE</version>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
All existing answers are made under the assumption that the Spring Boot project upon which another project should depend is an application, which is fair enough since the question is phrased like that.
But if the underlying project is meant to be used as a library only, i.e. it contains no (sensible) Main class, there is obviously no executable code that needs to be repackaged at all.
So in that case, it makes more sense to skip the repackaging entirely like this:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
I used version 2.2.5 and it's working. add it to your pom.xml
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.5.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
You can setup your projects so that the batch launcher relies on a jar, which would be shared with your other application.
Said differently, as per your initial request :
I want to use this Jar in my other application so added this jar to my application.
Let's say your jar is your project A, and your application is your project B.
Now, what I suggest, is that you remove the launching part from A ;
then you put it into a new project C, that would embed Spring Boot, and that would rely almost totally on A.
Then, since A is now a simple jar, B can use it as a dependency.
any project if you want add as a dependency you need that project <groupId>,<artifactId>,<version>, with these details you can add your project as a dependency in another module or application
for ex: your application pom details
<project
<groupId>com.sample</groupId>
<artifactId>sampleapp</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
</project>`
your dependency as like below
<dependency>
<groupId>com.sample</groupId>
<artifactId>sampleapp</artifactId>
<version>1.0</version>
</dependency>
I have a project that contains some tests, all it does is create a test-jar to be run by other projects. And it depends on a another artifact, let's call it artifact X
then there are multiple other projects that run the test-jar, using the maven-surefire-plugin
I have multiple implementations of artifact X and what I want to do is to be able to run those tests using the implementation that I want, not X
so for example:
in project A I want to run the tests using implementation A
in project B I want to run the tests using implementation B
this does not seems to be possible, because once the test-jar generated, it has the artifact X hard-coded in it
so I'm open to any other solutions
Edit :
extra information:
the pom file of the project generating the tests :
the part for generating the test-jar
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
the Artifact X dependency :
<dependency>
<groupId>com.conztanz</groupId>
<artifactId>X</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
the pom file of one of the projects running the tests (project A):
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.15</version>
<configuration>
<dependenciesToScan>
<dependency>testJar</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
Ideally what I want is do some thing that tells project A to Override artifact X with it's own implementation
I hope this makes more sense now
I think you're looking for the scope called provided.
The dependency would look like this:
<dependency>
<groupId>com.conztanz</groupId>
<artifactId>X</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
This tells Maven: "Hey, I need this to compile, but don't include it in the target output, because a container (or something) will provide the jar itself."
I am attempting to build a full site for my multi-module project in one command that I can execute in Jenkins. However when I build it, the submodule javadocs appear in the site root (site/apidocs instead of site/submodule/apidocs). All the links from the parent to submodule are broken as well.
Organization is the standard
pom.xml
submodule/pom.xml
Parent POM contains:
<build>
<pluginManagement>
<plugins>
... Various unrelated plugins ...
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>complete-build</id>
<build>
<plugins>
<!--JavaDoc setup for Jars-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<defaultAuthor>Leon Blakey</defaultAuthor>
<defaultVersion>${project.version}</defaultVersion>
<sourcepath>target/delombok</sourcepath>
</configuration>
</plugin>
<!--Deploy site with Mercurial (Hg)-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
<dependencies>
<dependency><!-- add support for scm -->
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-scm</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-hg</artifactId>
<version>1.8.1</version>
</dependency>
</dependencies>
<configuration>
<reportPlugins>
<!--JavaDoc setup for Site-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<defaultAuthor>Leon Blakey</defaultAuthor>
<defaultVersion>${project.version}</defaultVersion>
<sourcepath>target/delombok</sourcepath>
<show>public</show>
</configuration>
</plugin>
... Checkstyle, PMD, Findbugs, etc ...
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The submodule POM just contains the skeleton plugin definitions for pluginManagement.
When I try to build a site (both on my local machine and Jenkins) I run from the parent
mvn clean install site-deploy -Pcomplete-build
With the above setup, what would cause a submodule to dump its site files in the site root (site/) instead of the submodule directory (site/submodule)? Do I need to use the stanging commands (which I'm avoiding since it breaks the release process)? Is it simply impossible to build a multi-module site in one command?
Use the maven-reactor-plugin to trigger building at the submodule level.
I am setting up a Maven repository with the goal of automating much of my build and deploy process. My current workflow begins with bringing up a server, doing a git clone, and running a bunch of mvn install commands to complete the top level application.
To my understanding, Maven is not a tool for deploying applications, and at this point I do not see a need for a continuous integration or continuous deployment server or formal process.
However, thus far I have not been able to find a canonical way to put together the complete, runnable program together with Maven.
This script goes so far as to get the top level jar and install it into the local maven repo:
mvn -DgroupId=me.company -DartifactId=Top-Level-Application -Dversion=1.0-SNAPSHOT -DrepoUrl='http://theserver:8081/nexus/' dependency:get
If I installed everything manually, this application would find all of its dependent jars in a lib/ directory, as Maven ought to do. However this jar as pulled is not deployable - while the dependent jars are installed to a local repo they are not compiled where the classpath expects it.
I imagine if I could rig the above script to pull the pom.xml instead of just the jar and run a mvn install on that, everything would go smoothly (although weirdly that seems to be duplicating the last step of the build process). Another option is for applications to contain all dependent jars rolled up into one giant jar and have no external dependencies.
Which of these (or other) options is the proper way to complete the Maven build process?
Here is our top-level pom narrowed down to as much as I can think would be relevant:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>me.company</groupId>
<artifactId>Top-Level-Application</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>Top Level Application</name>
<url>http://company.me</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<distributionManagement>
<repository>
<id>releases</id>
<url>http://host:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Internal Snapshots</name>
<url>http://host:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>me.company.application.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>me.company</groupId>
<artifactId>First-Library</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- more in-house libraries -->
<!-- third party libraries - Apache Commons, javamail, etc. -->
</dependencies>
</project>
Correct me if I'm wrong -- you want to transform your source code into a compiled JAR, with appropriately-set classpath for its dependencies? That's not what dependency:get is for at all. You should look into the Maven JAR plugin and/or the Maven AppAssembler plugin.