JSPs, static content, SpringBoot jars and IntelliJ - spring-boot

So I'm developing in IntelliJ a spring boot app. Using Gradle, I'm creating the sprint boot jar file.
I'm having problems figuring out where to put the jsps and static content such as .js files in such a way that running the jar AND running from within IntelliJ works!
It seems that in order to get SpringBoot to find jsps in a jar file I need to put the jsps inside a src/main/resources/META-INF/resources directory. For example, META-INF/resources/WEB-INF/index.jsp. I'm pretty sure the WEB-INF is now meaningless.
However, if I try to run this spring boot app from within IntelliJ, it cannot find the jsp. 404, blah blah blah. I actually have to put the jsps in the war-style webapp directory in src/main. However that directory is totally ignored during the spring boot jar build.
So.. how do developers set up their development environments that is both IntelliJ and, say, gradle bootRun friendly?

There is a guide here which should work both in IntelliJ IDEA and in the command line via the war file which can be executed as a jar (via java -jar).

As per spring boot there are Limitations when it comes to jsp's.
To overcome these limitations we need to have the configuration made in the application to render jsp by placing the jsp's under src/main/resources/META-INF/resources/WEB-INF/jsp folder.
Sample Code: Click Here
References:
https://dzone.com/articles/spring-boot-with-jsps-in-executable-jars-1
https://github.com/hengyunabc/spring-boot-fat-jar-jsp-sample

Related

Spring Boot Maven plugin: What does it actually do?

Can someone give me an understanding of what the Spring Boot Maven plugin actually does? I have been Googling, but most of what I find doesn't give a clear picture.
The impression I have so far is that it can create a "fully executable" jar that does not need to be run via java -jar, and that it's also possible to make a more traditional jar that you would run via java -jar. I'm sure there are other variations of what it can produce as well.
I'm also under the impression that it can package up dependencies and resources. It's not at all clear to me how the resources are "accessed" by the application when it's run.
In either of the outcomes described above do I need just the jar and nothing else (i.e. no resource files, dependency jars, etc.)? In other words, is the jar self-contained? When I've opened the jar up, it does seem that everything it needs is there. Is that really the case?
Now, let's go a little further towards what I'm trying to do. I am writing a set of Spring services with REST APIs. Each service will be run in its own VM (or container - future). The services are packaged into a single jar and the service to be used is selected via Spring profile (i.e. spring.profiles.active=a-profile).
The way I've done things like this before has been to use the Maven assembly plugin to produce an archive (zip) for each separate service and inlcude all of the necessities (dependency jars, resource files, etc.). I'd place it where needed, unpack it, tweak some configuration and run it via an included script.
I'm getting the impression that's not "how it's done" when the Spring Boot Maven plugin is involved.
The Spring Boot Maven Plugin provides Spring Boot support in Maven, letting you package executable jar or war archives and run an application “in-place”.
It builds the uber jar which bundles in Tomcat along with your app. If you inspect the contents of the jar with jar -tf <file_name> you will see that the format is a bit different. The Spring Boot classes look normal, but then your project's files are inside a BOOT-INF folder.

How to create deployable springboot war

I am trying to create a maven spring boot application to be deployed in Tomcat. I am following what is suggested in Spring docs and other stackoverflow suggestions- war, Application.java extending SpringBootServletInitializer, removing spring-boot-maven-plugin from build plugins etc. War file is generated and is deployed in tomcat. But what I found is all static files are packaged under /WEB-INF/classes folder and I am not able to access the page. My project structure is as below:
Can anybody tell me how I can package the war properly to be deployed in Tomcat.
That doesn't change anything.
If you put your static assets in src/main/resources/static (and they end up in WEB-INF/classes/static), Spring Boot will serve them properly. So a src/main/resources/static/foo.png will be available at http://localhost:8080/your-context/foo.png if the context of your webapp is your-context.
Regarding the configuration, you can also go on start.spring.io, click advanced and chose war and you'll get an empty project pre-configured.
Or you can click this: https://start.spring.io/#!packaging=war
The issue is because of version issue. I compiled the application with Java 8 and deployed it in tomcat running under JRE 7. It may help someone facing the same issue.
I got the clue from the below post:
Spring boot war file deploy on Tomcat.

The gradle can build runnable jar made by spring boot to war file?

I made my application using spring boot. It use embedded servlet container using tomcat library and run as application. Because I use spring boot annotation in main class for running. I used it in the local, But I have to make this application buidld war file to send the remote server where tomcat instance is listening.
First, I want to ask this gradle plugin I found can to it to generate the war file even if it have a main class and doesn't follow original webapp style
Second, Is there any other gradle plugin to send the war to the remote server and make tomcat redeploy the war file I sent?
Thanks in advance.
It seems to me that you have the answer to your first question in the documentation. Spring Boot war is nothing different from traditional war so I am not sure I understand what you mean. Perhaps Converting a Spring Boot JAR Application to a WAR would help?
For your second question gradle remote deploy war on Google gave me this

Spring Boot Gradle - avoid lib-provided folder in war file

I have a Spring Boot based application and I'm trying to switch over from Maven to Gradle. The application is supposed to build a war file, which is deployed to a web server (WildFly in our case).
Now, I have some libraries provided by the web server and thus using a "providedCompile" scope (For hibernate search and infinispan). Now, when used with Spring Boot plugin, the plugin is creating the war file with all the "providedCompile" libraries moved to a folder named "lib-provided".
How do I avoid this? On the same context, it is also adding the Spring Boot loader classes on to the war file. If possible, I need to avoid this too.
Please help! Thanks!
If you're only ever going to deploy your application as a WAR file to an app server, then you don't need it to be turned into an executable archive. You can disable this repackaging in your build.gradle file:
bootRepackage {
enabled = false
}

IntelliJ + Tomcat + Spring-Loaded

I would like to try out Spring Source's "Spring Loaded" class reloading agent, with Tomcat run via IntelliJ.
https://github.com/SpringSource/spring-loaded
I've added the JVM arguments to my Tomcat run configuration, and my webapp starts up without errors and seems to behave normally.
I'm not really sure how to trigger the class reloading though. Do I just need to compile the classes that I modify? I've tried that and that didn't seem to work. Do I need to update Tomcat and deploy classes and resources? That doesn't seem to work either...?
Any specific configuration details would be greatly appreciated.
EDIT: More info, I think my problem may have to do with using two modules, one a core code library, and one the webapp. I use Maven for both, one configured as a jar project and the other as a war project. IntelliJ sets up the Artifact for the exploded war to use the jar module's jar file. I've tried switching the Artifact config to incorporate the jar module's compiled output into WEB-INF/classes instead. Now I see the .class files in target/webapp/WEB-INF/class/etc. But I'm not sure how to get IntelliJ to update a specific class file when I edit it.
If you added the following jvm parameters (as described at the springloaded page) to your tomcat
-javaagent:<pathTo>/springloaded-{VERSION}.jar -noverify SomeJavaClass
you should be fine. It may help to disable auto reloading in tomcat for the webapp you are testing. For exmaple in your server.xml:
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Context docBase="projekt" path="/projekt" reloadable="false" ...
This ensures that only the springloaded classloader loads changed classes.
spring loaded cannot hotswap jars.
Put web fragment output into webapp/WEB-INF/classes
Also spring loaded support only spring 4.1
https://github.com/spring-projects/spring-loaded/issues/139

Resources