Reputation: 3336
I have a JAX application using spring to set up the context.
I have set up an AppConfig to deal with this... like so.
@Configuration
@ComponentScan("com.whatever")
public class AppConfig {... //etc
However, I keep getting an error because the application is looking for the applicationContext.xml
.
org.springframework.beans.factory.BeanDefinitionStoreException:
IOException parsing XML document from class path resource [applicationContext.xml];
I believe I have to do something with my web.xml file... but I can't quite figure it out. Here's my web.xml
<web-app version="3.1" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd">
<listener>
<listener-class>com.whatever.etc.ApplicationListener</listener-class>
</listener>
<!-- Application -->
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
io.swagger.jaxrs.listing,
com.shutterstock.media.api
</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.scanning.recursive</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.whatever.etc.MainClass</param-value>
</init-param>
<init-param>
<param-name>dirAllowed</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<!-- used to overwrite default 4xx state pages -->
<param-name>jersey.config.server.response.setStatusOverSendError</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Swagger -->
<servlet>
<servlet-name>Jersey Swagger</servlet-name>
<servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
</web-app>
Upvotes: 1
Views: 3435
Reputation: 3850
The best advice I can give you is fully transform your project to spring boot in order to take advantage of all the great functionality it offers.
You should completely remove all XML from your project and do the following steps:
TL;DR
An easy way to start with spring boot is using spring initializr (Spring initializr) and start migrating your code to the new project.
Explanations of starting steps to migrate to spring boot in an existing project:
Maven Dependencies
Add the following dependencies and remove all other related spring dependencies. In general if you need any other dependency try to first check if there is a spring boot starter for it. (also make sure your packaging is jar
. if you want a war
you should follow this link: convert to war)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Spring Boot Application
Create a class annotated with @SpringBootApplication
that looks like the following in your base package. From this point on create classes only in sub-packages of this package so spring can catch all of your components automatically:
@SpringBootApplication
public class FooApplication {
public static void main(String[] args) {
SpringApplication.run(FooApplication .class, args);
}
}
Java Configuration
now you can easily add a package called config
for example under your base package and add @Configuration
annotated beans with your custom configuration.
application.properites/yml
If you don't already have, add application.properties/yml to src/main.resources
with the following configuration as a minimum (more properties can be found here: spring boot common properties)
spring.jersey.application-path=/
Jersey Configuration
You need to register jersey providers in a custom java configuration class that extends ResourceConfig
:
@Configuration
public class JerseyConfiguration extends ResourceConfig {
public JerseyConfiguration() {
register(FooController.class);
register(OtherController.class);
...
}
}
Important Notes
After doing this transformation you don't need web.xml
anymore as spring boot takes care of creating servlets for you. You should remove all XML from your project except for the pom.xml
and convert everything to java. It can coexist with your XML configuration using @ImportResource
but it is not recommended.
In order to run your project now with maven use maven build with the command: spring-boot:run
.
If you have any static files served by the system move them from src/main/webapp
to src/main/resources/static
(more info here: Static Content)
All of this should get your started with spring boot and allow you to remove applicationContext.xml
while keeping best practices of spring boot. You could do it in an easier fashion but I think it will serve you better in the long run.
Upvotes: 0
Reputation: 209062
You're getting the error because the default way for Jersey to integrate with Spring is to look for this applicationContext.xml file. If you want to go xml-less, you need to configure Spring programmatically with a WebApplicationInitializer
@Order(1)
public class SpringWebContainerInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerContextLoaderListener(servletContext);
// Set the Jersey used property so it won't load a ContextLoaderListener
// see bug report https://java.net/jira/browse/JERSEY-2038
servletContext.setInitParameter("contextConfigLocation", "");
}
private void registerContextLoaderListener(ServletContext servletContext) {
WebApplicationContext webContext;
webContext = createWebAplicationContext(SpringAnnotationConfig.class);
servletContext.addListener(new ContextLoaderListener(webContext));
}
public WebApplicationContext createWebAplicationContext(Class... configClasses) {
AnnotationConfigWebApplicationContext context;
context = new AnnotationConfigWebApplicationContext();
context.register(configClasses);
return context;
}
}
In this example, where you see
createWebAplicationContext(SpringAnnotationConfig.class)
Just use your AppConfig
there.
What we're doing here is loading the Spring context ourselves, and when Jersey looks for it, it will find it, and not try to load the context itself (where it would otherwise try to find the applicationContext.xml file).
See also:
Upvotes: 3