当程序 运行 时,在类路径中包含 slf4j 未被拾取
Inclusion of slf4j in classpath not being picked up when program is run
我一直在尝试将 slf4j
包含在项目中,但没有成功。我已将 slf4j-api-1.7.32.jar
和 slf4j-jdk14-1.7.32.jar
添加到 class 路径中,但无论我尝试了什么,我最终都会得到 java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
.
错误的开头部分是
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at com.google.gwt.dev.shell.jetty.JettyLauncher$WebAppContextWithReload$WebAppClassLoaderExtension.findClass(JettyLauncher.java:354)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:366)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
...
(如果有帮助,很高兴包含更多内容,但编译器会在此时将其切断)
项目在 Eclipse 中,我试过了
- 将库放在 class 路径的开头
- 放在最后
- 关闭和打开 Eclipse
- 重建项目
- 使用不同的版本
似乎没有任何效果。
然而,奇怪的是,使用完全相同的库集合,它在我编写的 JUnit 测试中运行良好。
今天早上,一位同事发现将一对 slf4j
库添加到 war/WEB-INF/lib
可以正常工作,但这不是一个可行的长期解决方案。
我希望有人有一些好主意!
编辑:
又取得了一些进展。来自 here 需要添加
<Set name="systemClasses">
<Array type="java.lang.String">
<!-- we from jetty WebAppContext source code ...-->
<Item>java.</Item>
<Item>javax.servlet.</Item>
<Item>javax.xml.</Item>
<Item>org.mortbay.</Item>
<Item>org.xml.</Item>
<Item>org.w3c.</Item>
<Item>org.apache.commons.logging.</Item>
<Item>org.apache.log4j.</Item>
<!-- and ... added slf4j -->
<Item>org.slf4j.</Item>
</Array>
</Set>
到jetty-web.xml
。现在需要找出部署脚本中需要更改的内容。
解决方案:
添加以下'systemClasses'设置到jetty-web.xml
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
...
<Set name="systemClasses">
<Array type="java.lang.String">
<!-- we copied these paths from jetty WebAppContext source code ...-->
<Item>java.</Item>
<Item>javax.servlet.</Item>
<Item>javax.xml.</Item>
<Item>org.mortbay.</Item>
<Item>org.xml.</Item>
<Item>org.w3c.</Item>
<Item>org.apache.commons.logging.</Item>
<Item>org.apache.log4j.</Item>
<!-- and ... added slf4j -->
<Item>org.slf4j.</Item>
<!-- we must promote slf4j to system classes, otherwise gwt
hosted mode will not allow loading them due to a policy
that don't allow server classes to be loaded from the
outside world (see gwt JettyLauncher source code). -->
</Array>
</Set>
</Configure>
2009 年在此留言板上找到:https://www.mail-archive.com/google-web-toolkit@googlegroups.com/msg14754.html
我们如何找到解决方案:
虽然单步执行 JettyLauncher.WebAppContextWithReload.WebAppClassLoaderExtension.findClass(String name)
显示在第一次加载时,大多数 super.findClass(name)
抛出了一个 ClassNotFoundException
,然后当他们通过 isServerPath
时,他们开始使用 systemClassLoader
从 .jar 文件加载它们。现在 systemClassLoader
的父类型 URLClassLoader
有一个字段 ucp
(URLClassPath
),它有一个包含所有 .jar 文件的列表(在 path
下)它可以从 类 加载。看看这里,slf4j 罐子确实存在,但由于某种原因 isServerPath
返回 true。这是最终找到上述解决方案的原因。
我一直在尝试将 slf4j
包含在项目中,但没有成功。我已将 slf4j-api-1.7.32.jar
和 slf4j-jdk14-1.7.32.jar
添加到 class 路径中,但无论我尝试了什么,我最终都会得到 java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
.
错误的开头部分是
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at com.google.gwt.dev.shell.jetty.JettyLauncher$WebAppContextWithReload$WebAppClassLoaderExtension.findClass(JettyLauncher.java:354)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:366)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
...
(如果有帮助,很高兴包含更多内容,但编译器会在此时将其切断)
项目在 Eclipse 中,我试过了
- 将库放在 class 路径的开头
- 放在最后
- 关闭和打开 Eclipse
- 重建项目
- 使用不同的版本
似乎没有任何效果。
然而,奇怪的是,使用完全相同的库集合,它在我编写的 JUnit 测试中运行良好。
今天早上,一位同事发现将一对 slf4j
库添加到 war/WEB-INF/lib
可以正常工作,但这不是一个可行的长期解决方案。
我希望有人有一些好主意!
编辑: 又取得了一些进展。来自 here 需要添加
<Set name="systemClasses">
<Array type="java.lang.String">
<!-- we from jetty WebAppContext source code ...-->
<Item>java.</Item>
<Item>javax.servlet.</Item>
<Item>javax.xml.</Item>
<Item>org.mortbay.</Item>
<Item>org.xml.</Item>
<Item>org.w3c.</Item>
<Item>org.apache.commons.logging.</Item>
<Item>org.apache.log4j.</Item>
<!-- and ... added slf4j -->
<Item>org.slf4j.</Item>
</Array>
</Set>
到jetty-web.xml
。现在需要找出部署脚本中需要更改的内容。
解决方案:
添加以下'systemClasses'设置到jetty-web.xml
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
...
<Set name="systemClasses">
<Array type="java.lang.String">
<!-- we copied these paths from jetty WebAppContext source code ...-->
<Item>java.</Item>
<Item>javax.servlet.</Item>
<Item>javax.xml.</Item>
<Item>org.mortbay.</Item>
<Item>org.xml.</Item>
<Item>org.w3c.</Item>
<Item>org.apache.commons.logging.</Item>
<Item>org.apache.log4j.</Item>
<!-- and ... added slf4j -->
<Item>org.slf4j.</Item>
<!-- we must promote slf4j to system classes, otherwise gwt
hosted mode will not allow loading them due to a policy
that don't allow server classes to be loaded from the
outside world (see gwt JettyLauncher source code). -->
</Array>
</Set>
</Configure>
2009 年在此留言板上找到:https://www.mail-archive.com/google-web-toolkit@googlegroups.com/msg14754.html
我们如何找到解决方案:
虽然单步执行 JettyLauncher.WebAppContextWithReload.WebAppClassLoaderExtension.findClass(String name)
显示在第一次加载时,大多数 super.findClass(name)
抛出了一个 ClassNotFoundException
,然后当他们通过 isServerPath
时,他们开始使用 systemClassLoader
从 .jar 文件加载它们。现在 systemClassLoader
的父类型 URLClassLoader
有一个字段 ucp
(URLClassPath
),它有一个包含所有 .jar 文件的列表(在 path
下)它可以从 类 加载。看看这里,slf4j 罐子确实存在,但由于某种原因 isServerPath
返回 true。这是最终找到上述解决方案的原因。