I created a spring boot job which relies on properties on the server and I can get it to run like so, no modifying manifest.
/bin/java -Dspring.config.location=/var/tmp/com.jdbc.properties -jar my.jar
and it works. But the application relies upon another jar that is an internal jar that lives under /usr/local/share/jni/foo.jar which I want to add to this mix.
I have tried countless runs trying such things as:
java -cp /usr/local/share/jni/foo.jar -Dspring(picking up original line)
When I start to google this, it takes me on magical tours of running:
'org.springframework.boot.loader.JarLauncher'
or
'org.springframework.boot.loader.PropertiesLauncher'
then mucking with manifest etc.
Spent last 4 hours with no success. Is there a best practice to run a standalone jar that needs to consume remote properties file and an additional jar file? Would like to keep it simple if possible.
If you are using Spring Boot and want to have a Fat-jar that encapsulates all your dependencies, the best way is to add the required Jar as a dependency to your project.
Assuming you are using Maven to build your project, the "foo.jar" needs to be added as a Maven dependency to your project. Then, spring Boot maven plugin will pick up the jar and includes it in your Fat-jar.
Even if the "foo.jar" does not exist in any Maven repo, you still can add it manually to your local Maven repo using the Maven command mvn install:install-file (See Maven doc).
Did you try using foo.jar as a provided dependency within your maven/gradle dependencies and building the project as executable war file?
See spring boot's maven plugin description of building executable war files.
Overall. Run spring boot standalone jar on a Linux server. Additionally read the database properties from a static file on the server, and path in a jar file that adds functionality that only lives on the server. Cannot include in the boot lib.
command line run (will convert to shell) and ran.
/path/to/..openjdk-1.7.0.55.x86_64/bin/java -cp /usr/somewhere/jni/Foo.jar:/path/where/lib/MYBOOTJAR.jar org.springframework.boot.loader.JarLauncher --spring.config.location=/path/to/properties/on/server/com.xxx.yyy.zzz.jdbc.properties
Seems like using the JarLauncher (no modifications to manifest, except excluding the Foo.jar from local)
Hope this helps someone else.
Related
I was going through spring-boot-maven-plugin documentation and came across a term auto executable jar.
Could someone please explain me what is an auto executable jar and how is it different then normal jar files and how they are auto executed?
spring-boot-maven-plugin documentation mentions the term but does not go further to explain it
repackage: create a jar or war file that is auto-executable. It can replace the regular artifact or can be attached to the build lifecycle with a separate classifier.
Could someone please explain me what is an auto executable jar
A fully executable jar can be executed like any other executable
binary or it can be registered with init.d or systemd. This makes it
very easy to install and manage Spring Boot applications in common
production environments.
So In conclusion is like any other executable when you use a executable jar
how is it different then normal jar files and how they are auto executed?
Well a java file you need to run with java -jar
From Spring Docs
The Maven build of a Springboot application first build your own application and pack it into a JAR file.
In the second stage (repackage) it will wrap that jar with all the jar files from the dependency tree into a new wrapper jar archive. It will also generate a Manifest file where is defined what's the application Main class is (also in the wrapper jar).
After mvn package you can also see 2 jar files in your target directory. The original file and the wrapped jar file.
You can start a Springboot application with a simple command like:
java -jar my-springboot-app.jar
I may suggest that auto executable means that you supplied main method so that it can be launched with java -jar options, otherwise it may be just a java library.
Here is a quote from https://docs.spring.io/spring-boot/docs/current/maven-plugin/repackage-mojo.html
Repackages existing JAR and WAR archives so that they can be executed from the command line using java -jar. With layout=NONE can also be used simply to package a JAR with nested dependencies (and no main class, so not executable).
Executable jar - the one that has main class declared in manifest and can be run with java -jar yourJarFile.jar command
Other jars - jars jars without delcared main calss. Can be anything - application, library, etc. Still can run application by providing fully.qualified.class.name as entry point like java -cp yourJarFile.jar my.bootstrap.BootstrapClass
Autoexecutable jars - never heard about it :)
Is there another way to run deployed spring boot application on server than *sh script?
My idea is create .sh script which will start app (java -jar name...). This solution is simple but have one disadvantage - I have application version in the file name. I can trust that there will be only one *jar file and run it - but I am not sure that it is best solution.
What do you think?
You could use maven-assembly-plugin to bundle your application jar and sh script onto one zip file. In this case you could use maven resource filtering to put replace ${version} placeholder in your sh with exact version of your jar during maven build.
If your jar has name like this: `my-project-.jar1 then your sh script will look like this:
java -jar my-project-${version}.jar
During build maven will replace ${version} with value from pom.xml.
So after build you need to unpack zip (or tar.gz) and execute sh script.
I have an application built using maven and spring mvc and tomcat7-maven-plugin. Can I package these to a jar file, so that i can run the jar file to start a tomcat server?
That means i don't need tomcat, only a jar file can provide a web service.
Spring documentation is your friend. I am providing the links which you can follow, with highlighted parts in this post.
Spring Boot Maven Packaging
Once spring-boot-maven-plugin has been included in your pom.xml it will automatically attempt to rewrite archives to make them executable using the spring-boot:repackage goal. You should configure your project to build a jar or war (as appropriate) using the usual packaging element in the pom.xml
The main class that you want to launch can either be specified using a configuration option, or by adding a Main-Class attribute to the manifest in the usual way.
To build and run a project artifact, you can type the following:
$ mvn package
$ java -jar target/mymodule-0.0.1-SNAPSHOT.jar
More information about the plugin is available here
I have a Java console application, till now it was developed in Netbeans IDE. When Netbeans builds application, it creates dist directory and builds an app into this directory as a jar archive and into dist/lib copies all dependencies. This this directory could be copied into final destination and run.
Now I'm trying to transfer this project into Maven. Everything goes ok, I can compile and package my app and a jar is created into target directory. I use maven-jar-plugin to set main class in manifest and maven-shade-plugin to package all sources into one jar file.
I would like to ask you how is such Maven project deployed in the real world? Should I use all target directory, copy it ad the final destination and run as I have been used to do with Netbeans? What are consequences when I don't use maven-shade-plugin - where are all libraries defined as dependencies located? I am asking, because in my testing project these libraries don't exist in target directory.
My question - I have a Java console application "A" packaged via Maven (without maven-shade-plugin) and Linux server "S" where this application should run. Can I copy all target directory manually to server "S" or is there some better / more automatic way how is this solved in the real world?
Simply copying over the target directory will not solve your problem. I have packaged many standalone applications using Maven and I have used Maven Assembly Plugin for it. You can create a distribution archive (zip, tar.gz) using the assembly plugin which your customer can unzip and start running.
It depends on you, how you want your target application directory structure (release). I usually end up with something like
bin/
conf/
lib/
log/
The bin directory contains a shell / batch script to run your program by calling your main class, setting appropriate classpath, providing relevant memory settings etc. I prefer using classworlds (which is used by Maven) to bootstrap my application and simplify writing of start scripts.
conf directory contains configuration files for your application as well as logging configuration files like log4j etc. This directory I add on classpath to make it easier to access configuration resources at runtime.
lib directory contains all the dependency jars a well as jar file for your code.
log is where your logging configuration will point to output log files.
Note that this structure is good for standalone server like applications. Also having a bin directory and run scripts allows you to add this directory to PATH on Windows / Linux to ensure you can run the application from anywhere.
If you are packaging a command line utility, simple shaded jar may work for you. Personally, I am not the biggest fan of java -jar application.jar
The question is too broad to be answered comprehensively, but I would like to provide an example of real-world maven deployment.
There are maven plugins for all major application servers. They have defined targets for local and remote deployment. One such plugin is the jboss-as-maven plugin. You can define the deployment properties (IP, port etc.) in your .pom or directly from command line, e.g.
mvn jboss-as:deploy -Dpassword=mypassword
There is also the cargo plugin that specializes in application deployment.
I am struggeling with this for a while.
I am using Spring3.1 in a standalone env. I have resources files which I need to add into the classpath (applicationXML). In eclipse it's a known and easy way. Now I am trying to deploy my application to a standalone env on linux using Daemon (commons-daemon-1.0.3.jar).
How can I add resources files there to the classpath?
One thing you can do is use the Maven Shade plugin. This is used to create a SuperJAR of everything in your build profile — dependent JARs from Apache and Spring, as well as your own code. The Shade Plugin can that add a Classpath entry of "." into the Manifest of the SuperJAR, this is precisely how you will be able to run the Main class of the SuperJAR, but have the classloader look in both a local directory as well as a JAR for all your components.
You'll have to adjust your build a bit so that things like log4j.properties and application-context.xml, and other files you wish to have sysadmins/customers modifer after build are kept out of the resources/path — otherwise they will get baked into the build.
You might look at my source code here http://sourceforge.net/projects/jee2pctest/. The client driver code provides an excellent example of how to use the Maven Shade plugin to create a directly executable JAR with external properties files.The magic is mainly in the pom.xml file. One Caveat, I am using the Maven build tooling, if you are still on ANT using using your IDE's built-in packager, then you might have some work cut out.