Elasticsearch JAR hell error

坚强是说给别人听的谎言 提交于 2019-12-06 04:33:20

问题


I created a Java file using Elasticsearch Java API. in NetBeans, everything worked just fine.

However, I started getting the following error:

org/elasticsearch/plugins/PluginsService.java:342:in `loadBundles': java.lang.IllegalStateException: failed to load bundle [file:/D:/ELK-2.0/elasticsearch-2.0.0/plugins/license/license-2.0.0.jar, file:/D:/ELK-2.0/elasticsearch-2.0.0/plugins/license/license-core-2.0.0.jar, file:/D:/ELK-2.0/elasticsearch-2.0.0/plugins/license/license-plugin-api-2.0.0.jar, file:/D:/ELK-2.0/elasticsearch-2.0.0/plugins/marvel-agent/marvel-agent-2.0.0.jar] due to jar hell
        from org/elasticsearch/plugins/PluginsService.java:113:in `<init>'
        from org/elasticsearch/node/Node.java:144:in `<init>'
        from org/elasticsearch/node/NodeBuilder.java:145:in `build'
        from spamdetection/SpamDetection.java:63:in `client'
        from spamdetection/SpamDetection.java:30:in `SpammerDetector'
        from java/lang/reflect/Method.java:497:in `invoke'
        from spam.rb:53:in `(root)'
        from spam.rb:53:in `(root)'
Caused by:
JarHell.java:120:in `parseClassPath': java.lang.IllegalStateException: Classpath should not contain empty elements! (outdated shell script from a previous version?) classpath=''
        from JarHell.java:95:in `parseClassPath'
        from PluginsService.java:338:in `loadBundles'
        from PluginsService.java:113:in `<init>'
        from Node.java:144:in `<init>'
        from NodeBuilder.java:145:in `build'
        from SpamDetection.java:63:in `client'
        from SpamDetection.java:30:in `SpammerDetector'
        from NativeMethodAccessorImpl.java:-2:in `invoke0'
        from NativeMethodAccessorImpl.java:62:in `invoke'
        from DelegatingMethodAccessorImpl.java:43:in `invoke'
        from Method.java:497:in `invoke'
        from JavaMethod.java:451:in `invokeDirectWithExceptionHandling'
        from JavaMethod.java:312:in `invokeDirect'
        from InstanceMethodInvoker.java:45:in `call'
        from CachingCallSite.java:326:in `cacheAndCall'
        from CachingCallSite.java:170:in `call'
        from spam.rb:53:in `__file__'
        from spam.rb:-1:in `load'
        from Ruby.java:857:in `runScript'
        from Ruby.java:850:in `runScript'
        from Ruby.java:729:in `runNormally'
        from Ruby.java:578:in `runFromMain'
        from Main.java:395:in `doRunFromMain'
        from Main.java:290:in `internalRun'
        from Main.java:217:in `run'
        from Main.java:197:in `main'

When trying to call my Java JAR file from JRuby. What's causing this error?


回答1:


You can now disable the "jar hell" check during tests via the tests.jarhell.check property.




回答2:


You can create a package named org.elasticsearch.bootstrap in your src/test/java, and put this class in there:

package org.elasticsearch.bootstrap;
import java.net.URL;
public class JarHell {
    private JarHell() {}
    public static void checkJarHell() throws Exception {}
    public static void checkJarHell(URL urls[]) throws Exception {}
    public static void checkVersionFormat(String targetVersion) {}
    public static void checkJavaVersion(String resource, String targetVersion) {}
    public static URL[] parseClassPath() {return new URL[]{};}
}

This has the advantage that the production code that uses the node builder to initialize the node can stay clean of any hacks, jar hell check is disabled only in the unit tests.




回答3:


If you are getting "jar hell" error while running unit tests, following hack should take care of it - agree that it's not an elegant way.

String originalClassPath = System.getProperty("java.class.path");
  String[] classPathEntries = originalClassPath.split(";");
  StringBuilder esClasspath = new StringBuilder();
       for (String entry : classPathEntries) {
           if (entry.contains("elasticsearch") || entry.contains("lucene")) {
               esClasspath.append(entry);
               esClasspath.append(";");
           }
       }
  System.setProperty("java.class.path", esClasspath.toString());
  node = nodeBuilder().local(true).settings(settings).node();
  System.setProperty("java.class.path", originalClassPath);



回答4:


I am late, but I figured that my answer may help others in the future and that's why I am posting it.

I believe that the right solution is to find the root cause and exclude the library that is producing the jar hell rather than hiding the problem. For example, in my case, I had the following duplicated library :

Caused by: java.lang.IllegalStateException: jar hell!
class: org.hamcrest.BaseDescription
jar1: C:\Users\Yeikel\.m2\repository\org\hamcrest\hamcrest-all\1.3\hamcrest-all-1.3.jar
jar2: C:\Users\Yeikel\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar
        at org.elasticsearch.bootstrap.JarHell.checkClass(JarHell.java:275)
        at org.elasticsearch.bootstrap.JarHell.checkJarHell(JarHell.java:192)
        at org.elasticsearch.bootstrap.JarHell.checkJarHell(JarHell.java:89)
        at org.elasticsearch.bootstrap.BootstrapForTesting.<clinit>(BootstrapForTesting.java:90)

All I did to fix the problem is to find the duplication and exclude it from my libraries. In this case, the library was bundled with JUnit as well

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.hamcrest</groupId>
                    <artifactId>hamcrest-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


来源:https://stackoverflow.com/questions/33975807/elasticsearch-jar-hell-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!