我正在尝试使用 Maven 设置一个项目,其中使用了两个不兼容的项目(Elasticsearch 和 Neo4j)。这两个项目都使用 Lucene,但版本不同且不兼容。事实证明这是不可能的!幸运的是,我在运行时需要 Elasticsearch,在测试时需要 Neo4j。所以理论上,我应该没问题。但我不是!
至于共享的 Lucence 包,Neo4j 使用了旧版本,因此我在 <dependencyManager>
中明确命名了旧版本。与 <scope>test</scope>
.许多运行时错误已通过这种方式得到解决。但是现在,我面临着 NoClassDefFoundError
异常运行测试,在 Elasticsearch 的文件中说:
java.lang.NoClassDefFoundError: org/apache/logging/log4j/Logger
at org.elasticsearch.common.logging.Loggers.getLogger(Loggers.java:101)
at org.elasticsearch.search.suggest.completion2x.Completion090PostingsFormat.<clinit>(Completion090PostingsFormat.java:78)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.apache.lucene.util.NamedSPILoader.reload(NamedSPILoader.java:72)
at org.apache.lucene.util.NamedSPILoader.<init>(NamedSPILoader.java:51)
at org.apache.lucene.util.NamedSPILoader.<init>(NamedSPILoader.java:38)
at org.apache.lucene.codecs.PostingsFormat$Holder.<clinit>(PostingsFormat.java:49)
at org.apache.lucene.codecs.PostingsFormat.forName(PostingsFormat.java:112)
at org.apache.lucene.codecs.lucene54.Lucene54Codec.<init>(Lucene54Codec.java:161)
at org.apache.lucene.codecs.lucene54.Lucene54Codec.<init>(Lucene54Codec.java:81)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.apache.lucene.util.NamedSPILoader.reload(NamedSPILoader.java:72)
at org.apache.lucene.util.NamedSPILoader.<init>(NamedSPILoader.java:51)
at org.apache.lucene.util.NamedSPILoader.<init>(NamedSPILoader.java:38)
at org.apache.lucene.codecs.Codec$Holder.<clinit>(Codec.java:47)
at org.apache.lucene.codecs.Codec.getDefault(Codec.java:140)
at org.apache.lucene.index.LiveIndexWriterConfig.<init>(LiveIndexWriterConfig.java:120)
at org.apache.lucene.index.IndexWriterConfig.<init>(IndexWriterConfig.java:140)
at org.neo4j.kernel.api.impl.index.IndexWriterConfigs.standard(IndexWriterConfigs.java:69)
at org.neo4j.kernel.api.impl.index.partition.WritableIndexPartitionFactory.createPartition(WritableIndexPartitionFactory.java:45)
at org.neo4j.kernel.api.impl.index.AbstractLuceneIndex.open(AbstractLuceneIndex.java:98)
...
这对我来说根本没有意义,因为:
- 我根本没有调用 Elasticsearch(我的测试中只有一个
int i = 0;
)。 - 确保
org/apache/logging/log4j/Logger
类可用,我在我的测试类中实例化了一个静态记录器,这次找到了这个类:final static org.apache.log4j.Logger logger = Logger.getLogger(ApplicationTests.class);
有趣的是,在 Elasticsearch 的代码中抛出异常之前,这个静态记录器对象被成功实例化了!
知道为什么我会遇到这个异常吗?
为了演示这个问题,我创建了 this project在 GitHub 上,你可以克隆它。尝试并运行测试 dummyTest
你会看到异常。
最佳答案
log4j 2.7 似乎不适用于 ElasticSearch 5.0.0。您还需要添加对库 slf4j-simple
和 log4j-to-slf4j
以及 log4j-api
的依赖。
对我来说,它适用于:
log4j-api
版本 2.8.2slf4j-simple
版本 1.7.25log4j-to-slf4j
版本 2.8.2elasticsearch
版本 5.4.0
关于java - 如何解决 java.lang.NoClassDefFoundError : org/apache/logging/log4j/Logger while the class is actually accessible,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43149824/