How to get jar name in start.sh script - shell

I am deploying a spring boot app + maven. I have written a start.sh script using link https://dzone.com/articles/packaging-springboot-application-with-external-dep
The jar name can change as per the version , so I don't want to hard code the jar name in start.sh like -jar ../lib/gs-spring-boot-0.1.0.jar
How can I make it dependent on jar name? any variable substitution possible?

If you know there's only one JAR file, how about something like this
JAR_FILE=`ls ../lib/gs-spring-boot-*.jar`
java -jar ${JAR_FILE}

You have to create your start.sh script automatically and paste correct jar name there. Please check http://www.mojohaus.org/appassembler/appassembler-maven-plugin/
Examples: http://www.mojohaus.org/appassembler/appassembler-maven-plugin/usage-program.html
In combination with maven-assembly you can create a tar.gz or zip archive which contains everything that you need.

Related

Error: Unable to access jarfile build/libs/gs-spring-boot-0.1.0.jar?

I follow the instructions in https://spring.io/guides/gs/spring-boot/#scratch, but when it says to run:
./gradlew build && java -jar build/libs/gs-spring-boot-0.1.0.jar
the build fails with the above error.
There is message before the failure that says:
Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
See https://docs.gradle.org/4.8.1/userguide/command_line_interface.html#sec:command_line_warnings
but everyone online says that's just a warning.
The build doesn't appear to create or download build/libs/gs-spring-boot-0.1.0.jar.
Currently completely blocked on first attempt to use Gradle.
I just had this problem.
The tutorial is in error in what you need to run. It should be
$ gradlew build && java -jar build/libs/gs-rest-service-0.1.0.jar
I think that they updated the code, but forgot to update the tutorial.
I had the same issue when build a simple project with Maven on Intellij IDEA. (Ubuntu 18.04.2).
Just typed terminal (in project directory):
$ sudo mvn package
$ java -jar ./target/(your-project-name)-(<version> at pom.xml).jar
For example my project name is hello-world-spring and version name in pom.xml is <version>0.0.1-SNAPSHOT</version>, I have to type:
$ sudo mvn package
$ java -jar ./target/hello-world-spring-0.0.1-SNAPSHOT.jar
Maybe this method can work for gradle as well.
Please check the path of the jar file build/libs/gs-spring-boot-0.1.0.jar. For your case, the jar might be in a different folder. If your code is in a module in the main project, then the jar will be in the build folder of the module.
If you git clone the repo, then the tutorial works. If you "To start from scratch, move on to Build with Gradle.", then the tutorial doesn't work. There are missing setup steps.
I got the same issue and I changed the command to java -jar target/rest-service-0.0.1-SNAPSHOT.jar (I checked the .jar file in target folder and found that the file name was incorrect).
Parent folder of my project was having spaces in it's name, i changed it to the underscore and it worked.
Looked at the command line as it was in the official guide:
./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
First, the above command line has two parts:
(1) ./gradlew clean build //Use gradle wrapper to build
(2) java -jar build/libs/gs-actuator-service-0.1.0.jar //To run an application packaged as a JAR file
Now, one might run into issues with one part or both parts. Separating them and running just on thing at a time helped troubleshoot.
(1) didn't work for my Windows, I did the following instead and that built the application successfully.
.\gradlew.bat clean build
Now moving to (2) java -jar build/libs/gs-actuator-service-0.1.0.jar
It literally means that "Run a jar file that is called gs-actuator-service-0.1.0.jar under this directory/path: build/libs/" Again, for Windows, this translates to build\libs\ , and there's one more thing that may catch you: The jar file name can be slightly different depending on how it was actually named by the configuration in initial/setting.gradle:
rootProject.name = 'actuator-service'
Note that the official guide changed it from 'gs-actuator-service' to 'actuator-service' in their sample code but hasn't updated the tutorial accordingly. But now you know where the jar file name comes from, that doesn't matter anymore, and you have the choice to rename it however you want.
Having all the factors adjusted, below is what eventually worked in my case:
java -jar build\libs\actuator-service-0.0.1-SNAPSHOT.jar
or
java -jar C:\MyWorkspace\Spring\gs-actuator-service\initial\build\libs\actuator-service-0.0.1-SNAPSHOT.jar //with fully qualified path
If you are curious where does "-0.0.1-SNAPSHOT" come from, here it is:
in build.gradle
version = '0.0.1-SNAPSHOT'
Again, you have the choice to modify it however you want. For example, if I changed it to 0.0.2-SNAPSHOT, the command line should be adjusted accordingly
java -jar build\libs\actuator-service-0.0.2-SNAPSHOT.jar
Reference: https://docs.oracle.com/javase/tutorial/deployment/jar/basicsindex.html
Because you are trying to execute .jar file that doesn't exist. After building the project go to ./build/libs and check the name of freshly built .jar file and then in your project directory run:
./gradlew build && java -jar build/libs/name-of-your-jar-file.jar
or you can set version property to empty string in your build.gradle file
version = ''
after that:
./gradlew build && java -jar build/libs/your-project-name.jar
For Windows, these commands solved the problem: "Error: Unable to access jarfile springboot.jar":
cd target
java -jar springboot-0.0.1-SNAPSHOT.jar
run ./mvnw package
Now a folder named target is created and you can see a jar file inside it.
then execute java -jar target/<jarfilename>

Dynamically get JAR filename in DockerFile

I am new to Docker. I am using spring boot and when we build the project using maven, it will create jar file like app-.jar and then I am coping this jar file using ADD command in DockerFile. Now If I change the version number in pom.xml, then I need to manually update the JAR file name in DockerFile.
Is there anyway by which I can dynamically get the version number which is in the pom.xml and update the JAR file name automatically in the DockerFile?
Instead of copying the jar file inside the dockerfile, you can mount the folder in which jar is created. And you will not be needed to be worried with the filename.
What you want can be done using environment variables. You can create an --env-file and keep your version number there. And inside dockerfile, refer to value of variable declared in env file with {VERSIION}. By following this process, you may want to use this same version in your pom file. For that, take a look at this question.
The answer links environment variables by setting env.path and detailed guide is here.

How to specify JVM Parameters inside Spring Boot Project when executed with init.d

I have a Spring Boot project that I'm running as an executable jar started as an init.d service on Linux.
I understand I can create a .conf file with the same name as the jar file to specify JVM parameters. However, I would ideally like to "hard code" some parameters so there is no risk of the .conf file being missing. This is a real risk as each deployment will have a different jar name because of the version number.
Also I know I can set the environment variable JAVA_OPTS, but I'm not sure how to do this if I'm launching the Spring Boot as a init.d service using a symlink to the jar file.
Lastly I know I can replace the init.d script completely using the embeddedLaunchScript parameter, but I fell this overkill for what I want to accomplish and would want updates to the script in further releases.
Is there a way to specify JVM parameters in the Maven plugin or some other programmatic method?
Alternatively is there a way to hard code a static CONF file name? Looking at the embeddedLaunchScriptProperties it looks like confFolder can the folder, but not the name of the .conf file.
As of Spring boot 2.0, you can set the inlinedConfScript property of the build plugin. You can now reference a file that includes the appending or overwriting the JAVA_OPTS variable before the application starts. More details can be found in the Spring Documentation.

Spring boot running a fully executable JAR and specify -D properties

The Spring Boot Maven and Gradle plugins can now generate full executable archives for Linux/Unix operating systems.Running a fully executable JAR is as easy as typing:
$ ./myapp.jar
My question is in this case how to set -D properties, e.g.
-Dspring.profiles.active=test
In addition, if server does not install jdk , could this fully executable jar still run?
There are two ways to configure properties like that:
1:
By specifying them in a separate configuration file. Spring Boot will look for a file named like JARfilename.conf which should be stored in the same folder like the JAR file. There you can add the environment variable JAVA_OPTS:
JAVA_OPTS="-Dpropertykey=propvalue"
2:
Or you can just specify the value for the environment variable in the shell before you execute the application:
JAVA_OPTS="-Dpropertykey=propvalue" ./myapp.jar
Have a look at the documentation for the complete list of available variables: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#deployment-service
Regarding your second question: To execute a JAR, you don't need a JDK, a JRE is sufficient (but you need at least that, if you don't have any java installed on the server, the application won't run).
By default SpringApplication will convert any command line option arguments (starting with ‘--’, e.g. --server.port=9000) to a property and add it to the Spring Environment. As mentioned above, command line properties always take precedence over other property sources.
e.g.
$ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'
please see http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/

Delete/Remove file from war with Gradle

I'm using gradle to build a Spring Boot application, and I would like to have the application.properties file removed from the war, because that will be loaded externally (this is running in a tomcat container, not embedded).
I've looked around StackOverflow and the Gradle docs to try to figure out what to do, but I don't know which phase to tie into, and if I exclude the file before or after the war is created. There also seem to be multiple ways of dealing with files.
I believe Maven uses packagingExcludes for the equivalent.
Although I was not able to prevent a file from being added to the war, I was able to remove a file after the war was created - thanks in part to a tip from this question: Is there a quick way to delete a file from a Jar / war without having to extract the jar and recreate it?
In my build.gradle file I appended the war command with an exec command so that I could run a command after the war file had been created. The command will remove the application.properties file from the war. This is what the task extension looks like:
war << {
exec {
workingDir 'build/libs'
commandLine 'zip', '-d', "${appName}-${appVersion}.war", 'WEB-INF/classes/application.properties'
}
}
In short, it changes the working directory to the location that gradle places the war, and then uses the zip command to remove a file from the war.
You also have the option that if you don’t care for these properties files to be copied from the src/main/resources to the build/resources/main folder (not just excluded when build/resources/main is copied to the War), you could use:
In build.gradle file;
processResources {
exclude('application.properties')
}

Resources