我有一个在 JBoss EAP 服务器 (7.4) 上运行的 Spring MVC 应用程序 (5.2.4.RELEASE)。
当我在控制器方法中出现错误时(例如
javax.naming.NameNotFoundException
),异常会记录在 server.log
中,而不是记录在应用程序日志中。对于日志记录,我使用 Log4J
api(版本 1.2.x)。
我怀疑 Spring MVC 需要某种日志配置,但我没有
log4j.properties
文件,因为我将所有日志配置放在 JBoss 日志配置文件中。
你知道我是否可以配置 Spring MVC 日志记录以排除 console/system.out 吗?
这是我仅在
server.log
中找到的日志示例:
16:14:32,739 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /MyApp/test.jsp: javax.servlet.ServletException: javax.naming.NameNotFoundException: jboss/datasources/aaa -- service jboss.naming.context.java.jboss.datasources.aaa
at org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:889)
at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:818)
at org.apache.jsp.test_jsp._jspService(test_jsp.java:158)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:433)
[...]
at java.lang.Thread.run(Thread.java:750)
Caused by: javax.naming.NameNotFoundException: jboss/datasources/aaa -- service jboss.naming.context.java.jboss.datasources.aaa
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:106)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
at org.apache.jsp.test_jsp._jspService(test_jsp.java:124)
... 53 more
以下是从头开始重现问题的步骤:
从此页面下载Wildfly 23.0.2.Final(Jakarta EE Full & Web Distribution):https://www.wildfly.org/downloads/并解压到文件夹中
按照此处所述设置管理员用户:https://docs.wildfly.org/23/Getting_Started_Guide.html#authentication
使用 JDK 8u392-b08,启动服务器:管理控制台位于 http://localhost:9990
创建一个名为“
MyLoggingProfile
”的新日志记录配置文件,将所有内容写入文件
创建一个 WAR 部署(我从一个空的 Maven 项目开始):
[
pom.xml
] 将 JBoss BOM 添加到 'dependencyManagement
' 部分:
org.jboss.bom:eap-runtime-artifacts:7.4.0.GA(类型 pom,范围导入)
org.jboss.bom:jboss-eap-jakartaee8:7.4.0.GA(类型pom,范围导入)
[
pom.xml
] 添加以下依赖项:
[
web.xml
] 定义错误页面:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/WEB-INF/errorPage.jsp</location>
</error-page>
[
errorPage.jsp
]:
<!DOCTYPE html>
<html>
<head>
<title>Error Page</title>
</head>
<body>
<p>ERROR: ${exception}</p>
</body\>
</html>
[
web.xml
] 将 Spring 调度程序 servlet 定义为(注意 Spring 配置位于 xml 文件中):
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
[
spring-config.xml
] 使用 ViewResolver、组件扫描和注释驱动来配置 Spring MVC
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd"\>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"\>
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /\>
<property name="prefix" value="/WEB-INF/view/" /\>
<property name="suffix" value=".jsp" /\>
</bean>
<context:component-scan base-package="it.andynaz.demo" />
<mvc:annotation-driven />
</beans>
使
META-INF/MANIFEST.MF
文件包含“Logging-Profile: MyLoggingProfile
”行(以便部署的应用程序将使用指示的日志记录配置文件
使用这两种方法创建一个 Spring 控制器(以及“
landPage.jsp
”文件)
@RequestMapping("/callOK")
public String callWithtoutErrors(Model model) {
model.addAttribute("message", "My message!");
return "landPage";
}
@RequestMapping("/callKO")
public String callWithErrors(Model model) {
String missingJndiName = "java:jboss/datasources/aaa";
Context ctx = new InitialContext();
Context envCtx = (Context) ctx.lookup("");
DataSource ds = (DataSource) envCtx.lookup(missingJndiName);
if (ds == null) {
model.addAttribute("message", "Datasource found!");
} else {
model.addAttribute("message", "Datasource NOT found!");
}
return "landPage";
}
现在,调用 '
/callOK
' url 将导致 JSP 页面,而调用 '/callKO
' url 将导致 ClassCastException
记录在 Wildfly 'server.log
' 文件中,而不是应用程序中日志配置文件中定义的日志文件
这是因为 Undertow 正在捕获并记录错误。目前无法从全局模块获取日志消息以记录到您的应用程序日志上下文。