2011-05-13 42 views
1

我正尝试在一个应用程序中使用Stanford NER和Stanford POS标记器。当我尝试运行POS标记方法时,我得到IncompatibleClassChangeError运行Stanford NER和Stanford POS标记器时出现IncompatibleClassChangeError

我在类路径中都有NER和POS tagger的jar文件。如果我从我的类路径中删除了jar的NER,那么这个错误不会发生。我猜在NER jar和POS jar中有一些共同的类,java不能确定在运行时使用哪个类。

以下是堆栈跟踪:

java.lang.IncompatibleClassChangeError: Implementing class 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(Unknown Source) 
    at java.security.SecureClassLoader.defineClass(Unknown Source) 
    at java.net.URLClassLoader.defineClass(Unknown Source) 
    at java.net.URLClassLoader.access$000(Unknown Source) 
    at java.net.URLClassLoader$1.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(Unknown Source) 
    at java.lang.ClassLoader.loadClass(Unknown Source) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
    at java.lang.ClassLoader.loadClass(Unknown Source) 
    at java.lang.ClassLoader.loadClassInternal(Unknown Source) 
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.init(MaxentTagger.java:407) 
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.readModelAndInit(MaxentTagger.java:699) 
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.readModelAndInit(MaxentTagger.java:673) 
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.<init>(MaxentTagger.java:280) 
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.<init>(MaxentTagger.java:260) 
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.runTagger(MaxentTagger.java:1305) 
    at edu.stanford.nlp.tagger.maxent.MaxentTagger.main(MaxentTagger.java:1499) 
    at com.tcs.srl.stanford.POSWrapper.executePOSTagger(POSWrapper.java:39) 
    at com.tcs.srl.stanford.test.POSWrapperTester.ExecutePOSTagger(POSWrapperTester.java:19) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

我不知道为什么这个错误即将到来。

回答

1

我认为你的诊断很接近但不完全正确。 Java将始终在类路径中使用类的第一个实例。然而,如果你有一个类加载器,并且一个子类加载器试图定义一个父类已经定义的类,你会得到这样的错误。

我不熟悉斯坦福大学的NER或POS代码。不过,我可以提供一些建议。

如果你是确信在两个罐子中名称相同的类是相同的,那么只需将两个罐子组合成一个罐子 - 这将删除任何重复。

如果您担心NER和POS代码可能不兼容,我会将两者的源代码移到单个项目中,然后重新编译,仔细检查重复项。

另一种方法是从一个项目中获取源代码并将其移入不同的包中,以使类名保持不变,但包不再发生冲突。一个好的IDE应该能够很轻松地做到这一点。

但是,像这样的邮件列表往往是最好的地方获得建议:http://www-nlp.stanford.edu/software/CRF-NER.shtml。我相信你不会是唯一一个一起使用这些软件的人。上面提到的解决方案都不是必需的,因此从使用它们的其他人处获得建议可能是最好的。

+0

非常感谢您的快速输入。我试图用Eclipse改变POS库的包结构。即使在更改包结构后,我的应用程序也没有给出ClassNotFoundException。我想在改变类结构之后,它无法找到名为“MaxEntTagger”的类。目前我正在调试这个POS API并试图找到答案。我想知道是否有可能在运行时将jar添加到classpath中。这样我可以避免上述错误。 – Shekhar 2011-05-13 08:28:58

+0

非常感谢您建议遵循邮件列表。很少有人遇到同样的问题。现在我正在阅读这些邮件。如果我得到答案,很快就会在这里更新它。谢谢 !!! – Shekhar 2011-05-13 08:33:51

+0

@Shekhar - 如果您在邮件列表中获得答案,请将其添加为独立答案 - 我将首先为其投票。 – 2011-05-13 10:11:55

1

这似乎是众所周知的问题,斯坦福大学的人们都知道这个问题。我已发送的邮件NER解析器的邮件列表中,我得到了下面的人回答叫约翰

这是一个已知的问题,这将是 固定在一个星期左右。在 与此同时,所有这两个库需要的类 都在 StanfordCoreNLP,

约翰

好像他们正试图从他们的API,并在下一版本中删除此错误解析器和标记器,我们将获得干净的API。

目前我正在使用CoreNLP软件包here。这个CoreNLP包包含了解析器,标记器,ner和其他一些东西的所有内容。

+0

上面的前两个段落是正确的,但这不是一个API错误,它只是公共版本的NER下载过于陈旧,而且标记器和NER使用的类已经变得不兼容(而CoreNLP下载中的类自然都是兼容的)。无论如何,修复此问题的斯坦福NER新版本今天发布(!)。 – 2011-05-16 19:14:27