AspectJ LTW (weaving) not working with Spring Boot - spring

I'm on Spring Boot 2.1.2.RELEASE - Java 11 - Fat JAR
Following the documentation, I have:
added the required dependencies to the Gradle build
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.aspectj:aspectjrt:1.9.2'
implementation 'org.aspectj:aspectjweaver:1.9.2'
enabled LoadTimeWeaving
#SpringBootApplication
#EnableLoadTimeWeaving
public class MyApplication { ... }
provided the aop.xml under META-INF
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<!-- only weave classes in our application-specific packages -->
<include within="my.base.package.*" />
</weaver>
<aspects>
<!-- weave in just this aspect -->
<aspect name="my.base.package.spring.aop.MyAspects" />
</aspects>
</aspectj>
created the new #Aspect class
#Aspect
public class MyAspects {
#Around("methodsToBeProfiled()")
public Object profile(final ProceedingJoinPoint pjp) throws Throwable {
final var sw = new StopWatch(getClass().getSimpleName());
try {
sw.start(pjp.getSignature().getName());
return pjp.proceed();
} finally {
sw.stop();
System.out.println(sw.prettyPrint());
}
}
#Pointcut("execution(* my.base.package.other.MyClass.*(..))")
public void methodsToBeProfiled() {}
}
added the Jar for instrumentation
-javaagent:/home/myuser/spring-instrument-5.1.5.RELEASE.jar
Log, which as you see, show MyAspects as recognized
[AppClassLoader#2c13da15] info AspectJ Weaver Version 1.9.2 built on Wednesday Oct 24, 2018 at 15:43:33 GMT
[AppClassLoader#2c13da15] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader#2c13da15
[AppClassLoader#2c13da15] info using configuration /home/edoardo/IdeaProjects/scheduler/scheduler-engine/out/production/resources/META-INF/aop.xml
[AppClassLoader#2c13da15] info using configuration file:/home/edoardo/.gradle/caches/modules-2/files-2.1/org.springframework/spring-aspects/5.1.5.RELEASE/3bb95e05b646ef93e2a4cf0b600924c2979fc723/spring-aspects-5.1.5.RELEASE.jar!/META-INF/aop.xml
[AppClassLoader#2c13da15] info register aspect my.base.package.spring.aop.MyAspects
[AppClassLoader#2c13da15] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
[AppClassLoader#2c13da15] info register aspect org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect
[AppClassLoader#2c13da15] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
[AppClassLoader#2c13da15] info register aspect org.springframework.transaction.aspectj.JtaAnnotationTransactionAspect
[AppClassLoader#2c13da15] info deactivating aspect 'org.springframework.transaction.aspectj.JtaAnnotationTransactionAspect' as it requires type 'javax.transaction.Transactional' which cannot be found on the classpath
[AppClassLoader#2c13da15] info register aspect org.springframework.cache.aspectj.AnnotationCacheAspect
[AppClassLoader#2c13da15] info register aspect org.springframework.cache.aspectj.JCacheCacheAspect
[AppClassLoader#2c13da15] info deactivating aspect 'org.springframework.cache.aspectj.JCacheCacheAspect' as it requires type 'org.springframework.cache.jcache.interceptor.JCacheAspectSupport' which cannot be found on the classpath
[AppClassLoader#2c13da15] info deactivating aspect 'org.springframework.cache.aspectj.JCacheCacheAspect' as it requires type 'javax.cache.annotation.CacheResult' which cannot be found on the classpath
[AppClassLoader#2c13da15] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
However MyAspects is never instantiated (so no debug), and methods are not being weaved with my aspect code.
Did I miss something?
Edit: seems both Jars, aspectjweaver and spring-instrument are required as agents. Is this normal?

You do need the aspectjweaver agent jar. You don't need spring-instrument (ever for a fat jar - AFAIK it was used in app servers to work around some historical issues with their class loaders). You also don't need to #EnableLoadTimeWeaving (also an app server feature, redundant if you control the agent). Also (minor niggle) aspectjrt is a transitive dependency of aspectjweaver, so you don't need both. So you have it working it seems, even though you have done more work than you needed. Sample Spring Boot apps with various weaving options: here.

Related

Problem with Google Cloud Pub/Sub API and Spring boot application

I write spring boot application for subscribing Google cloud Pub/Sub topic for this I use Google's tutorial, but when I run application I have get this error
2019-02-02 18:03:10.248 INFO 15080 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2019-02-02 18:03:10.271 INFO 15080 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-02-02 18:03:10.610 ERROR 15080 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of method messageChannelAdapter in tech.garoon.cloud.CloudApplication required a bean of type 'org.springframework.cloud.gcp.pubsub.core.PubSubTemplate' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.cloud.gcp.pubsub.core.PubSubTemplate' in your configuration.
Process finished with exit code 1
How Can I solve this problem?
GcpPubSubAutoConfiguration provides autoconfiguration feature of creating necessary beans including PubSubTemplate. In your case, somethng is missed, Kindly ensure that dependencies are in place or recreate following bean to make it work.
#Bean
public PubSubTemplate pubSubTemplate(PubSubPublisherTemplate pubSubPublisherTemplate,
PubSubSubscriberTemplate pubSubSubscriberTemplate) {
return new PubSubTemplate(pubSubPublisherTemplate, pubSubSubscriberTemplate);
}
Additionally, make sure GcpContextAutoConfiguration is created based on below properties in application.properties.
spring.cloud.gcp.credentials.location=${gcp_credentials}
starter dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
</dependency>
Solution
I added this dependency
implementation 'org.springframework.cloud:spring-cloud-gcp-autoconfigure:1.1.0.RELEASE'
My dependencies
dependencies {
implementation 'org.springframework.cloud:spring-cloud-gcp-pubsub:1.1.0.RELEASE'
implementation 'org.springframework.cloud:spring-cloud-gcp-autoconfigure:1.1.0.RELEASE'
implementation "org.springframework.boot:spring-boot-starter-web:2.1.2.RELEASE"
implementation 'org.springframework.integration:spring-integration-core:5.1.2.RELEASE'
}
if using external configuration class that is registering your channels, message handlers etc, make sure to annotate the configuration class with #Import({GcpPubSubAutoConfiguration.class})
#Configuration
#Import({GcpPubSubAutoConfiguration.class})
public class PubSubConfig{
}
I ran into this issue with these versions of spring-boot and spring-cloud-gcp-starter-pub:
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
and in my application.properties I had
spring.cloud.gcp.pubsub.enabled=false for local development.
I removed spring.cloud.gcp.pubsub.enabled=false and it worked. Although now it creates a connection to the pubsub gcp topic, so for local development, you will need to comment out publishing, to avoid sending messages.

wildfly 12 and spring java config, not working , 403 error

I am trying since few hours to bring this simple application to work on wildfly 12, which was working fine on tomcat. Any how below is log and config
Webappinitializer
#Configuration
public class ListenerConfig implements WebApplicationInitializer{
#Override
public void onStartup(final ServletContext servletContext) throws ServletException {
final AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
root.setServletContext(servletContext);
root.scan("com.app");
root.refresh();
final Dynamic servlet = servletContext.addServlet("spring", new DispatcherServlet(root));
servlet.setLoadOnStartup(1);
servlet.addMapping("/*");
servletContext.addListener(new ContextLoaderListener(root));
}
ApplicationConfig
#Configuration
#ComponentScan(basePackages = "com.app")
#PropertySource(value = { "classpath:jdbc.properties" })
#EnableTransactionManagement
public class ApplicationConfig {
MVCConfig
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter{
#Override
public void configureMessageConverters( List<HttpMessageConverter<?>> converters ) {
converters.add(converter());
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/html/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
jboss-deployment-structure.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="javax.api"/>
<module name="javax.jms.api"/>
<module name="javax.servlet.api"/>
<module name="org.apache.log4j"/>
<module name="pluto.lib" />
</dependencies>
</deployment>
</jboss-deployment-structure>
Note I haven't provided complete code, if required will post it.
Finally what I get in log is below
22:36:39,374 INFO [org.jboss.as.connector.subsystems.datasources]
(MSC service thread 1-2) WFLYJCA0001: Bound data source
[java:jboss/datasources/ExampleDS] 22:36:40,290 INFO
[org.wildfly.extension.undertow] (MSC service thread 1-4) WFLYUT0006:
Undertow HTTPS listener https listening on 127.0.0.1:8443 22:36:40,504
INFO [org.jboss.ws.common.management] (MSC service thread 1-3)
JBWS022052: Starting JBossWS 5.2.0.Final (Apache CXF 3.2.2)
22:36:43,005 INFO [org.infinispan.factories.GlobalComponentRegistry]
(MSC service thread 1-4) ISPN000128: Infinispan version: Infinispan
'Bastille' 9.1.6.Final 22:36:43,650 INFO
[org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 62)
WFLYCLINF0002: Started client-mappings cache from ejb container
22:36:44,314 INFO [org.wildfly.extension.undertow] (ServerService
Thread Pool -- 64) WFLYUT0021: Registered web context: '/Pluto' for
server 'default-server' 22:36:44,412 INFO [org.jboss.as.server]
(ServerService Thread Pool -- 37) WFLYSRV0010: Deployed "Pluto.war"
(runtime-name : "Pluto.war") 22:36:44,857 INFO [org.jboss.as.server]
(Controller Boot Thread) WFLYSRV0212: Resuming server 22:36:44,863
INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http
management interface listening on http://127.0.0.1:9990/management
22:36:44,863 INFO [org.jboss.as] (Controller Boot Thread)
WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
Pluto.war is application and I get 403 forbidden, I have tried multiple things, What I feel is Jboss is not able to pick dispatcher servlet at all, I have used spring with jboss as 7.1, but then it was xml config, I do not use maven so no pom.xml here, this same config is running fine in tomcat 8.
After removing custom lib and placed all the libs in web-inf/lib folder and deleted jboss-deployment-structure.xml from web-inf then its working fine. What wrong am I doing, in case of custom module? I created pluto.lib.main under modules folder and added this in standalone.xml
<subsystem xmlns="urn:jboss:domain:ee:4.0">
<global-modules>
<module name="pluto.lib" slot="main"/>
</global-modules>
Then I am facing 403 error
After a long pain-full debugging along with trial and error with different versions of spring and wild fly, I have come to a conclusion that my custom module which consists of spring 4.3 is not running on wildfly 12.
Anyhow the solution was to downgrade app server to wildfly 11. The very same module and .war runs smoothly on ver 11.
I enabled debug logs on ver 12, still there nothing in logs that could probably show the root cause, I think there is some bug associated to wildfy version 12 and spring.
As of now this seems to work fine, if anyone who is able to find solution for spring with java config on wildfly 12, please post an answer :)

Spring boot embedded tomcat logs

i'm using spring boot embedded tomcat with spring boot 1.5.9 ,
im also using Log4j2.
recently i exerience problems during load, so i want to understand better the tomcat logs [Not the access Logs] , i tried (in application.properties) :
logging.level.org.apache.tomcat: INFO
logging.level.org.apache.catalina: INFO
but none of the above worked. is there any other way to achieve it ?
Found it !! You are now able to see the internal Logs of Embedded Tomcat in your App's Log4j log file with 3 easy steps:
1] add to your pom:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
</dependency>
2] add to your running arg a new JVM param , e.g:
java -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager -jar target/demo-0.0.1-SNAPSHOT.jar
3] add to your application.properties:
logging.level.org.apache=DEBUG
Enjoy Life ! :)
Explaination:
the problem is because Log4j log levels is not propagated into JUL (which is the actual Logging way Embedded tomcat use) so the above achieves this connection with JUL and Log4j log levels.
Reference:
After reading the Spring boot 1.5.10 release notes (which is not required for the solution) i saw the new documentation that shed light how to achive it and explaination about it:
https://github.com/spring-projects/spring-boot/issues/2923#issuecomment-358451260
I struggled a lot,and didnt find anything of my help.Utlimately I had build "WAR" out of my spring boot application.Deploy it to tomcat instance and
followed below steps,which redirected all the internal tomcat logs(JULI) logs to my application log file.
Delete existing JULI library (CATALINA_HOME/bin/tomcat-juli.jar file) and the existing Tomcat Java Logging configuration file (CATALINA_HOME/conf/logging.properties).
Download JULI Log4j Tomcat library (tomcat-juli.jar) from the Tomcat downloads’ Extras section (http://tomcat.apache.org/download-70.cgi). Place the downloaded file to CATALINA_HOME/bin directory.
Download Tomcat JULI adapters library (tomcat-juli-adapters.jar) from the Tomcat downloads’ Extras section. Place this file in the CATALINA_HOME/lib directory.
Download Log4j (version 1.2 or later), and place the downloaded library file to CATALINA_HOME/lib directory.
Create the Log4j configuration file at the following location: CATALINA_HOME/lib/log4j.properties. Check below log4j configuration matching the default Java Logging configuration.
Restart Tomcat.
Log4j configuration File Matching the Default Tomcat Logging Settings:
log4j.rootLogger=INFO, CATALINA
//Define all the appenders log4j.appender.CATALINA=org.apache.log4j.DailyRollingFileAppender
log4j.appender.CATALINA.File=${catalina.base}/logs/catalina.
log4j.appender.CATALINA.Append=true log4j.appender.CATALINA.Encoding=UTF-8
//Roll-over the log once per day
log4j.appender.CATALINA.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.CATALINA.layout = org.apache.log4j.PatternLayout
log4j.appender.CATALINA.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.LOCALHOST=org.apache.log4j.DailyRollingFileAppender
log4j.appender.LOCALHOST.File=${catalina.base}/logs/localhost.
log4j.appender.LOCALHOST.Append=true log4j.appender.LOCALHOST.Encoding=UTF-8
log4j.appender.LOCALHOST.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.LOCALHOST.layout = org.apache.log4j.PatternLayout
log4j.appender.LOCALHOST.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.MANAGER=org.apache.log4j.DailyRollingFileAppender
log4j.appender.MANAGER.File=${catalina.base}/logs/manager.
log4j.appender.MANAGER.Append=true log4j.appender.MANAGER.Encoding=UTF-8
log4j.appender.MANAGER.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.MANAGER.layout = org.apache.log4j.PatternLayout
log4j.appender.MANAGER.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.HOST-MANAGER=org.apache.log4j.DailyRollingFileAppender
log4j.appender.HOST-MANAGER.File=${catalina.base}/logs/host-manager.
log4j.appender.HOST-MANAGER.Append=true log4j.appender.HOST-MANAGER.Encoding=UTF-8
log4j.appender.HOST-MANAGER.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.HOST-MANAGER.layout = org.apache.log4j.PatternLayout
log4j.appender.HOST-MANAGER.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Encoding=UTF-8
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
//Configure which loggers log to which appenders
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].
[localhost]=INFO,
LOCALHOST
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].
[localhost].[/manager]=INFO,MANAGER
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].
[localhost].[/host-manager]=
INFO, HOST-
MANAGER
You can also check a adapter avaiable on GIT # link
In your spring boot application,you can make changes like adding and removing jars,folder from embedded Tomcat server Or even adding custom config files to it using TomcatEmbeddedServletContainerFactory.class ,of spring boot.
For slf4j and Spring Boot 2 hide exceptions from Tomcat and handle them by yourself:
Add to pom:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
Add to config:
#PostConstruct
void postConstruct() {
SLF4JBridgeHandler.install();
}
Add to application.yaml
logging:
level:
org.apache.catalina: off
Handle exception in ErrorController
#Controller
#Slf4j
public class ErrorController implements
org.springframework.boot.web.servlet.error.ErrorController {
private static final String ERROR_PATH = "/error";
#Autowired
private ErrorAttributes errorAttributes;
#Override
public String getErrorPath() {
return ERROR_PATH;
}
#RequestMapping(ERROR_PATH)
public ModelAndView error(HttpServletRequest request) {
return processException(errorAttributes.getError(new ServletWebRequest(request)));
}
}
Default configurations are provided for Java Util Logging, Log4J, Log4J2 and Logback. In each case loggers are pre-configured to use console output with optional file output also available
refer this link : https://stackoverflow.com/questions/31939849/spring-boot-default-log-location/31939886
The embedded tomcat in spring boot internally echoes logs to console.
The default log configuration will echo messages to the console as they are written. So until you explicitly specify a file as you described, it stays in the Console.
From the spring boot logging doc.
You can custmize the logging as per your need.
A log file, generated by org.apache.catalina.valves.AccessLogValve, usually named something like localhost_access_log can be configured like this:
#Configuration
public class EmbeddedTomcatConfig {
#Bean
public TomcatEmbeddedServletContainerFactory containerFactory() {
TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory = new TomcatEmbeddedServletContainerFactory();
AccessLogValve accessLogValve = new AccessLogValve();
// set desired properties like
accessLogValve.setDirectory(...);
tomcatEmbeddedServletContainerFactory.addEngineValves(accessLogValve);
return tomcatEmbeddedServletContainerFactory;
}
}
Or, much better with Spring Boot 2:
#Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> customizer() {
return container -> {
AccessLogValve accessLogValve = new AccessLogValve();
// set desired properties like
accessLogValve.setDirectory("...");
container.addEngineValves(accessLogValve);
};
}

SpringRunner ignores application properties

I am trying to create Spring integration tests as follow:
#RunWith(SpringRunner::class)
#ActiveProfiles(profiles = ["Test"])
#ContextConfiguration(locations = ["classpath:**/applicationContext.xml"])
open class SimpleEntityIT {...}
applicationContact.xml contains:
<context:annotation-config/>
<context:spring-configured/>
<context:property-placeholder
ignore-resource-not-found="false"
location="classpath:application${spring.profiles.active}.properties,classpath:application.properties"/>
<context:component-scan base-package="net.goout"/>
The applicationContext is loaded, but it seems it is mostly ignored. Beans are not constructed via component-scan and the application.properties are completely ignored, no mention in logs:
2018-01-26 20:09:26,131 DEBUG Resolved location pattern [classpath:**/applicationContext.xml] to resources []
2018-01-26 20:09:26,132 DEBUG Loaded 0 bean definitions from location pattern [classpath:**/applicationContext.xml]
2018-01-26 20:09:26,167 INFO Refreshing org.springframework.context.support.GenericApplicationContext#aecb35a: startup date [Fri Jan 26 20:09:26 CET 2018]; root of context hierarchy
2018-01-26 20:09:26,167 DEBUG Bean factory for org.springframework.context.support.GenericApplicationContext#aecb35a: org.springframework.beans.factory.support.DefaultListableBeanFactory#20d3d15a: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory]; root of factory hierarchy
2018-01-26 20:09:26,198 DEBUG Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
2018-01-26 20:09:26,198 DEBUG Creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
2018-01-26 20:09:26,225 DEBUG Eagerly caching bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' to allow for resolving potential circular references
2018-01-26 20:09:26,231 DEBUG Finished creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
What am I not getting?
EDIT: Not event component-scan beans are not constructed, but really no beans are constructed – even those defined by <bean> in applicationContext.xml. It seems its content is just ignored even though it is correctly found.
As per the latest comments i believe this issue is solved, but even then couple of quick observations and alternatives :
a) You did not get an error on missing resource is because of below attr,i would suggest making it true to identify issues early on :
ignore-resource-not-found="false"
Also, you could use below :
#PropertySource(value = "xyz.properties", ignoreResourceNotFound = true)
b) Completely unrelated but :
#ActiveProfiles(profiles = ["Test"])
Could be written as :
#ActiveProfiles({"Test","QA"})
or in your application-test.properties
spring.profiles.active=Test,QA
c)For placing applicationContext.xml ,an alternative can also be placed in web.xml :
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/*.xml</param-value>
</context-param>
(Although, annotation with specifying the exact location with #ContextConfiguration is completely fine as well! )
And above all , if you are using Annotation based configs, i would advice Spring boot :-)
Hope it helps!!
You should not copy applicationContext.xml to /test/resources yourself. Allow this to maven
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
</testResources>
</build>

Spring Boot Does Not Seem to Start

I am trying to get a Spring Boot WAR to deploy to a private Tomcat 7.0.68 instance hosted by DailyRazor. I cannot figure out why the Spring Boot application will not work. I do not seem to get any errors. Locally, I have gotten this to work with STS 3.8.4, Tomcat 7.0.78, Tomcat 8.5.11, and a couple other versions of Tomcat.
I never see the Spring Boot banner display on the DailyRazor instance nor much of the other logging indicating that my Spring Boot application is starting and loading all of the beans. This is the only logging I see:
INFO main org.apache.catalina.core.StandardService - Stopping service Catalina
INFO main org.apache.catalina.core.AprLifecycleListener - The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/local/tomcat/users/user_id/jdk/jre/lib/amd64/server:/usr/local/tomcat/users/user_id/jdk/jre/lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
INFO main org.apache.catalina.startup.Catalina - Initialization processed in 2299 ms
INFO main org.apache.catalina.core.StandardService - Starting service Catalina
INFO main org.apache.catalina.core.StandardEngine - Starting Servlet Engine: Apache Tomcat/7.0.68
INFO foobar.com-startStop-1 org.apache.catalina.startup.TldConfig - 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.
INFO foobar.com-startStop-1 org.apache.catalina.util.SessionIdGeneratorBase - Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [271] milliseconds.
INFO foobar.com-startStop-1 org.apache.catalina.startup.HostConfig - Deploying web application archive /home/user_id/tomcat/webapps/foobar.com/ROOT.war
INFO foobar.com-startStop-1 org.apache.catalina.startup.TldConfig - 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.
INFO foobar.com-startStop-1 org.apache.catalina.startup.HostConfig - Deployment of web application archive /home/user_id/tomcat/webapps/foobar.com/ROOT.war has finished in 1,603 ms
INFO foobar.com-startStop-1 org.apache.catalina.startup.HostConfig - Deploying web application archive /home/user_id/tomcat/webapps/foobar.com/plant-service-0.0.1-SNAPSHOT.war
INFO foobar.com-startStop-1 org.apache.catalina.startup.TldConfig - 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.
INFO foobar.com-startStop-1 org.apache.catalina.core.ContainerBase.[Catalina].[foobar.com].[/plant-service-0.0.1-SNAPSHOT] - 3 Spring WebApplicationInitializers detected on classpath
INFO foobar.com-startStop-1 org.apache.catalina.core.ContainerBase.[Catalina].[foobar.com].[/plant-service-0.0.1-SNAPSHOT] - Initializing Spring embedded WebApplicationContext
INFO foobar.com-startStop-1 org.apache.catalina.startup.HostConfig - Deployment of web application archive /home/user_id/tomcat/webapps/foobar.com/plant-service-0.0.1-SNAPSHOT.war has finished in 21,769 ms
INFO main org.apache.catalina.startup.Catalina - Server startup in 26534 ms
INFO ajp-bio-127.0.0.1-9592-exec-1 org.apache.catalina.core.ContainerBase.[Catalina].[foobar.com].[/plant-service-0.0.1-SNAPSHOT] - Initializing Spring FrameworkServlet 'dispatcherServlet'
I have following the instructions for packaging as a WAR, extending SpringBootServletInitializer, overriding configure(...), etc. Again, this all works locally on multiple versions of Tomcat. I have tried to adjust the logging, but I do not see anything useful.
Any hints? Suggestions?
EDIT
Not sure if it is related, but when shutting down Tomcat, I see the following:
INFO main org.apache.catalina.core.StandardService - Stopping service Catalina
ERROR foobar.com-startStop-2 org.apache.catalina.loader.WebappClassLoaderBase - The web application [] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak.
INFO foobar.com-startStop-2 org.apache.catalina.core.ContainerBase.[Catalina].[foobar.com].[/plant-service-0.0.1-SNAPSHOT] - Destroying Spring FrameworkServlet 'dispatcherServlet'
INFO foobar.com-startStop-2 org.apache.catalina.core.ContainerBase.[Catalina].[foobar.com].[/plant-service-0.0.1-SNAPSHOT] - Closing Spring root WebApplicationContext
ERROR foobar.com-startStop-2 org.apache.catalina.loader.WebappClassLoaderBase - The web application [/plant-service-0.0.1-SNAPSHOT] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
ERROR foobar.com-startStop-2 org.apache.catalina.loader.WebappClassLoaderBase - The web application [/plant-service-0.0.1-SNAPSHOT] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak.
Could you please ensure you did all of this correctly ?
From Create a deployable war file (Spring boot documentation) :
Create a deployable war file
The first step in producing a deployable war file is to provide a
SpringBootServletInitializer subclass and override its configure
method. This makes use of Spring Framework’s Servlet 3.0 support and
allows you to configure your application when it’s launched by the
servlet container. Typically, you update your application’s main class
to extend SpringBootServletInitializer:
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
The next step is to update your build configuration so that your
project produces a war file rather than a jar file. If you’re using
Maven and using spring-boot-starter-parent (which configures Maven’s
war plugin for you) all you need to do is to modify pom.xml to
change the packaging to war:
<packaging>war</packaging>
EDIT
Do you have spring-boot-starter-web and spring-boot-starter-tomcat dependencies ?
To build a war file that is both executable and deployable into an
external container you need to mark the embedded container
dependencies as “provided”, e.g:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- ... -->
<packaging>war</packaging>
<!-- ... -->
<dependencies>
<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>
<!-- ... -->
</dependencies>
</project>

Resources