4

I am using a tool, GATE for text analysis and while installing a PR I get the following error-

SLF4J: The requested version 1.5.6 by your slf4j binding is not compatible with [1.6, 1.7]

Now, I have searched the internet regarding this and have found this-

 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.

I am using slf4j-api-1.7.12 , but this file- slf4j-simple-N does not exist on my computer. How can I resolve this problem? Any help will be apprecited. Thanks!

  • What PR / plugin is causing the problem? What do you mean by _"am using slf4j-api-1.7.12"_ ? Are you running GATE from java (GATE Embedded) or does the problem manifest in the GATE GUI (GATE Developer)? – dedek Jun 27 '16 at 13:01
  • You may have to delete the "slf4j-api jar" from the plugin directory or (preferably) from the plugin's `creole.xml` file. – dedek Jun 27 '16 at 13:06
  • @dedek Stanford POS tagger PR is causing the problem. SLF4J-api-1.7.12 is present on my system. I don't know which version of SLF4J-simple- I am using. I am using GATE 8.2 GUI. – Raghav Motwani Jun 29 '16 at 10:09
  • @dedek what will deleting slf4j-api jar do? The forum says that we need same versions of slf4j--simple and slf4j-api . – Raghav Motwani Jun 29 '16 at 10:11

2 Answers2

2

SLF4J is a standardized way to "wrap" a "real" logging framework. (The "F" stands for "Facade".) In addition to the slf4j-api-<version>.jar file, one also needs to include a "binding". One such binding for really simple applications is the slf4j-simple-<version>.jar, which has some simple configurations and is mainly for logging to the console. But if you don't have that on your classpath, then that's probably not the one that you're using.

So, which binding are you using? If you're not sure, figuring that out requires you to look at the .jar files that are on your classpath and seeing which are can be a binding for SLF4J. The binding libraries generally start with "slf4j-", but some like "logback" don't and directly implement the SLF4J API. If you're really stuck, you may need to look inside the .jar files (they can be read with any .zip file reader) and see which has a org/slf4j folder within it.

I think your real issue is within whatever dependency management system you're using, such as Maven, Gradle, or manually building a classpath with a bunch of .jar files. It looks like whatever you're using for this has either multiple versions of the slf4j-api file, multiple logging bindings, or an older version of slf4j-api that doesn't match the newer version of the binding library you're using. Look through all the .jar files in the classpath that you're running, and you should be able to spot the problem.

2

Edit: the problem no longer exists in GATE 8.4, where the classloading in GATE does allow each plugin to be separate and so libraries loaded by one plugin do not interfere with those loaded by another plugin.


Problem

I think, I can reproduce the problem. It is manifesting in the GATE Developer when two plugins are loaded and each of them is using a different version of slf4j-api. For example the Ontology plugin is using slf4j 1.5.6 and the Stanford_CoreNLP slf4j 1.7.12.

When trying to create a new instance of Stanford POS Tagger, it ends up with following error message (see the full log bellow):

java.lang.LinkageError: loader constraint violation: when resolving method "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)

Solution

There are three possible solutions I can think of:

1) Eliminate unnecessary plugins

Do you really need both plugins with the incompatible versions of slf4j? If not, simply unload the plugin you don't need (restart GATE for sure) and the problem should be gone.

2) Prevent loading of slf4j jars of ONE of the plugins

This a bit more dirty solution than the next one (because the modified plugin will not work alone) but it should be enough as a quick fix. Choose one of the plugins and remove slf4j entries from the plugin's creole.xml file. Again, the problem should be gone after GATE restart.

This is quite easy for the Ontology plugin: (note the commented out lines)

<?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>

For the Stanford_CoreNLP plugin, it is more complicated because it is loading slf4j jars using Apache Ivy and they have to be excluded in the ivy.xml file (plugins\Stanford_CoreNLP\build\ivy.xml, note the added line <exclude org="org.slf4j"/> at the bottom of the file)

<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) Unify the conflicting slf4j versions

This seems to be a clean solution but it is much more complicated than I expected, because the problem remains even after both the plugins use the same version of slf4j. The problem probably lies deeper inside of the GATE class-loading mechanism and the only "working for me way" how to unify the slf4j versions was to exclude them in all the conflicting plugins and to add the slf4j jars (e.g. those from the Ontology plugin) to the GATE's lib folder.

dedek
  • 7,981
  • 3
  • 38
  • 68