Spring-Boot External lib folder with Maven - maven

I need externalize my application's dependencies. I want to achieve the following layout for my Spring Boot Application
.
├── *.properties
├── static
├── main.jar
└── lib
└── *.jar
Where lib folder contains my dependencies.
I try with the maven-jar-plugin and spring-boot-maven-plugin but I get the following error:
Could not find or load main class com.Application
My pom.xml
<profile>
<id>dist</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<finalName>alfred</finalName>
<excludes>
<exclude>src/main/resources/*</exclude>
<exclude>*.properties</exclude>
<exclude>*.html</exclude>
<exclude>**/assembly/*</exclude>
<exclude>**/lib/*</exclude>
<exclude>**/static/*</exclude>
<exclude>**/templates/*</exclude>
</excludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<Main-Class>com.Application</Main-Class>
</manifest>
<manifestEntries>
<Class-Path>./alfred_lib/**</Class-Path>
<Class-Path>./**</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.2.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-1</version>
<configuration>
<descriptor>src/main/resources/assembly/dist.xml</descriptor>
<finalName>alfred</finalName>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
My src/main/resources/assembly/dist.xml:
<assembly>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>src/main/resources/assembly</directory>
<outputDirectory></outputDirectory>
<includes>
<include>**.sh</include>
</includes>
<fileMode>0755</fileMode>
</fileSet>
<!-- Estáticos -->
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory></outputDirectory>
<excludes>
<exclude>lib/**</exclude>
<exclude>assembly/**</exclude>
</excludes>
</fileSet>
<!-- Aplicación -->
<fileSet>
<directory>target</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
<!-- Dependencias -->
<dependencySets>
<dependencySet>
<outputDirectory>alfred_lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
I've been reading for several days and I have discarded:
Using spring-boot-thin-layout
Create far jar: It's a project requirement.

Related

copy the content of a directory of maven module project into another module

I want to copy the content of a directorymodule maven project.
Here is the hierarchy
I want to copy the content of dist directory into Tourism/Tourism-Services/src/main/webapp directory
For this purpose, I tried to use maven-assembly-plugin
here is the extract of the relative pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>./</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>cfg-main-resources</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>${basedir}/src/main/angular5/tourism/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
Here is the extract of assembly.xml file
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>distribution</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<outputDirectory>./</outputDirectory>
<directory>src/main/angular5/tourism/dist</directory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
The problem is that the content of dist directory is copied in Tourism/Tourism-Web/target directory. I would like to copy this content in another module, in Tourism/Tourism-Services/src/main/weapp directory. Thank you for your help
I succeded in configuring the pom.xml's
Here is an extract of pom.xml within Tourism-Web sub-module
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>true</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>cfg-main-resources</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>${basedir}/src/main/angular5/tourism/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
Here is an extract of assembly descriptor file
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>assembly</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<outputDirectory>./</outputDirectory>
<directory>src/main/angular5/tourism/dist</directory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
Here is an extract of pom.xml of Tourism-Services sub-module
<dependencies>
<dependency>
<groupId>tourism-guide</groupId>
<artifactId>tourism-web</artifactId>
<version>${project.version}</version>
<classifier>assembly</classifier>
<type>zip</type>
<scope>compile</scope>
</dependency>
..................
's..................
</dependencies>
<build>
<!-- Set the name of the war, used as the context root when the app is
deployed -->
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-angular-dist-resources</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>compile</phase>
<configuration>
<outputDirectory>${basedir}/src/main/webapp</outputDirectory>
<includeArtifactIds>tourism-web</includeArtifactIds>
<includeGroupIds>${project.groupId}</includeGroupIds>
<excludeTransitive>true</excludeTransitive>
<excludeTypes>pom</excludeTypes>
<scope>compile</scope>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Thank you for reading

Generate several war for spring boot application

It seems that spring boot will repackage the package generated by maven package phase, and then repacke the war to make it executable.
Now I want to genrate multiple wars for different environments by a single maven command, I tried to use maven-assembly-plugin:
1 unzip the war generated by `spring-boot-maven` plugin to a directory
2 Assembly with the files in the directory, and add some other filtered resources
3 create the war
Check this post:generate multiple artifacts in maven
While it works, and I got multiple wars, but none of them can be executeable by java -jar xx.war. It seems that the classes are corrupted.
So I wonder if there is an alternative solution?
update my pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/as-common</source>
<source>src/main/as-server</source>
<source>src/main/as-app</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<!-- unzip the contents of the war(executeable) generated by spring-boot to a certain directory -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>extract_spring_war</id>
<phase>package</phase>
<configuration>
<target>
<echo message="extract war generated by spring-boot-maven-plugin"/>
<delete dir="${basedir}/target/${project.build.finalName}-spring" includeemptydirs="true"/>
<unzip src="${basedir}/target/${project.build.finalName}.war" dest="${basedir}/target/${project.build.finalName}-spring/"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>iterator-maven-plugin</artifactId>
<version>0.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>iterator</goal>
</goals>
<configuration>
<items>
<item>test</item>
<item>dep1</item>
<item>dep2</item>
</items>
<pluginExecutors>
<pluginExecutor>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
</plugin>
<goal>single</goal>
<configuration>
<archive>
<manifest>
<mainClass>org.springframework.boot.loader.WarLauncher</mainClass>
</manifest>
</archive>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</pluginExecutor>
</pluginExecutors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
assmbly.xml:
<assembly>
<id>${item}</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<!-- file from the unpacked contents -->
<fileSet>
<directory>target/${project.build.finalName}-spring</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
<filtered>true</filtered>
</fileSet>
<!-- add environment awared resources -->
<fileSet>
<outputDirectory>/WEB-INF/classes</outputDirectory>
<directory>${basedir}/src/main/custom/</directory>
<includes>
<include>${item}.properties</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Update:
At first I got the error:
No main class detected
Then I add the following for maven-assembly-plugin,
<archive>
<manifest>
<mainClass>org.springframework.boot.loader.WarLauncher</mainClass>
</manifest>
</archive>
After that I repackage the wars, and I got error when I ran:
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 4022320623 in class file org/springframework/boot/loader/WarLauncher
The class files are being corrupted when you're repackaging the war file. I suspect that's because you're filtering all of the files:
<fileSet>
<directory>target/${project.build.finalName}-spring</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
<filtered>true</filtered>
</fileSet>
You don't want to filter binary files as they may happen to contain data that looks like a ${} placeholder. You should update the assembly to avoid applying the filtering to class files. The simplest way to do that would be to disable filtering entirely:
<fileSet>
<directory>target/${project.build.finalName}-spring</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
<filtered>false</filtered>
</fileSet>
If you need filtering for text files, you should use two fileSets. One that includes the binary files and disables filtering, and one that includes the text files and enables filtering.

Assembly ID is getting appended when zip file is created by maven

xml and pom.xml which creates jar file and then zip file with some artifacts including jar file. But when i run maven install zip file is getting created as GenerateMissingUsersReport-bin.zip instead I want it to create as GenerateMissingUsersReport.zip. I have set as false. But no difference.
Any pointers?
Here is dep.xml
<id>bin</id>
<baseDirectory>../</baseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/classes</directory>
<includes>
<include>plugin.xml</include>
</includes>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
Here is pom.xml
<finalName>GenerateMissingUsersReport</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<finalName>GenerateMissingUsersReport</finalName>
<appendAssemblyID>false</appendAssemblyID>
<descriptor>src/assembly/dep.xml</descriptor>
</configuration>
<executions>
<execution>
<id>make-zip</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>plugin.xml</exclude>
</excludes></configuration>
</plugin>
Add the following line under configurations element of the pom
<appendAssemblyId>false</appendAssemblyId>
Also make sure you use the latest version of the assembly plugin
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>

I wish to exclude some class files from my jar. I am using maven-assembly-plugin. It still adds the files. I dont get any error

I dont get any error with this code. Just that the file that I want to exclude still gets added. I am using the maven plugin for eclipse
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>only</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>com.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<excludes>
<exclude>**/com/uiservices/controllers/*.* </exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
The maven-assembly-plugin doesn't work like that.
There what you want to do is override the configuration of the assembly descriptor jar-with-dependencies and that's not possible.
If what you want to do is create a jar similar to the one created by the assembly jar-with-dependencies but without some specific classes of your own project, you have to write your own assembly and call it in the maven-assembly-plugin like what follows.
Assembly in src/assembly/jar-with-deps-with-exclude.xml :
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<!-- TODO: a jarjar format would be better -->
<id>jar-with-dependencies-and-exclude-classes</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>${project.build.outputDirectory}</directory>
<excludes>
<exclude>com/uiservices/controllers/*.*</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
This will create an assembly with no the dependencies unpacked and with your classes added except the ones excluded.
And then in your pom.xml :
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>only</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assembly/jar-with-deps-with-exclude.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
But if what you need is your classical jar without excluded classes, you can exclude them in the maven-jar-plugin directly :
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>com/uiservices/controllers/*.*</exclude>
</excludes>
</configuration>
</plugin>
I had a similar issue with maven-assembly-plugin:
Project beans-conversion has files application.properties,
logback.xml, and logback.xsd
Project extract-conversion has also files called application.properties, logback.xml, and logback.xsd
Requirement is extract-conversion.jar should include beans-conversion.jar content but application.properties, logback.xml, and logback.xsd of extract-conversion.jar should override the beans-conversion.jar.
Solution:
We solved this using maven-shade-plugin as below in extract-conversion's pom.xml.
...
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>beans-conversion</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
...
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>application.properties</include>
<include>logback.xml</include>
<include>logback.xsd</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<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>
<filters>
<filter>
<artifact>com.mycompany:beans-conversion</artifact>
<excludes>
<exclude>application.properties</exclude>
<exclude>logback.xml</exclude>
<exclude>logback.xsd</exclude>
</excludes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
using maven-shade-plugin
ref: Maven dependency: exclude one class
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.artifactId}-jar-with-dependencies</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.taobao.arthas.core.Arthas</Main-Class>
</manifestEntries>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:termd-core</artifact>
<excludes>
<exclude>META-INF/services/io.termd.core.spi.ConfigProvider</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>

Maven Assembly Create Custom Format

As part of a bigger project, I want to package some items I download together with some jar files as a .tar.gz package. And I did that successfully.
But now I want to "rename" that .tar.gz to something custom (e.a. to mypackage.banana)
Is there an easy way to achieve this?
What I have so far id accomplished using https://github.com/maven-download-plugin/maven-download-plugin
<build>
<plugins>
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>${some.jar.file.url}</url>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<url>${some.models.zip.url}</url>
<unpack>true</unpack>
<outputDirectory>${project.build.directory}/data</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version> <!-- Old -->
<executions>
<execution> <!-- Build tar.gz archive. -->
<id>tar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/tar.xml</descriptor>
</descriptors>
<finalName>project-${project.version}-el6</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution> <!-- /NewStuff -->
</executions>
</plugin>
</plugins>
</build>
using tar.xml:
<assembly>
<id>tar</id>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>target/data</directory>
<outputDirectory>/data</outputDirectory>
</fileSet>
<fileSet>
<directory>target/lib</directory>
<outputDirectory>/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>meta</directory>
<outputDirectory>/meta</outputDirectory>
</fileSet>
</fileSets>

Resources