【问题标题】:LinkageError while starting tomcat from eclipse从eclipse启动tomcat时出现LinkageError
【发布时间】:2014-06-12 15:31:20
【问题描述】:

我正在尝试在服务器视图中的 Eclipse 中运行一个 tomcat。

我的项目设置:

-subproject
  -src/main/java
     {mycode}
  -build.gradle
-webappproject
  -src/main/java
     {mycode}
  -build.gradle
-build.gradle

webapp 项目依赖于子项目。 我在服务器视图中将 webapp-project 添加到我的服务器。服务器启动正常。当我打开我的一个页面(我使用子项目中的一个类)时,我得到一个类未找到异常。

为了解决这个问题,我在服务器运行配置的类路径中的用户条目中添加了一个子项目。当我还在 linux 上开发时,这解决了问题,一切都很好。

现在我在 Windows 8 上工作,并在启动 tomcat 时遇到此异常。

Jun 12, 2014 4:57:55 PM org.apache.catalina.core.StandardContext filterStart
SCHWERWIEGEND: Exception starting filter WicketApplication
java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/apache/catalina/loader/WebappClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for resolved class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type LoggerFactory; used in the signature
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:306)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:276)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:288)
    at org.apache.wicket.protocol.http.WicketFilter.<clinit>(WicketFilter.java:64)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at java.lang.Class.newInstance(Class.java:374)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:140)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:258)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4809)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5485)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

如果我构建战争并将其放入 tomcat/webapps 中,它就可以工作。

我的 build.gradle 包含

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'eclipse-wtp'

请帮帮我。

【问题讨论】:

  • 另外,我认为如果您将 slf4j 记录器标记为编译而不是在部署时提供,则可能会发生这种情况。例如。在这篇文章中:answers.atlassian.com/questions/253499/…
  • 我已将 slf4j-api 标记为子项目中的编译依赖项。原因是我想为另一个依赖于不在 tomcat 内部运行的子项目的应用程序进行日志记录,因此需要它自己的日志记录。 tomcat 是否提供它自己的 slf4j-api?我在 apache/libs 中找不到它。如果是这样,将依赖项更改为提供确实是有意义的。
  • @phil_20686:我继续尝试,然后......它有效!我可以在 Eclipse 中运行 webapp!但是,如果我建立战争并放入 omcat/webapps,它会如我预期的那样为 org.slf4j.Logger 获得 ClassNotFoundException。如果你还想出如何让 slf4j-api.jar 出现在 .war 中,那么赏金就是你的了!
  • 我对tomcat了解不多,但通常在服务器中有一个文件夹,您可以在其中部署库,并且将它们部署在应用程序级别,而不是在WAR级别,并且您应该对多次战争使用的任何库执行此操作。免责声明 - 我绝不是该主题的专家。

标签: java eclipse tomcat gradle slf4j


【解决方案1】:

您是否使用javawar 插件将eclipse-wtp 插件应用到您的Gradle 项目中。

【讨论】:

    【解决方案2】:

    我发现以下文章对理解此类错误非常有帮助:

    http://frankkieviet.blogspot.co.uk/2009/03/javalanglinkageerror-loader-constraint.html

    基本上,有时会发生的情况是,类加载器可以尝试加载类本身,或者委托给它的父加载器,因此,如果您有一个自加载的类,并且它会加载该类,那么类位于类加载器网络中,但父级无法访问,因此如果您尝试从另一个类加载它,则违反了约束,因为该类已经加载,但不在另一个加载器中类可以访问。至少我认为这就是发生的事情。我正在查看 jboss 上下文中的链接错误。

    基本上,经验法则是,如果你有一个自我优先的 WAR 和一个父优先的战争,它们都试图加载同一个类,你可能会遇到问题。

    【讨论】:

      【解决方案3】:

      我仍然不知道出了什么问题,但我找到了解决方法。正如 phil_20686 所指出的,问题在于 slf4j-api 位于 WebAppLibraries 下的 eclipse-classpath 中。出于某种原因,这会破坏构建。所以它需要从那里移除。

          eclipseClasspath{
            plusConfigurations.each{
              it.allDependencies.each{ it.exclude group: 'org.slf4j', module: 'slf4j-api' }
            }
          }
      

      Need to exclude a dependency from eclipse using a gradle build file中找到

      那家伙也排除了 slf4j-jar,所以它可能在某种程度上与我的问题有关。

      【讨论】:

        猜你喜欢
        • 2011-06-24
        • 2011-05-12
        • 1970-01-01
        • 1970-01-01
        • 2010-09-11
        • 2020-07-26
        • 1970-01-01
        • 2015-10-21
        相关资源
        最近更新 更多