How to deploy Springboot app in Linux along with Maven dependencies - java

I have created a Spring Boot java application (REST Services) which uses Tomcat internally as web server on Windows machine using Eclipse as IDE. It uses JDK 1.8 & Maven as build system. Here I create jar file (Run as Maven Install ) and then invoke that jar file from command prompt in my windows machine. I test these REST services using POSTMAN on my Windows machine.
Now I have to get it working on an Linux machine which does not have UI. Can you please help me how to achieve same on Linux machine and how to get those dependencies on Linux machine.

first, make sure your Linux server have Java installed. Best match your local java version.
second, make use of maven plugin to generate a shell script which can kick off this project.
Below is an example
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<!-- bind to package phase -->
<executions>
<execution>
<id>make-appassembly</id>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- set alternative assemble directory -->
<assembleDirectory>${project.build.directory}/${project.artifactId}-${project.version}
</assembleDirectory>
<environmentSetupFileName>envSetup.sh</environmentSetupFileName>
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
<repositoryLayout>flat</repositoryLayout>
<repositoryName>lib</repositoryName>
<platforms>
<!-- <platform>windows</platform> -->
<platform>unix</platform>
</platforms>
<!-- Extra JVM arguments that will be included in the bin scripts -->
<extraJvmArguments>-Dlog4j.configuration=file:$BASEDIR/etc/log4j.properties
-Dapplication.properties=file:$BASEDIR/etc/XXX.properties
-Xms2048m
-Xmx12288m -server -showversion -XX:+UseConcMarkSweepGC
-DXXX.log.dir=XXX
-DXXX.app.id=XXX
</extraJvmArguments>
<programs>
<program>
<mainClass>com.xxx.App</mainClass>
<name>xxx.sh</name>
</program></programs>
</configuration>
</plugin>

Related

Remove the dependency on Python while building RPM using rpm-maven-plugin

I'm using rpm-maven-plugin to build an rpm as a part of my mvn build which later will be installed in a docker image that doesn't have Python. Python is not being used in the project as well. But for some reason, the generated spec file has the line
Requires: python >= 2.6
I tried putting in
<autoRequires>no</autoRequires>
<autoProvides>no</autoProvides>
but doesn't work as well. This is causing the docker build to fail as the rpm install fails because of missing dependency. How do I remove the dependency on python?
Following is the extract from my pom.xml
...
<version.rpm-maven-plugin>2.2.0</version.rpm-maven-plugin>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-rpm</id>
<phase>package</phase>
<goals>
<goal>rpm</goal>
</goals>
</execution>
</executions>
<configuration>
<group>XXX</group>
<vendor>XXX</vendor>
<copyTo>
target/${install.package.name}-${project.version}.rpm
</copyTo>
<targetOS>linux</targetOS>
<autoRequires>no</autoRequires>
<autoProvides>no</autoProvides>
<mappings>
...
</mappings>
<preinstallScriptlet>
<scriptFile>${basedir}/src/main/package/control/preinst</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</preinstallScriptlet>
<postinstallScriptlet>
<scriptFile>${basedir}/src/main/package/control/postinst</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</postinstallScriptlet>
<preremoveScriptlet>
<scriptFile>${basedir}/src/main/package/control/prerm</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</preremoveScriptlet>
<postremoveScriptlet>
<scriptFile>${basedir}/src/main/package/control/postrm</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</postremoveScriptlet>
<cleanScriptlet>
<script>rm -rf ${project.build.directory}/rpm/buildroot</script>
</cleanScriptlet>
</configuration>
</plugin>
maven version: 3.5.4.
target docker image runs bare-bones SLES linux with just what is required and doesn't have Python.
Got it working by manually overriding the requires section
...
<autoRequires>no</autoRequires>
<autoProvides>no</autoProvides>
<requires>
<require>java-11-openjdk-headless</require>
</requires>
...

Micronaut Dockerfile breaks package build

I've created a simple Micronaut application using
mn create-app app_name --build maven
with a JDK 11 in case that matters.
This creates a maven project which compiles fine, but includes a Dockerfile like this:
FROM adoptopenjdk/openjdk11-openj9:jdk-11.0.1.13-alpine-slim
COPY target/app_name*.jar app_name.jar
EXPOSE 8080
CMD java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Dcom.sun.management.jmxremote -noverify ${JAVA_OPTS} -jar app_name.jar
However, there is no docker build included in the Maven AFAICT.
So I included this
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-maven-version}</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>dockerUser/app_name</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
which does manage to build a docker image, but not without manual intervention. The reason is that upon mvn package, three jars get created in target/:
app_name-0.1.jar
app_name-0.1-shaded.jar
original-app_name-0.1.jar
which makes the docker target fail with
When using COPY with more than one source file, the destination must be a directory and end with a /
That message does make sense because all the jars match the COPY source pattern in the Dockerfile.
Right now, I just delete the other two jars (original and shaded) and run the docker target on its own, but that's only fine as long as I work in local manual mode.
Am I missing something or is this an oversight on the Micronaut project creation?
I can't help you with the micronaut configuration, unfortunately. However, if the purpose is to copy the main jar file and the unknown version suffix is the cause of the wildcard being used while copying, a finalName element can be added to the pom.xml in order to strip the version info from the name of the JAR file:
<build>
<finalName>app_name</finalName>
</build>
Am I missing something or is this an oversight on the Micronaut
project creation?
The latter.
If you file an issue at https://github.com/micronaut-projects/micronaut-profiles/issues we can get it straightened out.
Relevant files:
https://github.com/micronaut-projects/micronaut-profiles/blob/c391ef02b5ca087bbdec79f80b129240b29cc246/service/skeleton/maven-build/Dockerfile
https://github.com/micronaut-projects/micronaut-profiles/blob/c391ef02b5ca087bbdec79f80b129240b29cc246/service/skeleton/gradle-build/Dockerfile
Thanks for the input.

Embedded java at desktop application

If it possible to build java desktop application with embedded JVM? I do not need to depend on the end user having the right JRE installed.
I build my application for Windows with l4j maven plugin.
Googling does not give needed results. Maybe you someone know how to do it with maven o gradle, not by some another utility like Avian, ProGuard and etc. (Embed a JRE in a Windows executable?)
The Maven plugin for Launch4j lets you generate the Launch4j
executable as part of the Maven build process. It supports Maven 2.0.4
and Launch4j 3.x.
See here
This is a sample of the configuration that you can try to use:
<plugin>
<groupId>com.akathist.maven.plugins.launch4j</groupId>
<artifactId>launch4j-maven-plugin</artifactId>
<executions>
...
<configuration>
...
<jre>
<!-- Specify path or minVersion or both. -->
<path>bundled JRE path (%VAR%)</path>
<bundledJre64Bit>true|false</bundledJre64Bit>
<bundledJreAsFallback>true|false</bundledJreAsFallback>
<minVersion>x.x.x[_xx]</minVersion>
<maxVersion>x.x.x[_xx]</maxVersion>
<jdkPreference>jreOnly|preferJre|preferJdk|jdkOnly</jdkPreference>
<runtimeBits>64|64/32|32/64|32</runtimeBits>
<!-- Heap sizes in MB and % of available memory. -->
<initialHeapSize>MB</initialHeapSize>
<initialHeapPercent>%</initialHeapPercent>
<maxHeapSize>MB</maxHeapSize>
<maxHeapPercent>%</maxHeapPercent>
<opt>text (%VAR%)</opt>
</jre>
...
</configuration>
</execution>
</executions>
</plugin>

Enable exec-maven-plugin while executing jar through java command

I am using exec-maven-plugin to execute a shell script.
<executions>
<execution>
<id>exec-ui-install</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>bash</executable>
<arguments>
<argument>${basedir}/ui-build.sh</argument>
</arguments>
<skip>${exec.skip}</skip>
</configuration>
</execution>
</executions>
I dont want this to run during build time (as i don't need to run it during build and i am building it from windows). So i am using a parameter named exec.skip and with its help i am able to skip it.
After building jar and moving it to Linux env i am using java command
Ex: java -cp : javaclass
to run the jar. During this i need to execute "exec-maven-plugin" which was disabled during build mode. How do i pass "exec.skip=true" through java command so that i can run plugin.
You cannot do it.
The maven configuration of a project is used during the build of the project.
Once the artifact/component is constructed, you don't interact any longer with maven.
In your case, you should build your component with the suitable configuration parameters before moving it to linux.
Using a Maven profile with this specific configuration that is launched by a continuous integration tool could ease the task and make it reliable.

How can I get the temp folder of a machine running maven?

I'd like to save some unpacked files into the temp folder of a machine.
Question: How can I get the temp folder using maven?
Question: Will it work on both linux and windows environments?
Maven supports, as part of the default properties, any Java System property, hence you can use the following property:
java.io.tmpdir Default temp file path
As example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<!-- further conf here -->
<outputDirectory>${java.io.tmpdir}/libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Note the outputDirectory element and its value.
As a further note, also note that the target folder of the Maven build is also meant to host temporary files, so you should also consider to use it for such a purpose.
Will it work on both linux and windows environments?
Yes, since it is Java property, it is supposed to be OS independent.
use the java environment tmp dir - java.io.tmpdir
you can access it from maven via ${java.io.tmpdir} without having to predefine it.
you can also customize it on a specific run by running:
mvn clean install -Djava.io.tmpdir=/tmp/where/ever

Categories