Spring Boot - Could not resolve placeholder when ran from jar file - spring

I'm running into this strange issue where I can run my Spring Boot application without problems from within Intellij, but when I do:
mvn clean package -Pst -Dspring.profiles.active=st && java -jar target/myapp-0.0.1-SNAPSHOT.jar
I can see errors saying Spring Boot cannot resolve the #Value placeholders.
ERROR o.s.boot.SpringApplication - Application startup failed
java.lang.IllegalArgumentException: Could not resolve placeholder
What I did to investigate was to get the jar file and extract the files like using jar xf myapp.jar and I can see the properties files in the classpath root. Initially I had this problem that Maven was not packaging my properties and statics from the main/resource folder, but I already resolved that with:
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>static</directory>
<targetPath>static</targetPath>
</resource>
Any comments, ideas what could I be missing here?

I managed to resolve this. It was really weird, it seems that I need to tell java in which profile to run the jar in e.g --spring.profiles.active=st.
mvn clean package -Pst -Dspring.profiles.active=st && java -jar target/myapp-0.0.1-SNAPSHOT.jar --spring.profiles.active=st

It is not Maven deciding, what Spring Profile you use, but the Spring container during every single execution of the jar. The differen profiles are all available. The Spring profile is used to adapt the executable to different environments by configuration.
There are additionally Maven profiles, but they configure the build of the executable, not the execution.

Related

How to run spring batch application without spring boot maven plugin

Is it possible to run a spring batch application without spring boot maven plugin?
I need to run the application on another server and transferring a big jar (with spring dependencies) is time consuming. For this reason I want to compile and create a jar without spring dependencies included inside the jar and run it from command line.
If you want to create a simple JAR without spring boot dependencies, remove spring-boot-plugin from build.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
Above snippet should not be present in your pom.xml.
With this, fat/uber jar won't be created.
To run built jar:
java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main
Where your libraries are contained in lib directory relative to current directory and MyJar.jar is the name of the jar built with maven.

Remote debug or local debug with tomcat embedded in Spring boot

I am working on a new project which embedded a tomcat with the dependency spring-boot-starter-tomcat:2.5.3 (into vaadin-spring-boot-starter).
I am building my project into a .jar, and launching it with "mvn spring-boot:run".
But because of the embedded tomcat, I am unable to use the debug mode with Eclipse.
I have already try to launch a remote debug session, with :
MAVEN_OPTS= -Xmx1024M -XX:MaxPermSize=256M -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
Eclipse connects itself well, but breakpoints are not working and it shows me only one thread, without any more informations.
So, do you have any idea how can I make it works ?
Thanks you for your time !
When running application using mvn spring-boot:run you can attach debugger like this:
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:8000"
By providing spring-boot.run.jvmArguments system property.
Alternatively, you can build application first and then run it using the following command:
java -jar app.jar -Dagentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000
When you provide debugger configuration using MAVEN_OPTS, the debugger is attached to the Maven process, however, the application is running in a separate Java process without a debugger attached.
The easiest way to debug a Spring Boot application from an IDE is to not use Maven at all but instead directly launch the main method from the #SpringBootApplication class.
As a third solution, I have installed Spring Tools 4 on the Eclipse Marketplace.
It makes me able to launch a #SpringBootApplication in debug mode, like Leif Astrand said, but with an IHM (Boot Dashboard).
Another solution is described here:
https://vaadin.com/forum/thread/17519592/debug-with-intellij
This solution also helped me get around the problem of connecting the remote debugger, but breakpoints not being reached (see my comment above).
You can add a JVM arg to the config params of the plugin, like this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- my edits start -->
<configuration>
<jvmArguments>
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
</jvmArguments>
</configuration>
<!-- my edits end -->
</plugin>

How can I configure the heap size when starting a Spring Boot application with embedded Tomcat?

I am trying to deploy a Spring Boot powered web app to production. The app is built with Spring Boot 1.0.1 and has the default Tomcat 7 embedded as application server. I want to allocate larger memory to the app when start the app with java -jar myapp.jar command line.
Should I use JVM parameter such as -Xms -Xmx or use environment variable such as JAVA_OPTS? I have tried to look for the answer in documentation or google it, but I did not get an answer. Can anyone give some hints?
If starting the application with the spring-boot plugin:
mvn spring-boot:run -Drun.jvmArguments="-Xmx512m" -Drun.profiles=dev
Otherwise if running java -jar:
java -Xmx512m -Dspring.profiles.active=dev -jar app.jar
Since this is specifically a Spring Boot question, I'd argue that a more useful answer than #DaveSyer's is this:
You can drop a .conf file in the same directory as your WAR file that is effectively a shell script.
For example,
$ ls
myapp.conf
myapp.war
$ cat myapp.conf
export JAVA_OPTS="-Xmx1024m -Xms256m"
Any configuration you do there will be run before the Spring Boot embedded Tomcat starts up. Personally, I version control a .conf.example file in my application itself and then drop a copy of it on each server I deploy to.
Of course, anything you set in that .conf file is overridable with command-line operations.
Just use whatever normal mechanism you would to set up the JVM. Documentation is available on the command line:
$ java -X
...
-Xms<size> Set initial Java heap size
-Xmx<size> Set maximum Java heap size
...
For Spring Boot 2, you have to specify the heap size in the pom.xml file as below:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>-Xmx64m</jvmArguments>
</configuration>
</plugin>
For Spring Boot 1, the Maven argument to specify in the plugin configuration is jvmArguments, and the user property is run.jvmArguments:
mvn spring-boot:run -Drun.jvmArguments="-Xms2048m -Xmx4096m"
For Spring Boot 2, the Maven argument to specify in the plugin configuration is also jvmArguments, but the user property is now spring-boot.run.jvmArguments:
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xms2048m -Xmx4096m"
So if you use the plugin configuration way, both for Spring Boot 1 and 2 you can do that:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>
-Xms4048m
-Xmx8096m
</jvmArguments>
</configuration>
</plugin>

Add test jars in maven-jetty-plugin or create test-war with maven-war-plugin

I'm using maven to build a multi-module webapp. I would like to run my integration tests in their own module and use the jetty plugin. In order to get everything to work I will need to add a couple of jars to the classpath for the war but I see no option for such a thing in the documentation http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html#deploy-war-running-pre-assembled-war
I am able to deploy the war but it fails because it's missing the two jars I need to add.
Is there a way for me to add a couple extra jars to the plugin configuration?
If not, is there a way for me to package a "test-war" like you can do with test-jar in maven?
There are multiple ways to extend the web application classpath with the jetty-maven-plugin. The most appropriated for you would be to set the extraClasspath field in the webAppConfig block of your plugin configuration:
<configuration>
...
<webAppConfig>
...
<extraClasspath>path/to/your/custom-dependency.jar</extraClasspath>
</webAppConfig>
</configuration>
The documentation is not very consistent about that. But the javadoc is quite clear.
You can find relevant configuration examples on my jetty plugin wiki page.
Add the dependencies directly to the plugin's <dependencies/>. No need for scopes or anything -- they'll not enter your final artifact, but rather -- only be used by the Jetty plugin during execution.

how to let maven war plugin to create multiple war file

i used selenium-mave-plugin for integration test, which require the war file named: project.artifactId-version(say: myproj-0.1-SNAPSHOT.war) while the default war created by maven-war-plugin is project.artifactId.war(say myproj-SNAPSHOT.war).
in order to let selenium plugin, i override the maven-war-plugin in that selenium profile as:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-beta-1</version>
<configuration>
<warName>${project.artifactId}-${project.version}</warName>
</configuration>
</plugin>
now when i build the project, it failed at rpm:rpm, complaining:
source location ..../myProj.war does not exist
my question is if it's possible to create 2 war files: myProj.war and myProj-0.1-SNAPSHOT.war so both rpm and selenium plugins are happy? Thanks
For rpm plugin, please make sure you use the location directive. If you need further help, please post your full pom.xml.
As for selenium, it doesn't really need to know where your .war file resides. Only the web application server needs to know. Sadly, you didn't provide information in which phase of maven the "does not exist" error occured. So I can only guess it's while starting jetty, tomcat or another web application server.
You should run your full build (including tests) with: mvn clean verify integration-test rpm:prm.

Resources