【问题标题】:Binding error with slf4jslf4j 绑定错误
【发布时间】:2016-10-28 17:35:39
【问题描述】:

我正在使用 GATE 工具进行文本分析,在安装 PR 时出现以下错误-

SLF4J:您的 slf4j 绑定请求的版本 1.5.6 与 [1.6, 1.7] 不兼容

现在,我已经在互联网上搜索了这个并找到了这个-

 Mixing different versions of slf4j-api.jar and SLF4J binding can cause problems. For example, if you are using slf4j-api-1.7.2.jar, then you should also use slf4j-simple-1.7.2.jar, using slf4j-simple-1.5.5.jar will not work.

我正在使用 slf4j-api-1.7.12 ,但我的计算机上不存在这个文件 - slf4j-simple-N。 我该如何解决这个问题? 任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 什么 PR / 插件导致了问题? "am using slf4j-api-1.7.12" 是什么意思?您是从 java 运行 GATE(GATE Embedded)还是问题出现在 GATE GUI(GATE 开发人员)中?
  • 您可能需要从插件目录或(最好)从插件的creole.xml 文件中删除“slf4j-api jar”。
  • @dedek Stanford POS tagger PR 导致了这个问题。 SLF4J-api-1.7.12 存在于我的系统中。我不知道我使用的是哪个版本的 SLF4J-simple-。我正在使用 GATE 8.2 GUI。
  • @dedek 删除 slf4j-api jar 会做什么?论坛说我们需要相同版本的 slf4j--simple 和 slf4j-api 。

标签: slf4j gate


【解决方案1】:

编辑:GATE 8.4 中不再存在该问题,GATE 中的类加载确实允许每个插件分开,因此一个插件加载的库不会干扰另一个插件加载的库。


问题

我想,我可以重现这个问题。 GATE Developer 当两个插件被加载并且每个插件都使用不同版本的slf4j-api 时,它就会在 GATE Developer 中体现出来。例如 Ontology 插件使用 slf4j 1.5.6Stanford_CoreNLP slf4j 1.7.12

当尝试创建 Stanford POS Tagger 的新实例时,会出现以下错误消息(请参阅下面的完整日志):

java.lang.LinkageError:加载程序约束违规:解析方法时“org.slf4j.impl ...

GATE 8.2 build 5482 started at Mon Jul 04 21:54:09 CEST 2016
and using Java 1.8.0_91 Oracle Corporation on Windows 8.1 amd64 6.3.
CREOLE plugin loaded: file:/C:/Program%20Files/gate-8.2-build5482-BIN/plugins/Stanford_CoreNLP/
CREOLE plugin loaded: file:/C:/Program%20Files/gate-8.2-build5482-BIN/plugins/Ontology/
org.xml.sax.helpers.DefaultHandler is available via both the system classpath and a plugin; the plugin classes will be ignored
SLF4J: The requested version 1.5.6 by your slf4j binding is not compatible with [1.6, 1.7]
SLF4J: See http://www.slf4j.org/codes.html#version_mismatch for further details.
java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of gate/util/GateClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of gate/util/GateClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:335)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:283)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:304)
    at edu.stanford.nlp.io.IOUtils.<clinit>(IOUtils.java:42)
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.readModelAndInit(MaxentTagger.java:765)
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.<init>(MaxentTagger.java:298)
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.<init>(MaxentTagger.java:263)
    at gate.stanford.Tagger.init(Tagger.java:129)
    at gate.Factory.createResource(Factory.java:432)
    at gate.gui.NewResourceDialog$4.run(NewResourceDialog.java:270)
    at java.lang.Thread.run(Unknown Source)

解决方案

我能想到三种可能的解决方案:

1) 消除不必要的插件

你真的需要两个不兼容版本的 slf4j 插件吗?如果没有,只需卸载您不需要的插件(一定要重新启动 GATE),问题就会消失。

2) 防止加载 ONE 的插件的 slf4j jars

这个解决方案比下一个更脏(因为修改后的插件不能单独工作),但作为一个快速修复应该足够了。选择其中一个插件并从插件的creole.xml 文件中删除 slf4j 条目。同样,GATE 重启后问题应该消失了。

这对于 Ontology 插件来说非常简单:(注意注释掉的行)

<?xml version="1.0"?>
<CREOLE-DIRECTORY> 
      <JAR>lib/commons-httpclient-3.1.jar</JAR>
      <JAR>lib/owlim-lite-5.4.jar</JAR>
<!--  <JAR>lib/slf4j-api-1.5.6.jar</JAR>
      <JAR>lib/slf4j-jdk14-1.5.6.jar</JAR> -->
      <JAR>lib/openrdf-sesame-2.7.9-onejar.jar</JAR>
      <JAR SCAN="true">Ontology.jar</JAR>
</CREOLE-DIRECTORY>

对于 Stanford_CoreNLP 插件,它更复杂,因为它使用 Apache Ivy 加载 slf4j jar,并且必须在 ivy.xml 文件中排除它们 (@987654328 @,注意文件底部添加的行&lt;exclude org="org.slf4j"/&gt;

<ivy-module version="2.0">

  <info
    organisation="uk.ac.gate.plugins"
    module="stanford_corenlp"
    revision="8.2-SNAPSHOT">
    <description homepage="https://github.com/GateNLP/gateplugin-Stanford_CoreNLP/" />
  </info>

  <configurations>
    <conf name="default" />
  </configurations>

  <dependencies defaultconf="*->master(default),runtime(default)" >
    <dependency org="edu.stanford.nlp" name="stanford-corenlp" rev="3.6.0" />
    <exclude org="org.slf4j"/>
  </dependencies>
</ivy-module>

3) 统一冲突的 slf4j 版本

这似乎是一个干净的解决方案,但它比我预期的要复杂得多,因为即使两个插件都使用相同版本的 slf4j,问题仍然存在。问题可能存在于 GATE 类加载机制的更深处,唯一“为我工作”的方式是如何统一 slf4j 版本,将它们排除在所有冲突的插件中并添加 slf4j jar(例如来自 Ontology 插件的那些) ) 到 GATE 的 lib 文件夹。

【讨论】:

    【解决方案2】:

    SLF4J 是“包装”“真实”日志框架的标准化方式。 (“F”代表“Facade”。)除了slf4j-api-&lt;version&gt;.jar 文件,还需要包含一个“binding”。 slf4j-simple-&lt;version&gt;.jar 是非常简单的应用程序的一个这样的绑定,它有一些简单的配置,主要用于登录到控制台。但是,如果您的类路径中没有它,那么它可能不是您正在使用的那个。

    那么,您使用的是哪种绑定?如果您不确定,则需要查看类路径中的 .jar 文件并查看哪些可以是 SLF4J 的绑定。绑定库通常以“slf4j-”开头,但有些像“logback”不直接实现 SLF4J API。如果您真的卡住了,您可能需要查看 .jar 文件(可以使用任何 .zip 文件阅读器读取它们),看看其中有一个 org/slf4j 文件夹。

    我认为您真正的问题在于您使用的任何依赖管理系统,例如 Maven、Gradle,或者使用一堆 .jar 文件手动构建类路径。看起来您为此使用的任何内容都具有多个版本的 slf4j-api 文件、多个日志记录绑定,或者与您正在使用的较新版本的绑定库不匹配的较旧版本的 slf4j-api。查看您正在运行的类路径中的所有 .jar 文件,您应该能够发现问题。

    【讨论】:

      猜你喜欢
      • 2012-07-06
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2021-05-23
      • 2015-08-10
      • 2018-12-10
      • 2018-07-10
      相关资源
      最近更新 更多