Serving static content with spring boot and resteasy - spring

I have integrated resteasy with spring boot for our backend web application. My application.java file looks like below
#ComponentScan(basePackages = "<basepackage>")
#EnableAutoConfiguration
#EnableWebMvc
#ImportResource(value = { "classpath:springmvc-resteasy.xml" })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
In order to serve static content from my web application, it was suggested #https://stackoverflow.com/questions/24661289/spring-boot-not-serving-static-content to extend WebMvcAutoConfigurationAdapter. Once I did the same, I got the following exception
java.lang.IllegalStateException: could not find the type for bean named faviconRequestHandler
at org.jboss.resteasy.plugins.spring.SpringBeanProcessor.getBeanClass(SpringBeanProcessor.java:437) ~[resteasy-spring-3.0.8.Final.jar:na]
at org.jboss.resteasy.plugins.spring.SpringBeanProcessor.processBean(SpringBeanProcessor.java:294) ~[resteasy-spring-3.0.8.Final.jar:na]
at org.jboss.resteasy.plugins.spring.SpringBeanProcessor.postProcessBeanFactory(SpringBeanProcessor.java:272) ~[resteasy-spring-3.0.8.Final.jar:na]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:265) ~[spring-context-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:170) ~[spring-context-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:609) ~[spring-context-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) ~[spring-context-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120) ~[spring-boot-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691) [spring-boot-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) [spring-boot-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952) [spring-boot-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941) [spring-boot-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at com.xactly.insights.app.Application.main(Application.java:33) [classes/:na]
I package my application as executable jar. Can anyone throw some light on how to avoid the above exception while serving the static content?

Related

Multiple Context Loader definition error in tomcat

I have a ApplicationInitializer class that implements WebApplicationInitializer and in it I am adding my own ContextLoaderListener. When I am running my app in STS it is running perfectly, but when I try to deploy the war file in my tomcat, the application does not deploy and gives the following multiple context listener error:
10-Oct-2019 10:51:58.252 INFO [Catalina-utility-2] org.apache.catalina.core.ApplicationContext.log 3 Spring WebApplicationInitializers detected on classpath
10-Oct-2019 10:52:05.987 INFO [Catalina-utility-2] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
10-Oct-2019 10:52:11.237 SEVERE [Catalina-utility-2] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:262)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4683)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5146)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:978)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1849)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:773)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:427)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1620)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:305)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1151)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1353)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1357)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1335)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:835)
10-Oct-2019 10:52:11.240 INFO [Catalina-utility-2] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
I read the following documentation:
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file
From what I understood is I can completely remove my AppInitializer class and add its contents in the spring boot application class. Then I looked at how the onStartup of SpringBootServletInitializer was done and changed my code to:
#SpringBootApplication
#EntityScan("com.example")
#EnableJpaRepositories("com.example")
#ComponentScan("com.example")
#EnableConfigurationProperties(CustomProperties.class)
public class Application extends SpringBootServletInitializer{
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
#Override
public void onStartup(final ServletContext sc) throws ServletException{
AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
root.scan("com.example");
sc.addListener(new ContextLoaderListener(root){
#Override
public void contextInitialized(ServletContextEvent event) {
// no-op because the application context is already initialized
}
});
ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(new GenericWebApplicationContext()));
appServlet.setLoadOnStartup(1);
appServlet.addMapping("/");
sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
This time the war file deploys normally but when I try to hit the home page I get the following error although I did add the springSecurityFilterChain:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' available
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:771)
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:294)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1111)
org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:337)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
This is what I had initially(two separate classes):
public class AppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(final ServletContext sc) throws ServletException{
AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
root.scan("com.example");
sc.addListener(new ContextLoaderListener(root));
ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(new GenericWebApplicationContext()));
appServlet.setLoadOnStartup(1);
appServlet.addMapping("/");
sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
}
}
#SpringBootApplication
#EntityScan("com.example")
#EnableJpaRepositories("com.example")
#ComponentScan("com.example")
#EnableConfigurationProperties(CustomProperties.class)
public class Application extends SpringBootServletInitializer{
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Please help me figure out what I am doing wrong.

Setting up a 2nd Springboot application to use a #Autowired repository #Component from App 1 caused incorrect loading and REST requests broke

I have setup 2 Spring Boot applications. I am trying to #Autowire the repository from Application 1 in Application 2.
Both of these applications will be using REST to communicate back and forth. When I ran application 2 alone without the #Autowire of the repository for Application 1 I could correctly communicate with http://localhost:8082/runTestExecution via the #RestController HomeController class without an issue.
When I setup the #Autowire and #ComponentScan({"com.miw.mcb.server.repositories"}) so that I have access to the repositories of Application 1, Application 2 no longer functions correctly.
I am unable to reach the #RestController at http://localhost:8082/runTestExecution.
I also had a class which implemented CommandLineRunner which would run when I started up Spring Boot and this no longer runs either.
#Component
public class InitialRunner implements CommandLineRunner
Is this a issue because Application 1 also has a main class which loads #SpringBootApplication?
Can anyone suggest what is going wrong?
Below I have outlined my steps I took to add the jar of Application 1 and #Autowired class to Application 2
Here are the steps I took:
Setup maven to have the new library dependency and add it to the maven library mvn:install
Add Autowired bean to the HomeController class:
#RestController
public class HomeController {
#Autowired
TestSuiteRepository repo;
#RequestMapping(value = "/")
public String index() {
return "index";
}
#RequestMapping("runTestExecution")
public String runTestExecution(#RequestParam(value = "testExecutionID", required = true) String testExecutionID) {
return "Good";
}
}
Main class
#SpringBootApplication
public class AdbService {
public static void main(String[] args) {
SpringApplication.run(AdbService.class, args);
}
TestResultRepository class
package com.miw.mcb.server.repositories;
#Component
public interface TestResultRepository extends PagingAndSortingRepository<TestResult, Long> {
}
Add #Configuration and #ComponentScan, only supply the comment scan for the repositories package of the JAR file
Application 2 main class
#Configuration
#ComponentScan({"com.miw.mcb.server.repositories"})
#SpringBootApplication
public class AdbService {
public static void main(String[] args) {
SpringApplication.run(AdbService.class, args);
}
}
Application 1 Config Class
#Configuration
#ComponentScan({"com.miw.mcb.server.repositories"})
public class AppConfig {
}
Application 1 Main class
#SpringBootApplication
public class ReactAndSpringDataRestApplication {
public static void main(String[] args) {
SpringApplication.run(ReactAndSpringDataRestApplication.class, args);
}
}
Prior to adding the #ComponentScan I got the following stack trace:
2016-04-14 13:29:56 - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'homeController': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: com.miw.mcb.server.repositories.TestSuiteRepository
com.miw.mcb.adbservice.HomeController.repo; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[com.miw.mcb.server.repositories.TestSuiteRepository] found for
dependency: expected at least 1 bean which qualifies as autowire
candidate for this dependency. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at
org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
at
org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
at
org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
at com.miw.mcb.adbservice.AdbService.main(AdbService.java:38) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497) at
org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:478)
at java.lang.Thread.run(Thread.java:745)
Try to use #EnableJpaRepositories instead of #ComponentScan for JpaRepositories:
#Configuration
//#ComponentScan({"com.miw.mcb.server.repositories"})
#EnableJpaRepositories("com.miw.mcb.server.repositories")
#SpringBootApplication
public class AdbService {
public static void main(String[] args) {
SpringApplication.run(AdbService.class, args);
}
}

Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean while loading the context xml in run method

#Configuration
#EnableAutoConfiguration
#ComponentScan
#SpringBootApplication
public class InitService extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run("classpath:abc-server.xml", args);
}
}
++++++++++++++++++++++++++++++++++++++++++
Here i am trying to migrate the Spring MVC project to Spring boot Standalone jar with embedded tomcat. So i tried loading the context xml(abc-server.xml) used in the existing project. When i run/deploy the spring boot jar, the following exception is thrown.
++++++++++++++++++++++++++++++++++++
[2015-05-19 15:12:30,012] ERROR org.springframework.boot.SpringApplication - Application startup failed
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at com.gogo.asp.server.init.InitService.main(InitService.java:188)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)
... 13 more
When you call run, you're only providing server-abc.xml as a source for your application's configuration:
SpringApplication.run("classpath:abc-server.xml", args);
That means that InitService is being ignored, including the fact that you've enabled auto-configuration. Without auto-configuration being switched on, Spring Boot will not automatically configure an embedded servlet container for you. You need to provide both InitService and abc-server.xml as configuration for your application.
I would provide InitService.class to SpringApplication.run and use #ImportResource to pull in your old XML configuration:
#SpringBootApplication
#ImportResource("classpath:abc-server.xml")
public class InitService {
public static void main(String[] args) {
SpringApplication.run(InitService.class, args);
}
}
Note that #SpringBootApplication is equivalent to #ComponentScan, #Configuration, and #EnableAutoConfiguration. You can just use #SpringBootApplication and drop the other three annotations as I've done above.

Spring boot DispatchServlet

I've a spring boot project (executable jar with embedded jetty9).
I should register 2 different DispatcherServlet. I done in this way:
#Bean
public ServletRegistrationBean dispatcherServlet() {
DispatcherServlet servlet = new DispatcherServlet();
ServletRegistrationBean sr = new ServletRegistrationBean(servlet, "/graniteamf/*");
return sr;
}
#Bean
#Order(2)
public ServletRegistrationBean customDispatcherServlet() {
DispatcherServlet servlet = new DispatcherServlet();
ServletRegistrationBean sr = new ServletRegistrationBean(servlet, "/client/*");
return sr;
}
Unfortunally when I try to start the application I've this exception:
17/02/2015 18:24:04 INFO ApacheAsyncTransport:54 - Starting Apache HttpAsyncClient transport...
17/02/2015 18:24:04 INFO ApacheAsyncTransport:54 - Apache HttpAsyncClient transport started.
17/02/2015 18:24:04 DEBUG Application:173 - Inizializzazione identity
17/02/2015 18:24:04 ERROR DispatcherServlet:497 - Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:537)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:452)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:663)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:629)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:677)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:548)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:489)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:612)
at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:395)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:871)
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedWebAppContext$JettyEmbeddedServletHandler.deferredInitialize(JettyEmbeddedWebAppContext.java:46)
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedWebAppContext.deferredInitialize(JettyEmbeddedWebAppContext.java:36)
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer.handleDeferredInitialize(JettyEmbeddedServletContainer.java:162)
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer.start(JettyEmbeddedServletContainer.java:109)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:287)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at it.pianetatecno.gsmgateway.Application.main(Application.java:61)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)
... 30 more
17/02/2015 18:24:05 ERROR SpringApplication:339 - Application startup failed
org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Jetty servlet container
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer.start(JettyEmbeddedServletContainer.java:119)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:287)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at it.pianetatecno.gsmgateway.Application.main(Application.java:61)
I've two questions:
xml file for dispatcherServlet is mandatory?
in which folder Spring expect to find this file? I tried to put it into resources/WEB-INF but it doesn't work.
Edited question
This is my main mathod in Spring Boot:
#SpringBootApplication
public class Application {
private static Logger log = Logger.getLogger(Application.class);
private static ApplicationContext context;
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setShowBanner(false);
context = app.run(args);
app.setShowBanner(false);
}
Thanks
You don't need XML, but you do need to set the ApplicationContext on the servlet. Spring will do that for you if it is a #Bean (as it is in the DispatcherServletAutoConfiguration in Spring Boot), or I guess you can do it manually.

spring-boot with tomcat and cxf-servlet

I'm trying to stand up an embedded Tomcat with spring-boot. I want to use CXF for a set of web services in the app but I can not figure out how to stand up the CXF servlet.
My Main class looks like this...
#Configuration
#EnableAutoConfiguration
#ComponentScan(basePackages={"com.connecture.services.documentservice.webservice"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(new Class[] { Application.class, CfxInitializer.class }, args);
}
#Bean
public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory("", 8080);
return factory;
}
}
And my CfxInitializer like this...
public class CfxInitializer implements ServletContextInitializer
{
#Override
public void onStartup(ServletContext servletContext) throws ServletException
{
XmlWebApplicationContext rootContext = new XmlWebApplicationContext();
rootContext.setConfigLocations(new String[] { "classpath*:applicationContext.xml" });
servletContext.addListener(new ContextLoaderListener(rootContext));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("CXFServlet", CXFServlet.class);
dispatcher.addMapping("/api/*");
}
}
When I try to build and start the jar with the typical command ./gradlew build && java -jar build/libs/gs-spring-boot-0.1.0.jar
I get an Exception for multiple Contexts.
Java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:277)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4971)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Here is a more complete pastebin - http://pastebin.com/bcJ2ULhM
----------------------------------------------------------------------------------
Similarly to Dave's answer I was able to fix it by removing the ServletContextInitializer and adding a bean to the Application Class.
#Bean
public ServletRegistrationBean servletRegistrationBean(){
return new ServletRegistrationBean(new CXFServlet(),"/api/*");
}
The Spring Boot embedded servlet features are designed to work with Servlet and ServletRegistration #Beans, and not with the ContextLoaderListener (which looks like it is trying to steal the ServletContext attribute for the root context). Try adding a ServletRegistration for your servlet instead; if it is Spring aware, assuming it has an interface that lets you change the application context or the context location, then you should be able to configure it in the registration.
I found the following project on github which helped me get started
https://github.com/ungerts/spring-boot-jaxrs-sample
Worked for me with:
spring-boot 1.2.3
cxf-rt-frontend-jaxrs:3.1.0
jackson-jaxrs-json-provider:2.5.3
Samples are now part of the CXF wiki: http://cxf.apache.org/docs/jaxrs-services-configuration.html#JAXRSServicesConfiguration-SpringBoot

Resources