what is the difference between run spring boot Application class and run it in Tomcat - spring-boot

My colleague create a spring boot project used 2.0.0.M7, when I run the project by run Application class in idea it cloud be stopped successfully, but if I run it in tomcat(war exploded)
in this case when I stop it I always get below error
Exception in thread "scheduler_Worker-7" Caused by: java.lang.ClassNotFoundException: Illegal access: this web application instance has been stopped already. Could not load [ch.qos.logback.core.status.WarnStatus]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1305)
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForClassLoading(WebappClassLoaderBase.java:1293)
java.lang.NoClassDefFoundError: ch/qos/logback/core/status/WarnStatus
at ch.qos.logback.classic.LoggerContext.noAppenderDefinedWarning(LoggerContext.java:186)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:264)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
at ch.qos.logback.classic.Logger.debug(Logger.java:482)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:612)
So what the difference between run Application class and run Tomcat, why run Tomcat could have the additional error when stop it?
In additional in very rare situation it also could be stopped successfully.

Your question has 2 parts.
Part 1: Running options
When you run by Tomcat (as you seen yellow Tom cat icon), you run/debug application on local/remote real server.
When you run by SpringBootApplication, it mean, fat JAR (executable JAR, with embedded Apache Tomcat 8.5.x server).
Part 2: Error what related Logback
Add dependencies
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>audit-client</artifactId>
<version>0.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>audit-common</artifactId>
<version>0.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>log4j-bridge</artifactId>
<version>0.9.7</version>
</dependency>
Let's me know what happen after apply the above solutions.

Related

Spring Boot logging with Log4j2

Written simple POC to prove and test Spring Boot and log4j2 compatibility. Once successful I will move it to real application.
Please refer my POC source code:
https://github.com/Dennyss/SpringBootLog4j2POC
I know/read about Spring version and log4j2 compatibility from:
How to set up Spring Boot and log4j2 properly?
Found and tried recommendations described here:
Spring-Boot logging with log4j2?
But still not working. The problem is that both application logs and Spring logs are printing to console only.
Please refer maven dependencies below (from POC):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
If I don't exclude Spring's logback and don't add boot-starter-log4j2 then application logs are printing to application file but Spring logs are not printing at all. I feel the problem somewhere with dependencies. Appreciate any help.
According to the Spring Boot Logging documentation, the location of the logging configuration file can be specified using the logging.config property. I noticed that your start.sh script is passing -Dlog4j.configurationFile. Normally, this would be sufficient for direct Log4J 2 integration, but Spring Boot uses logging.config.
After switching to this, it writes to the log files:
java -Dlogging.config=/share/LogPOC/log4j2.xml -cp poc.jar:libs/* com.poc.logger.Application

Why is the JSP page not rendered while deploying a SpringBoot App in Pivotal Web Services while it works fine with Thymeleaf and other views

The application is deployed in pivotal web services and when I hit the application with the link https://webstore.cfapps.io/, the login.jsp page is not rendered.
The same application runs successfully in the local server. I tried for searching the same issue but none of them solve the problem. I used both STS deployment and also tried cf command line for deploying separately but couldn't get the result.
I am giving you the details.
The error shown.
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat Jan 14 04:21:40 UTC 2017
There was an unexpected error (type=Not Found, status=404).
/WEB-INF/jsp/login.jsp
My pom file is
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
ecommerce.com
webstore
0.0.1-SNAPSHOT
jar
ecommerce-webstore
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.4.2.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot</groupId> spring-boot-starter-security</artifactId>
</dependency> -->
org.springframework.boot
spring-boot-starter-web
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
org.springframework.boot
spring-boot-maven-plugin
3.MY application.properties file is
spring.mvc.view.prefix:/WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
spring.datasource.url= jdbc:mysql://localhost:3306/ecommercestore
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
3.The manifest.yml generated after deployment is
applications:
name: webstore
memory: 1024M
host: webstore
domain: cfapps.io
buildpack: standard buildpack provided in git hub. I am not writing link
services:
cleardb
The result after giving the following command from cmd is
cf push webstore -p target/webstore-0.0.1-SNAPSHOT.jar --no-start
......................................................................
C:\Users\santosh dahal\Desktop\excellerant\ecommerce-webstore>cf push webstore -p target/webstore-0.0.1-SNAPSHOT.jar --no-start
Creating app webstore in org santosh-org / space Myspace as santoshdahal2072#gmail.com...
OK
Using route webstore.cfapps.io
Binding webstore.cfapps.io to webstore...
OK
Uploading webstore...
Uploading app files from: C:\Users\SANTOS~1\AppData\Local\Temp\unzipped-app904639435
Uploading 478.9K, 140 files
Done uploading
OK
6. I went to myapp in pivotal and started the application after binding the database cleardb to the same instant and application, the application runs successfully with the Running Status
7. the folder arrangement is as follows:
I have kept jsp pages in
src/main/webapp/WEB-INF/jsp/login.jsp
While the application.properties is in src/main/resources.
I will provide more details if needed. the github link for the code is
here
you are packaging it as a jar not as a war . In that case put your jsp files into static folder under resources or follow the below the link to understand better on the packaging aspect. But I feel it is better to package it as a war
Package a spring boot application including JSPs and static resources.
Also please check the jar generated before pushing the app to PWS whether jsp is avaibale at the requested path.

ValidationException with Spring boot and Jetty

I set up a spring boot application(1.4.0.RELEASE) with the following configuration
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
As expected, this ran with embedded Tomcat. I then thought of trying the same with a Jetty server and followed the steps mentioned in the documentation here:
Using Jetty instead of Tomcat
Basically excluding Tomcat and adding dependency for Jetty.Running mvn clean install from the command line or running the main method resulted in the following exception:
Caused by: javax.validation.ValidationException: HV000183: Unable to
load 'javax.el.ExpressionFactory'. Check that you have the EL
dependencies on the classpath, or use ParameterMessageInterpolator
instead
I could solve this by adding the following dependency in the pom.xml:
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
I am not directly using any validation related code but I suspect this is getting pulled from the spring boot jpa starter which pulls in Hibernate. I have also seen a discussion around this here: Similar issue
Questions:
1) Is this the right fix?
2) If it is the right fix, should the documentation be updated to add this dependency as well?
You are correct in using the javax.el dependency. When the JPA pulls in Hibernate as you stated, it will use the Hibernate Validator. It's specified here. This is the right fix. As for the documentation, I personally would raise it but I suspect not everyone will have the same issue. I still can run my mvn clean install without errors however if I run mvn spring-boot:run it starts up and shuts-down straight after.

Spring Boot Servlet API Version

I'm trying to run a Spring Boot app on Tomcat 7. From my understanding, it should be compatible with servlet 3.0 spec.
In my dependency, I mark tomcat as provided:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope> <!-- Mark as provided so it doesn't interfere when we deploy in container -->
</dependency>
Edit: And I've added the property <tomcat.version>7.0.59</tomcat.version>
But I still can't start it in tomcat. I'm getting this error:
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
at org.apache.tomcat.websocket.server.WsServerContainer.(WsServerContainer.java:147)
at org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131)
at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:47)
Which are because it apparently needs servlet spec 3.1.
Am I missing something?
The problem is, spring-boot also configure websocket support on spring-boot-starter-tomcat, which is includes by spring-boot-starter-web. And according to Apache, you must use Java 7 if you want web socket with Tomcat 7.
Here: http://tomcat.apache.org/whichversion.html
Either compile with Java 7 or exclude websocket support
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>
</exclusions>
</dependency>

Spring Boot WAR jolokia integration

According to the Spring Boot 1.2.3 Reference Docs.
Enabling jolokia seems to be as simple as adding as adding the following Maven dependency:
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
While this does work for a Spring Boot application packaged as a fat jar, I am unable to get this to work when packaged as a WAR file.
The root cause appears to be:
Caused by: java.lang.ClassNotFoundException: org.json.simple.JSONAware
I'm using STS for development purposes and deploying to an embedded pivotal tc Server 3.1. The dependency(json-simple-1.1.1.jar) containing the org.json.simple.JSONAware does appear under the Maven Dependency node so I'm not sure what the issue is.
So as I was composing the question I stumbled onto a solution that at least seems to work for me:
I took a look at the effective POM and found this dependency declaration:
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<optional>true</optional>
</dependency>
So for lack of better option I declared the following dependency explicitly
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<optional>false</optional>
</dependency>
Adding false to the the <optional> element seemed necessary.
Now I can access jolokia via the following url:
http://<myurl>:<myport>/<appcontext>/jolokia
Looking at 1.4.4 this seems to have been fixed:
<dependency>
<!-- Make json-simple non-optional.
It is marked optional in boot-dependencies, but required by jolokia-core.
Without this fix it would be missing when used war-packaging. -->
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<optional>false</optional>
</dependency>
Yet I'm seeing similar issues running a war in JBoss.

Resources