使用 EJB3.1 进行日志记录
我正在使用 logback/slf4j 来处理应用程序中的日志记录。在我开始使用 EJB 之前,一切都运行得很完美。当我向应用程序添加无状态 EJB 后,记录器开始忽略我的 logback.xml 并停止使用我的附加程序。我切换到编程记录器配置以查看出了什么问题,现在当我尝试在 EJB 中使用记录器时出现以下错误:
org.slf4j.impl.JDK14LoggerFactory 无法转换为 ch.qos.logback.classic.LoggerContext
源于以下行:
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
是否需要任何特殊配置才能使 logback 与 EJB 配合使用?如果重要的话,我将部署在 glassfish v3 上。
I am using logback/slf4j to handle logging in my application. Everything was working perfectly until I started using EJBs. Once I added a stateless EJB to my app, the logger started ignoring my logback.xml and stopped using my appenders. I switched to a programmatic logger configuration to see what was wrong and now I am getting the following error when I try to use my logger within the EJB:
org.slf4j.impl.JDK14LoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext
stemming from the line:
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
Is there any special configuration necessary to get logback to work with EJBs? If it matters I am deploying on glassfish v3.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这看起来非常接近此线程中描述的问题,我怀疑类似的类加载问题。由于 logback 加载
logback.xml
的方式(更准确地说是它检索ClassLoader
来执行此操作的方式),它可能无法获取其配置文件并依赖于默认的BasicConfiguration
。不确定如何打包代码,但建议的解决方法是将
logback.xml
包含在 EAR 库中。如果您没有使用 EAR 打包,请尝试识别用于查看logback.xml
文件放置位置的类加载器。最后,这可能是logback的问题。但没有检查他们的问题跟踪器。
更新:如果您使用 war 打包,请尝试将 GlassFish 配置为在委托之前首先使用子类加载器。在sun-web.xml
中:更新: 我在我这边做了一些测试......我无法重现你的问题。我为 Java EE 6 Web 应用程序创建了一个项目,其结构如下:
我的 pom.xml 如下所示:
SimpleEJB.java
的代码是:SimpleServlet.java< 的代码/code> 是:
index.jsp
的代码是:我的
logback.xml
看起来像:我的
logback.xml
已正确加载并调用 servlet 时,我得到以下跟踪信息(取自日志文件):我还尝试将 EJB 打包在自己的 JAR 中并部署在 WEB-INF/lib 中,并得到相同的结果,它就是有效的。你能发现任何明显的区别吗?也许上传应用程序的简化版本(顺便说一句,错误报告很可能需要)。
我在 Eclipse 3.5 下运行 GlassFish v3(使用 GlassFish v3 插件)。
This looks very close to the problem described in this thread and I suspect a similar class loading issue. Because of the way logback loads
logback.xml
(more precisely the way it retrieves aClassLoader
to do so), it may fail at picking up its configuration file and fall back on a defaultBasicConfiguration
.Not sure how you package your code but the suggested workaround is to include the
logback.xml
in a EAR lib. If you aren't using an EAR packaging, try to identify the class loader used to see where to put thelogback.xml
file.At the end, this might be a problem in logback. Didn't check their issue tracker though.
Update: If you use a war packaging, try to configure GlassFish to use firstly the child classloaders before to delegate. In thesun-web.xml
:Update: I did a little test on my side and... I cannot reproduce your problem. I've created a project for a Java EE 6 webapp which has the following structure:
My pom.xml looks like:
The code for
SimpleEJB.java
is:The code for
SimpleServlet.java
is:The code for
index.jsp
is:And my
logback.xml
looks like:My
logback.xml
gets propertly loaded and I get the following trace (taken from my log file) when invoking the servlet:I did also try with the EJB packaged in its own JAR and deployed in
WEB-INF/lib
and get the same result, it just works. Can you spot any obvious difference? Maybe upload a simplified version of your app (will very likely be required for the bug report BTW).I am running GlassFish v3 under Eclipse 3.5 (with the GlassFish v3 plugin).
org.slf4j.impl.JDK14LoggerFactory 无法转换为 ch.qos.logback.classic.LoggerContext 异常表明 SLF4J 未绑定到 logback-classic,而是绑定到 slf4j-jdk14。简而言之,logback 代码不应该受到指责,因为它没有被执行或调用。
看起来 GFv3 正在将 slf4j-jdk14.jar 导出到您的应用程序中,从而覆盖您对日志记录后端(本例中为 logback)的选择。这是应用程序服务器无意中将其选择强加给用户的场景之一。
如果 GFv3 确实将 SLF4J 绑定强加给最终用户,那么这就是 GFv3 问题,必须由 GFv3 开发人员解决。我可能是错的,但我认为他们假设最终用户不会想要除 java.util.logging 提供的功能之外的任何其他日志记录功能,而只是在 GFv3 中捆绑 slf4j-jdk14。用户需要联系他们并抱怨他们的假设不正确。他们也有可能意识到这个问题并已经提供了解决方法......
The
org.slf4j.impl.JDK14LoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext
exception shows that SLF4J is not bound to logback-classic but to slf4j-jdk14. In short, logback code is not to blame because it is not being exercised nor called.It looks like GFv3 is exporting slf4j-jdk14.jar into your application and thus overriding your choice of the logging back-end, logback in this case. This is one of those scenarios where the app server inadvertently imposes its choices on the user.
If indeed GFv3 imposes it's SLF4J binding on the end-user, then that's a GFv3 issue which must be solved by GFv3 developers. I might be wrong but I think they assume that the end-user will not want any other logging functionality beyond what is provided by java.util.logging and just bundle slf4j-jdk14 in GFv3. Users needs to contact them and complain that their assumption is incorrect. It is also possible that they are aware of this issue and already provide a workaround...
下面是几乎完全相关的代码:
登录 EJB:
我的日志记录代码所在的拦截器:
logback.xml
jsf2.0 支持 bean。
我有一个 jsf 页面,
终于有我的 pom
编辑:我也尝试将我的记录器更改为静态,没有更改。
Here is pretty much the exact relevant code:
The Login EJB:
The interceptor where my logging code is:
The logback.xml
The jsf2.0 backing bean.
I have a jsf page that has
finally my pom
Edit: I also tried changing my logger to a static, no change.
基本上,问题在于应用程序服务器
使用提供 slf4j 并且您尝试使用它会转到应用程序服务器 slf4j 绑定,而不是您自己想要的绑定。不能只在 Glassfish 中使用 slf4j 绑定吗?
Basically the problem is that the application server
usesprovides slf4j AND that your attempts to use it goes to the application server slf4j binding instead of the one you want yourself.Can't you just use the slf4j binding in Glassfish?