Is it possible with Spring Boot to serve up JSPs with a JAR packaging?
If your springboot is building your project and running it in local server correctly then YES.
What you need to do is to build the project using
mvn -U clean package
.
Then in target folder you have your runnable xxxx.jar . Now what you have to do is put your xxxx.jar file in the server or where you want along with the src/main/webapp/WEB-INF/jsp/
*.jsp files in same hierarchy.
then try java -jar xxxx.jar
Your project will run with no issue.
`
.
├── src
│ └── main
│ └── webapp
│ └── WEB-INF
│ ├── jsp
│ │ ├── default.jsp
│ │ ├── help.jsp
│ │ ├── index.jsp
│ │ ├── insert.jsp
│ │ ├── login.jsp
│ │ ├── modify.jsp
│ │ ├── search.jsp
│ │ └── show.jsp
│ └── web.xml
├── xxx.jar
└── xxx.jar.original`
java -jar xxx.jar
<pre>
$java -jar xxx.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.4.RELEASE)
2017-09-05 19:31:05.009 INFO 10325 --- [ main] com.myapp.app.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT on dipu-HP with PID 10325 (/home/dipu/Documents/workspace-sts/jspjartest/xxx.jar started by dipu in /home/dipu/Documents/workspace-sts/jspjartest)
2017-09-05 19:31:05.014 INFO 10325 --- [ main] com.myapp.app.DemoApplication : No active profile set, falling back to default profiles: default
2017-09-05 19:31:05.138 INFO 10325 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5e91e4: startup date [Tue Sep 05 19:31:05 IST 2017]; root of context hierarchy
2017-09-05 19:31:07.258 INFO 10325 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8090 (http)
2017-09-05 19:31:07.276 INFO 10325 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2017-09-05 19:31:07.278 INFO 10325 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.15
2017-09-05 19:31:08.094 INFO 10325 --- [ost-startStop-1] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2017-09-05 19:31:08.396 INFO 10325 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-09-05 19:31:08.401 INFO 10325 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3267 ms
2017-09-05 19:31:08.615 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2017-09-05 19:31:08.617 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'loginServlet' to [/loginServlet/]
2017-09-05 19:31:08.618 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'uploadController' to [/uploadController/]
2017-09-05 19:31:08.622 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-09-05 19:31:08.622 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-09-05 19:31:08.623 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-09-05 19:31:08.623 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-05 19:31:09.137 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5e91e4: startup date [Tue Sep 05 19:31:05 IST 2017]; root of context hierarchy
2017-09-05 19:31:09.286 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/user-management]}" onto java.lang.String com.myapp.app.DemoController.user()
2017-09-05 19:31:09.288 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto java.lang.String com.myapp.app.DemoController.reload()
2017-09-05 19:31:09.290 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/show]}" onto java.lang.String com.myapp.app.DemoController.show()
2017-09-05 19:31:09.292 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/modify]}" onto java.lang.String com.myapp.app.DemoController.modify()
2017-09-05 19:31:09.293 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin]}" onto java.lang.String com.myapp.app.DemoController.admin()
2017-09-05 19:31:09.294 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login]}" onto java.lang.String com.myapp.app.DemoController.login()
2017-09-05 19:31:09.294 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/faq-management]}" onto java.lang.String com.myapp.app.DemoController.faq()
2017-09-05 19:31:09.294 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/subject-area]}" onto java.lang.String com.myapp.app.DemoController.subject()
2017-09-05 19:31:09.295 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/Chat]}" onto java.lang.String com.myapp.app.DemoController.index()
2017-09-05 19:31:09.295 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/delete]}" onto java.lang.String com.myapp.app.DemoController.delete()
2017-09-05 19:31:09.296 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/result]}" onto java.lang.String com.myapp.app.DemoController.result()
2017-09-05 19:31:09.296 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/insert]}" onto java.lang.String com.myapp.app.DemoController.insert()
2017-09-05 19:31:09.300 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/fileUpload]}" onto java.lang.String com.myapp.app.DemoController.file()
2017-09-05 19:31:09.301 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/search]}" onto java.lang.String com.myapp.app.DemoController.search()
2017-09-05 19:31:09.301 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/help]}" onto java.lang.String com.myapp.app.DemoController.help()
2017-09-05 19:31:09.312 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/LoginServlet]}" onto public void com.myapp.app.LoginServlet.LoginServlet.doPost(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2017-09-05 19:31:09.313 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/image],methods=[GET],produces=[text/html;charset=UTF-8]}" onto public java.lang.String com.myapp.app.controller.ImageController.image()
2017-09-05 19:31:09.316 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/authenticate],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.authenticate(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.317 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/searchCompany],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.getCompany(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.318 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/executeQuery],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.executeQuery(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.318 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/insertData],methods=[POST]}" onto public int com.myapp.app.controller.AjaxController.insertResources(java.lang.String,java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.319 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/showData],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.showResources(java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.319 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/searchData],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.getSearchData(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.319 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/deleteData],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.deleteData(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.320 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/modifyData],methods=[POST]}" onto public int com.myapp.app.controller.AjaxController.modifyData(java.lang.String,java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.322 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/suggestWords],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.suggestWords(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.322 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/authenticateUser],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.authenticateUser(java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.323 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/insertJson],methods=[POST]}" onto public int com.myapp.app.controller.AjaxController.insertJsonResources(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.323 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/getvalue],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.getResource(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.324 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/searchQuery],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.getResources(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.330 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/upload],methods=[POST]}" onto public void com.myapp.app.controller.UploadController.doPost(org.springframework.web.multipart.MultipartFile,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2017-09-05 19:31:09.333 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-09-05 19:31:09.334 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-09-05 19:31:09.388 INFO 10325 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-05 19:31:09.388 INFO 10325 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-05 19:31:09.461 INFO 10325 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-05 19:31:09.752 INFO 10325 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-09-05 19:31:09.861 INFO 10325 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8090 (http)
2017-09-05 19:31:09.867 INFO 10325 --- [ main] com.myapp.DemoApplication : Started DemoApplication in 5.349 seconds (JVM running for 5.866)
</pre>
here the server is running
$ curl 127.0.0.1:8090/login
Welcome to Login page
My POM.xml
<code>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myapp</groupId>
<artifactId>app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Jsp Springboot</name>
<description>Jsp Springboot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- Need this to compile JSP,
tomcat-embed-jasper version is not working, no idea why -->
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>rest</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>
</project>
</code>
my application.properties
<code>
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
server.port=8090
</code>
My Project Structure
<code>
.
├── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── myapp
│ │ └── app
│ │ ├── mynewapp
│ │ ├── controller
│ ├── resources
│ │ └── static
│ │ ├── assets
│ │ │ ├── css
│ │ │ │ ├── fonts
│ │ │ │ └── lib
│ │ │ ├── img
│ │ │ └── js
│ │ │ └── lib
│ │ ├── css
│ │ │ └── img
│ │ ├── fonts
│ │ ├── images
│ │ └── js
│ │ └── img
│ └── webapp
│ └── WEB-INF
│ ├── jsp
│ └── lib
</code>
Thank You.
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