How to add executable file in resources folder in Spring Boot - java

Requirement: To use an executable file within my resources folder
Limitation: I need to have that executable file within the resources folder, that is, I cannot have the executable file be present on the server from before
Scenario: When I am adding the executable file in the resources folder and then I am building the project using mvn clean install, then I have the following target folder structure.
target -> classes -> myExecutableFile
Problem: myExecutableFile present inside the target folder does not have executable permissions. Is there any way I can retain the executable permission for the file?

You could do this via Ant by doing something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>process-resources</id>
<phase>process-resources</phase>
<configuration>
<target>
<chmod file="target/script.sh" perm="755"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

Related

Copy resulting fat jar to another target folder in Spring boot project

I have Spring boot project. Everything is built OK in /target folder but I'd like to change destination folder.
I tried to use maven-jar-plugin as described below but it copies only jar with compiled classes of project (small jar).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<outputDirectory>${maven.multiModuleProjectDirectory}/output/bin</outputDirectory>
</configuration>
</plugin>
Instead I want to make Maven to copy FAT jar.
Maven builds FAT jar and puts the Jar to /target folder. How to change destination?
UPDATE 1
this is needed by project requirements - need to build folder structure with properties, bash scripts(as entry point) and fat jar:
Try to add this plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
<outputDirectory>${maven.multiModuleProjectDirectory}/output/bin</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

Put libraries for spring boot application in extra lib dir

I am currently building my spring boot application as a fat jar. But because I am also building a docker image from these, I have to pull the jar with all its dependencies every time I change some of my code. So my question is: How would I have to change my gradle files to get a task called 'buildWithExternalLibs' that has all dependencies in a lib folder, but can still be started using java -jar ... as long as the lib folder is right next to the jar?
I have done it in maven project. You can use same logic in gradle too.
When you will clean install, it will copy your jar file too.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<id>install-jar-lib</id>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>com.***.*</groupId>
<artifactId>abc-library</artifactId>
<version>*.*.*</version>
<packaging>jar</packaging>
<file>${project.basedir}/src/lib/***.jar</file>
</configuration>
</execution>
</executions>
<inherited>false</inherited>
</plugin>

Copy file to jar root when building spring-boot project with Maven

I have a Spring Boot project and I'm building the jar file with mvn clean build.
I need to copy a folder and a file to the root of the jar, where META-INF is located. I tried maven-resources-plugin but I can't reach my goal.
For war files I used maven-war-plugin in the past but I can't find something similar for jars.
Can anybody give me an idea?
Thanks.
I could manage to add files after the repackage goal of the spring-boot-maven-plugin using the maven-antrun-plugin and the Jar tool included in the JDK.
Updating a JAR File
The Jar tool provides a u option which you can use to update the contents of an existing JAR file by modifying its manifest or by adding files.
The basic command for adding files has this format:
jar uf jar-file input-file(s)
https://docs.oracle.com/javase/tutorial/deployment/jar/update.html
Using Maven-Antrun-Plugin
This command can be executed using the maven-antrun-plugin together with the exec task, which allows you to execute commands via Runtime.exec(..).
The entry may look like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<exec executable="jar" vmlauncher="false">
<arg value="uf" />
<arg value="${project.build.directory}/myprogram.jar" />
<arg value="-C" />
<arg value="${project.build.directory}/classes" />
<arg value="org/company/app/Main.class" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Notice the -C option, which allows you to change the directory that should not be included in the jar.
https://maven.apache.org/plugins/maven-antrun-plugin/usage.html
https://ant.apache.org/manual/Tasks/exec.html
Using Exec-Maven-Plugin
Alternatively the exec-maven-plugin can be used which does not require Ant to be installed.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals><goal>exec</goal></goals>
<configuration>
<executable>jar</executable>
<arguments>
<argument>uf</argument>
<argument>${project.build.directory}/myprogram.jar</argument>
<argument>-C</argument>
<argument>${project.build.directory}/classes</argument>
<argument>org/company/app/Main.class</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
The final structure may look like this:
myprogram.jar
|-BOOT-INF/..
|-META-INF/..
|-org/springframework/boot/loader/..
|-org/company/app/Main.class
That way you can add any additional files you want after the jar has been packaged.
could something like the following help?
See also maven-jar-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<includes>
<include>**/cdi/*</include>
<include>**/META-INF/*</include>
<include>*.properties</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
I resolved my problem by using the maven-assembly-plugin. I created an assembly zip which contains the application jar and some other resources.
This solution is specific for applications which use AWS Elastic Beanstalk and need to implement the Procfile (http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-se-platform.html#java-se-procfile).

How to copy war file to multiple folders?

It's possible to change the target build path where the war file is placed on mvn package by:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<outputDirectory>my\target\folder</outputDirectory>
</configuration>
</plugin>
Question: how can I create the war file in the default /target, folder, but additionally copy the war file to one (or multiple) other destinations after build?
A simple way to do that would be to bind an execution of the maven-antrun-plugin to the package phase. The advantage is that you don't need to re-execute the maven-war-plugin like mentioned in this answer.
This execution would copy the main artifact to the folder /path/to/folder.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<copy file="${project.build.directory}/${project.build.finalName}.war"
todir="/path/to/folder" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
(This snippet must be placed inside the <build><plugins> element).
Running mvn clean install (or "Run As... > Maven Install" in Eclipse), Maven will do what you want. ${project.build.directory}/${project.build.finalName}.war refers to the main WAR artifact present in the build directory (which is target by default).

Maven plugin - edit files in target (war)

I am developing some little maven plugin and I need to edit some css and js files from target (not from src!). And I can't understand on what phase I can do it.
To get access to src I use the phases:generate-resources and the following code:
MavenProject project = (MavenProject) getPluginContext().get("project");
String projectDir=project.getBasedir().toString();
How can I get target when all js,css files are copied there but war file is not generated in order to edit some files from target and get final war with some modifications of js and css files?
EDIT
What for I need it. I have js files in my project: a.js, b.js. I want to obfuscate them via maven. I mean, obfuscate when I build project. And of course all files in final war must be obfuscated but the same files in src must be left unobfuscated.
Besides, I need to combine some obfuscated files into one file.
I found the answer. The problem is that we must add some logic between "prepare-package" and "package" phases. As we user maven-war-plugin we can do it using exploded goal. From official docs:
Create an exploded webapp in a specified directory.
And here it's necessary to remember one important thing that maven after version 2.0.1 copies resources twice so if we want to use maven 2.5 we must use <useCache>true</useCache>. So final solution:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>prepare-war</id>
<phase>prepare-package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
<configuration>
<useCache>true</useCache>
</configuration>
</plugin>
<plugin>
<groupId>my plugin</groupId>
<artifactId>...</artifactId>
<version>....</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>...</goal>
</goals>
</execution>
</executions>
</plugin>

Categories

Resources