Running an exploded spring-boot jar from command line - java

I'm looking to run an exploded spring-boot jar.
Currently I'm doing
jar xf app.jar
java -cp /lib/*:/ com/domain/module/Main
which seems to begin the app startup, but invariably stops on
[restartedMain] INFO c.a.a.spring.MetricsJersey2Config - Registering InstrumentedResourceMethodApplicationListener for jersey2 with MetricRegistry: com.codahale.metrics.MetricRegistry#43fee23e
The next line I'd usually expect to see is
[restartedMain] INFO o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService
Running the app using
java -jar app.jar
works fine, but for reasons I need to run it exploded.
Is there anything I'm missing in trying to run a spring-boot app this way?

I solved this by running:
java -cp /lib/*:/ com.domain.module.Main
Rather than:
java -cp /lib/*:/ com/domain/module/Main

i'm facing this problem too ! don't forget to copy your clashpath of your .class in main package and spring boot org.springframework package, for example :-cp ./com/*:./org/*

Related

Customize Spring Boot executable-jar startup script

I'm trying to run Spring Boot executable-jar built using spring-boot-maven-plugin on a Linux machine. The machine has multiple jdks installed, the one on PATH is jdk8 and changing it is unfortunately not an option. My executable-jar however needs jdk17, so when I just launch it as is I get UnsupportedClassVersionError.
I was following the official documentation and created the corresponding .conf file to override JAVA_HOME. But this does not seem to solve the issue:
[root#ios-maket updater-new]# ls
updater-new-3.0-SNAPSHOT.conf updater-new-3.0-SNAPSHOT.jar
[root#ios-maket updater-new]# cat updater-new-3.0-SNAPSHOT.conf
JAVA_HOME=/opt/jdk-17/bin/java
[root#ios-maket updater-new]# ./updater-new-3.0-SNAPSHOT.jar
Application is running as root (UID 0). This is considered insecure.
Exception in thread "main" java.lang.UnsupportedClassVersionError...
On the other hand if I run it manually everything works fine:
[root#ios-maket updater-new]# /opt/jdk-17/bin/java -jar ./updater-new-3.0-SNAPSHOT.jar
[main] INFO com.icl.ios.fias.updaternew.UpdaterNew - Starting UpdaterNew using Java 17.0.6
What am I doing wrong?
Setting JAVA_HOME is not enough, you also need to set PATH to point to JAVA_HOME/bin.
JAVA_HOME=/opt/jdk-17
PATH=${JAVA_HOME}/bin:$PATH
java -jar updater-new-3.0-SNAPSHOT.jar
Try running the jar with -Dloader.path to specify the config manually.
java -Dloader.path=./updater-new-3.0-SNAPSHOT.conf -jar ./updater-new-3.0-SNAPSHOT.jar
If this still does not work, then probably there is an issue with your config file, but from what I can see, your config file looks okay, unless the java path is incorrect.

What is the general way to deploy jetty application in production?

I just take over a project which is a java servlet application, I just figured out the way running the application is mvn jetty:run by using history. The previous only developer just quit suddenly, and there's no document. I have to create production server and deploy the application.
I have no previous Java experiences, so have not idea how to do it. Should I install nginx or apache and run the application like PHP? Or I just do something like nodejs ?
Jetty is a Java Servlet container/server (with many more features).
There's no need for another server.
You have a few choices on how to start Jetty.
Standalone server using the jetty-home (or the older jetty-distribution) tarballs.
In this mode you unpack the jetty-home tarball (this will become the ${jetty.home} directory), create a new directory for your configuration / deployment (this will become the ${jetty.base} directory), and then run Jetty against this ${jetty.base} directory.
There are many many examples online of how to do this.
From the official Jetty documentation at https://www.eclipse.org/jetty/documentation/current/
To various examples here on stackoverflow.
# Grab the tarball
[~]$ curl -O https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/9.4.30.v20200611/jetty-home-9.4.30.v20200611.tar.gz
# Unpack the tarball
[~]$ tar -zxvf jetty-home-9.4.30.v20200611.tar.gz
# Make a {jetty.base} directory to house your configuration
[~]$ mkdir myappbase
[~]$ cd myappbase
# Since this is a new {jetty.base}, lets initialize it with a
# few common modules
[myappbase]$ java -jar ../jetty-home-9.4.30.v20200611/start.jar \
--add-to-start=http,deploy
INFO : webapp transitively enabled, ini template available with --add-to-start=webapp
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : security transitively enabled
INFO : servlet transitively enabled
INFO : http initialized in ${jetty.base}/start.ini
...(snip)...
INFO : deploy initialized in ${jetty.base}/start.ini
MKDIR : ${jetty.base}/webapps
INFO : Base directory was modified
# Lets see what we have now
[myappbase]$ ls -F
start.ini webapps/
# Copy your webapp into place
[myappbase]$ cp ~/Projects/mywebapp.war webapps/
# See this Jetty Configuration
[myappbase]$ java -jar ../jetty-home-9.4.30.v20200611/start.jar --list-config
# Run Jetty
[myappbase]$ java -jar ../jetty-home-9.4.30.v20200611/start.jar
Embedded Jetty
This means you have initialized everything entirely in code, from the Server object, to the ServerConnector, to the WebAppContext (or the ServletContextHandler) and are issuing a Server.start(); to make the Server execute.
This is probably the more common usage of Jetty, we find far more users on this approach then the standalone approach.
For development using the jetty-maven-plugin
This is what you have discovered already.
In a maven project with <packaging>war</packaging> you can execute the various jetty-maven-plugin goals to do various things with that maven project during development time.
NOTE: This mode is not suitable for production!
jetty:run is the jetty-maven-plugin and the run goal.
See: https://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html
Alternate environments where Jetty is embedded.
This mode is seeing increasing use, and if your application is using libraries like Spark or SpringBoot then you are essentially using Jetty under the covers, and have no need for a separate server installation / configuration, it's all done within the API/SDK of that library.

running war from command line without maven jetty

I am trying to put a piece of open source software in a docker container (https://github.com/att/XACML) but in this container I can not use maven. The documentation for running this service says to use mvn jetty, which does work fine, but in order to get this in a container I don't want to include a build step (maven).
Instead, I'd like a way to compile the a war, so I can copy just the war into the container and execute it from there.
I have tried many attempts to get the war running without maven jetty but none of them work.
java -jar /path/to/jar
no main manifest attribute error. There is no main class, it extends an HttpServlet
using jetty-runner
when I launch the war with jetty-runner through the command line I do not get any errors, but it boots up to a page showing the directory of files, and not the actual project.
Making an 'uber-jar' to package all deps
same issue as 1, get a no main manifest issue.
I can include more code if that would be helpful (pom files etc), but I don't want to add too much if it is unneeded. I am super unfamiliar with how java projects are packaged and deployed, so I am having a difficult time figuring out what needs to be done.
Thanks!
Minimal Dockerfile to work with your webapp / war file is ...
FROM jetty:9.4.18
ADD ROOT.war /var/lib/jetty/webapps/
This uses the official jetty docker image at
https://hub.docker.com/_/jetty
Managed at
https://github.com/eclipse/jetty.docker
The name ROOT.war is special, and will deploy your webapp in the "root" context path of "/"
Building Image
If you build it like this ...
$ docker build -t stackoverflow/jetty:latest .
Running Image
Interactively (so you can the logs)
$ docker run --interactive --tty --rm --publish 80:8080 stackoverflow/jetty:latest
As Daemon
$ docker run --detach --publish 80:8080 stackoverflow/jetty:latest
The server will be available on port 80 of the machine you ran the docker run command on.
Configuring Jetty Base
If you need to configure the jetty image you can use any of the standard start.jar commands.
Example:
FROM jetty:9.4.18
WORKDIR $JETTY_BASE
RUN java -jar $JETTY_HOME/start.jar --add-to-start=jsp
ADD ROOT.war /var/lib/jetty/webapps/
How This Works Without Maven
See the official image details ...
https://github.com/eclipse/jetty.docker/blob/master/9.4-jdk11/Dockerfile
The key commands are ...
WORKDIR $JETTY_BASE
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["java","-jar","/usr/local/jetty/start.jar"]

How to start grail application in production mode without terminate session when close command windows?

I have a grails 2.4.3 application run on centos 7. My problem is that I can't start the application via terminal, because when I close terminal, the session is terminated.
My command to start program is:
export PATH=$PATH:/opt/setup/grails-2.4.4/bin
export JAVA_HOME=/usr/java/jdk1.7.0_80/
grails prod run-app
I have already try many ways:
i.e: nohup grails prod run-app (nothing change after running command),
setsid prod run-app (program terminated by accidentally after a time running).
Both the ways are not worked.
Please help me find a way to start Grails application in production precisely.
Thanks.
Do not use grails run-app in production. From the Grails 2.4.4 documentation
NEVER deploy Grails using the run-app command as this command sets Grails up for auto-reloading at runtime which has a severe performance and scalability implications
In Grails 2.x (for production), you need to deploy your application to a supported Java EE Container (Tomcat, Jetty, etc), which are listed on the same page in the documentation.
In Grails 3.x you can package your web app as a jar and run it like any other jar because it is built on top of Spring Boot and the container was packaged into the jar.
On linux, you can use the nohup (no hang-up) command to make sure that the command will not be killed when you close the terminal.
Create a sh (startup.sh) file containing your startup statements:
echo "export PATH=$PATH:/opt/setup/grails-2.4.4/bin
export JAVA_HOME=/usr/java/jdk1.7.0_80/
grails prod run-app" > startup.sh
make sure the script is executable
chmod +x startup.sh
then
nohup ./startup.sh

Spring Boot init.d not Not running (process not found)

I was trying to follow the instructions from here, where trying to run the Spring Boot app as init.d service but could not successfully.
I created the fully executable jar (myapp.jar) as mentioned and also created the symlink to /etc/init.d/myapp When I run the java -jar myapp.jar I could see the application start up successfully.
But when I try to use
service myapp status it says Not running (process not found)
service myapp start it says Failed to start
the documentation says "Assuming that you have a Spring Boot application installed in /var/myapp" I don't understand this point quite well. I copied the executable jar (via Jenkins) to /var/myapp. so it contains only one file which is jar. does this create the problem?
Any suggestions are appreciated.
Environment:
springBootVersion = '1.3.2.RELEASE'
JDK6 (yes it is)
Ubuntu 12.04
Sometimes, you may need to run: sudo systemctl daemon-reload for your new service to be loaded.
You must register your jar as service. Look at http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#deployment-initd-service
In ubuntu you need reload deamon with sudo systemctl daemon-reload

Categories