Can I serve JSPs from inside a JAR in lib, or is there a workaround?
Servlet 3.0 which Tomcat 7 supports includes the ability to package jsps into a jar.
You need to:
- place your jsps in
META-INF/resources
directory of your jar - optionally include a
web-fragment.xml
in theMETA-INF
directory of your jar - place the jar in
WEB-INF/lib
directory of your war
You should then be able to reference your jsps in your context. For example if you have a jsp META-INF/resources/test.jsp
you should be able reference this at the root of your context as test.jsp
How to include JSP from jar lib
I know of only one way.
- Keep the JSP in
/META-INF/resources
folder. - Create a 'lib' folder inside the WEB-INF folder in your WAR.
- Place the JAR (containing the JSP in the
/META-INF/resources
folder) in the lib folder of the WAR. - In the main JSP where you want to include this external JSP residing in the JAR, use the following statement:
<jsp:include page="/myJSP.jsp" ></jsp:include>
. Note that the '/' is required in front of the jsp file name to make the container look for the JSP in an absolute path (and hence in the jar in the lib folder) rather than in the current path where the main JSP is lying.
This will surely work.
Spring boot: resolve JSPs from jar dependencies
I don't think it is worth to publish the whole pom.xml
, but here is the maven-dependency-plugin
section that works in my case:
<!-- ... -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<!-- this skip property is set by maven profile in same pom.xml - no magic here -->
<skip>${exclude.some_submodule}</skip>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>some_submodule</artifactId>
<version>${project.version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<!-- there are webapp/view/*.jsp files in some_module's structure -->
<includes>view/**</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<!-- ... -->
The only problem here is that it works only when you launch the executable .war
. Launching this application from IDE (IntelliJ IDEA) need some additional steps to be made. And that's another one disadvantage of this solution, to my mind. The first one is a dirty pom.xml
.
TL;DR
Solution:
BUT!. I have found another solution that is more suitable, I think.
Actually I have moved from Tomcat to Jetty, and solution above works fine even there. There's no need in hacking the build anymore.
Now I put my .jsp
files into src/main/webapp/META-INF/resources/view/some_module
folder in some_module dependency and resolve it by path 'some_module/someJsp' via standard Spring's @Controller
s.
I apologize that I haven't found this topic earlier. Now this is a duplicate. But who knows, maybe someone will apply solution with maven dependency plugin.
Is it possible with Spring Boot to serve up JSPs with a JAR packaging?
As @Andy Wilkinson said, there are limitations related to JSP. Please package your application as war
and execute as jar
. This is documented at spring site.
With Tomcat it should work if you use war packaging, i.e. an executable war will work (...). An executable jar will not work because of a hard coded file pattern in Tomcat.
- 27.3.5 JSP limitations
- jsp sample
Deprecated, old answer
Yes, this is possible with Spring Boot.
Take look at this example: https://github.com/mariuszs/spring-boot-web-jsp-example.
For doing this use spring-boot-maven-plugin or gradle equivalent.
With this plugin jar is executable and can serve JSP files.
$ mvn package
$ java -jar target/mymodule-0.0.1-SNAPSHOT.war
(Note the extension of the artifact in the above command .war)
or just
$ mvn spring-boot:run
Tomcat hot reload of JSP file that is inside a JAR of an exploded webapp
I noticed that Tomcat DOES recompile jsp and tag files inside JAR files.
However, "Package File" action of IntelliJ, which updates the file in the JAR, is not enough for this.
To recompile jsp and tag files in a JAR from a dependency, I have to
- compile the dependency project
- In the example, go to
core
project and runmvn install
- In the example, go to
- package the webapp project
- In the example, go to
webapp-demo
project and runmvn package
- In the example, go to
Tomcat then notices the changed JAR and recompiles the jsp and tag files.
Note that it does not work, when running mvn package
in core
project. It seems like Tomcat is missing something, when the dependency project is packaged but not build.
Note further that Tomcat seems to recompile all jsp and tag files in the JAR in this case. Maybe even further files from later projects that depend on these. Thus, in my case recompilation of the jsp and tag files of the changed JAR takes nearly as long as deploying the webapp from scratch.
Tested with Tomcat 9.0.50 and Maven 3.6.0
Web application in other web application
Of course you can do that:
1) Create Servlet classes / JSP files
. Package them all in a jar
file. Don't include web.xml
or any other files.
2) Import the jar
in your web application classpath
.
3) Configure Servlet classes
and JSP files
in your web.xml
as below:
For JSP:
<servlet>
<servlet-name>MyJSPFile</servlet-name>
<jsp-file>/path/to/jsp/MyJSP.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>MyJSPFile</servlet-name>
<url-pattern>/MyJSP.jsp</url-pattern>
</servlet-mapping>
For Servlet:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>my.servlet.classpath.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet.do</url-pattern>
</servlet-mapping>
Related Topics
What Is the Equivalent of Java Static Methods in Kotlin
Java - How to Receive Point Coordinates After Mouse Button Release (Jfreechart)
How to Create a Hashmap with Two Keys (Key-Pair, Value)
Find a Class Somewhere Inside Dozens of Jar Files
How to Write a Compareto Method Which Compares Objects
Method Overload Resolution in Java
Comparing and Thencomparing Gives Compile Error
Differences Between Java 8 Date Time API (Java.Time) and Joda-Time
How to Manually Set an Authenticated User in Spring Security/Springmvc
Hash String via Sha-256 in Java
Comparing Time Is Incorrect When Picking 12:00
Java.Util.Date to Xmlgregoriancalendar
How to Convert from Cmyk to Rgb in Java Correctly