Spliting version number from dependency jar using spring-boot-maven-plugin? - java

I am using spring-boot-maven-plugin for creating a fat jar of my project, How can I split version number from the dependency jars getting created inside Boot-Inf/lib. As per my requirement I don't want version to be appended. I tried with maven-dependency-plugin that is working fine, but I need solution with sprint-boot-maven-plugin. Please suggest!!.

You can specify the artifact-name with the maven boot plugin:
In this case, it will be NewJarName.jar
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<finalName>NewJarName</finalName>
</configuration>
</execution>
</executions>
</plugin>

Related

Skip default jar creation in maven causes error

Im using maven 3.8.3. Tryig to avoid the step of the default jar creation, using the answers I found in topics like:
remove jar created by default in maven
What is the best way to avoid maven-jar?
What I tried:
1.
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.3</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.3</version>
<executions>
<execution>
<id>default-jar</id>
<phase/>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
<configuration>
<finalName>unwanted</finalName>
<classifier>unwanted</classifier>
</configuration>
</execution>
</executions>
</plugin>
I also checked the solution of <packaging>pom</packaging> instead of jar. but I'm not sure this is the use case.
More details: This is a non-empty module, containing resources and generated unversioned java sources.
Solutins #1-#3 caused me the following error:
The packaging for this project did not assign a file to the build artifact.
Please assist, Thanks in advance.

Maven pom plugin not executing on build

I'm practicing Maven and I've hit a wall. I've installed the PlantUml plugin on IntelliJ and I'm trying to set it up so that it always generates a new image from the source file on compile time. I'm using this plugin to generate the image, and I've configured the pom.xml file as follows:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.github.jeluard</groupId>
<artifactId>plantuml-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>GeneratePlantUml</id>
<phase>generate-resources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/images</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
<sourceFiles>
<directory>${basedir}/plantuml</directory>
<includes>
<include>TestGeneratorDiagram.puml</include>
</includes>
</sourceFiles>
<outputDirectory>${basedir}/images</outputDirectory>
</configuration>
<dependencies>
<dependency>
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>8031</version>
</dependency>
</dependencies>
</plugin>
<plugins>
</pluginManagement>
<build>
This works fine when I use a terminal command where I specify the goal:
mvn compile com.github.jeluard:plantuml-maven-plugin:generate
However, it doesn't work if I just write:
mvn compile
Which, as far as I know, should also work. I've tried setting the phase on compile but it didn't change anything. I've searched for hours now for a solution but I haven't found one. Does anyone know how I can force the plugin to generate a new image on compile time by configuring the pom?
You have put your configuration into pluginManagement. You needs to put it into plugins (outside pluginManagement).
The pluginManagement is just to override/specify configuration and version numbers.
Have a look at Maven: What is pluginManagement?
your plugin and your execution is configure à the "generate-resources" phase and not at the compile phase like you want.
See this link to more detail on phase.
change this:
<execution>
<id>GeneratePlantUml</id>
<phase>generate-resources</phase>
<goals>
<goal>generate</goal>
</goals>
to this
<execution>
<id>GeneratePlantUml</id>
<phase>compile</phase>
<goals>
<goal>generate</goal>
</goals>
It must works.

how to make single jar file with including all other jar libraries in dist folder

I have created a application. In this application I have doubt that when getting output I need to include lib (library folder which includes all supporting jar files) but I need in a single jar files which must be include all supporting jars. Is it possible? I am using Netbeans.
You don't tell us what you are using to build your code. I'm going to guess at maven (because I know the answer is in Maven!). What you need is:
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- Add your other plug-ins here -->
</plugins>
</build>

jsonschema2pojo maven plugin configuration in execution not considered

I am trying to use the jsonschema2pojo plugin for generating POJOs based on both schema and json sourceTypes. The configurations are specified per execution. But every time the plugin is reporting "One of sourceDirectory or sourcePaths must be provided". I am able to run it when the configuration is provided at the plugin level ( global ). But then I can only specify one sourceType.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>0.5.1</version>
<executions>
<execution>
<id>generate-schema</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<outputEncoding>${project.build.sourceEncoding}</outputEncoding>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<annotationStyle>jackson2</annotationStyle>
<generateBuilders>false</generateBuilders>
<initializeCollections>true</initializeCollections>
<refFragmentPathDelimiters>#/</refFragmentPathDelimiters>
<sourceType>jsonschema</sourceType>
<targetPackage>com.company.app.integration.sabre.stub.rest</targetPackage>
<sourceDirectory>${basedir}/src/main/resources/schema</sourceDirectory>
</configuration>
</execution>
<execution>
<id>generate-json</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<outputEncoding>${project.build.sourceEncoding}</outputEncoding>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<annotationStyle>jackson2</annotationStyle>
<generateBuilders>false</generateBuilders>
<initializeCollections>true</initializeCollections>
<refFragmentPathDelimiters>#/</refFragmentPathDelimiters>
<sourceType>json</sourceType>
<targetPackage>com.company.app.integration.sabre.stub.rest</targetPackage>
<sourceDirectory>${basedir}/src/main/resources/json</sourceDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Is there any way to have the plugin use the configuration at execution level per goal ?
Plugin version: 0.5.1
tl;dr
When running the 'compile' from Maven projects lifecycle, the plugin is considering the configuration from execution and is working as expected.
I am using Intellij and was trying to generate the pojo from Plugins -> jsonschema2pojo -> jsonschema2pojo:generate under 'Maven Projects' window. This was giving the above error and was not taking the configuration per execution.
When I run compile from the Maven Lifecycle, it is picking the configuration in the execution and is generating the files as specified.
I am not yet sure if this is a issue with the plugin or maven or if its a issue at all !!
Try moving your configuration out to the plugin level and using the parent folder (${baseDir}/src/main/resources) as the sourceDirectory.
Here's an old bug report describing the same thing:
https://github.com/joelittlejohn/jsonschema2pojo/issues/145

Spring Boot Maven Plugin - No BOOT-INF directory

Between version 1.3.8.RELEASE of the spring-boot-maven-plugin and version 1.4.0.RELEASE - there has been a change in the generated package structure (if you extract the uber jar file)
1.3.8.RELEASE com, lib, META-INF and org directories
1.4.0.RELEASE has a BOOT-INF, META-INF and org directories
Basically from 1.4.0.RELEASE onwards - all the classes and libs are in the BOOT-INF directory.
Due to this - when you try to run a Spring Boot project on Amazon Lambda - it says that there is a jar not found as it cannot read the new Spring Boot Uber jar structure
My question is - is it possible in the newer versions of the Spring Boot Maven Plugin to get it to generate the uber jar to be the same structure as in version 1.3.9.RELEASE?
I tried the maven-shade-plugin - but that leads to other issues
Any help is greatly appreciated
Thanks
Damien
The solution was to add the MODULE layout for the plugin in the pom.xml file
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layout>MODULE</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
In my case I'm using spring boot 2.X and I declared the spring-boot-maven-plugin after the maven-dependency-plugin (which I used to unpack and create exploded app in Docker) and it must be before the unpack, makes sense, it was unpacking before the spring boot maven plugin executed. Next time I'll declare it first thing in the plugin chain, lost more than 1 hour on this. Hope it helps someone.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${spring.boot.mainClass}</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The answer above with
<layout>MODULE</layout>
does not work anymore, this is because layout element is deprecated in Spring Boot 2.x.
I am using Spring Boot 2.0.x, I found this helpful comment on github:
Support for the module layout was removed in Spring Boot 2.0 having been deprecated in 1.5. Unfortunately, the updates to the Maven Plugin's documentation were missed so we can use this issue to sort that out. You should use a custom LayoutFactory instead.
But as I did not want to implement LayoutFactory I tried this second solution below that actually repackage and creates an extra jar with a classifier given name:
This is due to the change in layout of executable jars in Spring Boot 1.4. Application classes are now packaging in BOOT-INF/classes.
Your client module depends on the repackaged, fat jar of your web module. Due to the new layout that means that the client module can no longer load the web module's classes. If you want to use your web module as a dependency, you should configure Boot's repackaging to apply a classifier to the fat jar. For example:
<build>
<plugins>
<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>
</plugins>
</build>
Doing so will allow other modules to depend on the original jar that does not embed the module's dependencies and has the classes at the root of the jar.
One original jar have the same structure as I wanted like
com.my-package.foo.bar
META-INF
and the second classifier have the newer structure with BOOT-INF/ etc.
For me, the solution was a bit more insidious....I had the spring-boot-maven-plugin nested under pluginManagement, (see below). Doh!
The nasty thing, is that when I'd run mvn spring-boot:run, spring boot comes up just fine, and runs app! It wasn't until we tried to deploy to PCF (as a spring-boot JAR), that we'd get an error that there was something wrong with format of the binary....
<build>
<!--
DON'T DO THIS!!
-->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<!--
DO THIS INSTEAD!!
-->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Once I removed the pluginManagement tags from the POM, I would now get the ./BOOT-INF structure. Please keep in mind that pluginManagement is typically for a parent-pom structure, where you want that plugin's config used across other modules.
I was using Gradle, instead of Maven, and this is what I had to do:
1- In my build.gradle, I added the following properties as defined in https://spring.io/guides/gs/spring-boot-Docker/.
buildscript {
...
dependencies {
...
classpath('gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.13.0')
}
}
group = 'springio'
...
apply plugin: 'com.palantir.docker'
task unpack(type: Copy) {
dependsOn bootJar
from(zipTree(tasks.bootJar.outputs.files.singleFile))
into("build/dependency")
}
docker {
name "${project.group}/${bootJar.baseName}"
copySpec.from(tasks.unpack.outputs).into("dependency")
buildArgs(['DEPENDENCY': "dependency"])
}
2- My dependency folder was not being written to
ARG DEPENDENCY=target/dependency
instead, I located it in another folder, so I changed this property in the Dockerfile:
ARG DEPENDENCY=build/dependency
With this I got a successful build.

Categories

Resources