问题
I have a Spring + Jersey web application that I'm migrating from a web.xml to annotation base configuration. I'm implementing WebApplicationInitializer and everything works except log4j, because I have a custom file name.
In the web.xml I had
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>/WEB-INF/custom-name-log4j.xml</param-value>
</context-param>
This worked.
Now, I tried to do the same in Java:
container.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
This doesn't work... I get the following errors in Tomcat 7.0.62:
ERROR StatusLogger No Log4j context configuration provided. This is very unusual.
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
My WAR file contains the xml in the WEB-INF/ folder.
Do I have to do more than specifying that log4jConfiguration parameter?
Later Edit: WebApplicationInitializer
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(MyApplicationConfiguration.class);
container.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
rootContext.setConfigLocation("my.package.spring");
final FilterRegistration.Dynamic characterEncodingFilter = container.addFilter("characterEncodingFilter", new CharacterEncodingFilter());
characterEncodingFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
characterEncodingFilter.setInitParameter("encoding", "UTF-8");
characterEncodingFilter.setInitParameter("forceEncoding", "true");
container.setInitParameter("spring.profiles.default", "prod");
rootContext.register(SecurityContextFilter.class);
container.addListener(new ContextLoaderListener(rootContext));
container.addListener(new RequestContextListener());
container.setInitParameter("contextConfigLocation", "");
final ServletContainer servlet = new ServletContainer();
final ServletRegistration.Dynamic appServlet = container.addServlet("appServlet", servlet);
appServlet.setInitParameter("jersey.config.server.provider.packages", "my.package");
appServlet.setLoadOnStartup(1);
final Set<String> mappingConflicts = appServlet.addMapping("/rest/*");
}
回答1:
You also need to register a Listener : Log4jConfigListener
(you can find it in org.springframework.web.util)
servletContext.addListener(Log4jConfigListener.class);
By the way, you can note that it is deprecated since spring 4.2.1
EDIT
Sorry I didn't realized that you were using log4j2, everything stated above is false, and here is the solution for you :
log4j2 (thanks to log4j-web
artifact) & spring are both relying on ServletContainerInitializer
from servlet 3.0
API to setup the ServletContext
.
The problem is that the order they are executed depends on the order they are scanned on the classpath and you can't really rely on it (in your case the Log4jServletContainerInitializer
startup methods is called before the one from SpringServletContainerInitializer
).
To correct this you can declare your own ServletContainerInitializer
implementation which we'll be taken into account before others (before scanning the classpath) and here is a sample :
public class Log4j2ConfigServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
ctx.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
}
}
Then you have to create a file :
/META-INF/services/javax.servlet.ServletContainerInitializer
and put into it :
example.initializer.Log4j2ConfigServletContainerInitializer
(change to suit your needs)
and the configuration you provided to set a custom log4j config file location will be set before triggering the Log4jServletContainerInitializer
and everything is going to be fine.
see :
https://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html
http://www.eclipse.org/jetty/documentation/current/using-annotations.html#servlet-container-initializers
http://logging.apache.org/log4j/2.x/manual/webapp.html
EDIT
POC @ http://www.filedropper.com/32713596_1
just run mvn jetty:run
来源:https://stackoverflow.com/questions/32713596/spring-application-without-web-xml-log4j-configuration