Elasticsearch install custom plugins results in ERROR: `elasticsearch` directory is missing in the plugin zip

Elasticsearch install custom plugins results in ERROR: `elasticsearch` directory is missing in the plugin zip

当我尝试安装我通过调用

构建的插件时
./elasticsearch-plugin install file:///fullpath/to/zipfile/custome_plugin.zip

它给我这个错误:

ERROR: `elasticsearch` directory is missing in the plugin zip

我正在阅读其他一些类似的帖子,许多人试图安装 .jar 而不是 .zip。我确实尝试安装 .zip,但仍然出现同样的错误。

此外(可能与此问题无关),当我手动解压缩 zip 文件并将其放入插件文件夹时,执行 elasticsearch-plugins list 会列出自定义插件。在这种情况下,插件是一个自定义分析器,但不知何故映射无法识别分析器。是不是因为我没安装好?

编辑:

添加一点信息,当我关闭集群然后手动解压缩插件并将其放入plugin目录后重新启动时,集群无法启动。我收到看起来像

的错误
[2017-08-31T11:15:52,668][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [] fatal error in thread [main], exiting
java.lang.NoClassDefFoundError: org/elasticsearch/index/analysis/AnalysisModule$AnalysisBinderProcessor
    at java.lang.Class.getDeclaredConstructors0(Native Method) ~[?:1.8.0_65]
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671) ~[?:1.8.0_65]
    at java.lang.Class.getConstructor0(Class.java:3075) ~[?:1.8.0_65]
    at java.lang.Class.getConstructor(Class.java:1825) ~[?:1.8.0_65]
    at org.elasticsearch.plugins.PluginsService.loadPlugin(PluginsService.java:423) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.plugins.PluginsService.loadBundles(PluginsService.java:387) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:140) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.node.Node.<init>(Node.java:312) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.node.Node.<init>(Node.java:244) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.bootstrap.Bootstrap.<init>(Bootstrap.java:232) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:232) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:351) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:123) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:114) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:67) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:122) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.cli.Command.main(Command.java:88) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:91) ~[elasticsearch-5.5.2.jar:5.5.2]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:84) ~[elasticsearch-5.5.2.jar:5.5.2]
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.index.analysis.AnalysisModule$AnalysisBinderProcessor
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_65]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_65]
    at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814) ~[?:1.8.0_65]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_65]
    ... 19 more

好像是这样分析的

有没有我缺少的图书馆?

编辑 2: 经过更多的挖掘,我找到了这个网站

http://snacktrace.com/artifacts/org.elasticsearch/elasticsearch/1.7.3/org.elasticsearch.index.analysis.AnalysisModule$AnalysisBinderProcessor$AnalyzersBindings

似乎这个 AnalyzersBindings 只适用于 ES 1.x 和 2.x (<2.4)?我需要一种方法来替换它。

编辑 3: 根据要求,这是 AnalyzerBinding 最初的使用方式

package org.elasticsearch.plugin.analysis.my.analyzer;

import org.elasticsearch.index.analysis.AnalysisModule;

public class AnalyzerBinderProcessor extends AnalysisModule.AnalysisBinderProcessor {

    @Override
    public void processAnalyzers(AnalyzersBindings analyzersBindings) {
        analyzersBindings.processAnalyzer("my_name", AnalyzerProvider.class);
    }

    @Override
    public void processTokenFilters(TokenFiltersBindings tokenFiltersBindings) {
    }
}

然后在我的 AnalyzerPlugin.java 我有

public class AnalyzerPlugin extends Plugin {
    //some other code here that's not related to Binder 

    public void onModule(AnalysisModule module) {
        module.addProcessor(new AnalyzerBinderProcessor());
    }
}

编辑 4:这是永无止境的......

如果我保留@Override,它会抛出

[ERROR] /opt/bg/analytics/src/java/src/analyzer5.0/src/main/java/org/elasticsearch/plugin/analysis/my_analyzer/AnalyzerPlugin.java:[16,5] method does not override or implement a method from a supertype

此外,面临

的问题
[ERROR] /opt/bg/analytics/src/java/src/analyzer5.0/src/main/java/org/elasticsearch/plugin/analysis/my_analyzer/AnalyzerPlugin.java:[36,17] onModule(org.elasticsearch.indices.analysis.AnalysisModule) in org.elasticsearch.plugin.analysis.my_analyzer.AnalyzerPlugin cannot override onModule(org.elasticsearch.indices.analysis.AnalysisModule) in org.elasticsearch.plugins.Plugin

因为overridden method is final

这是从旧 Plugin 到新的更新吗?我好迷茫......

我觉得我需要一个关于如何为自定义分析器创建插件的完整教程,目前我能找到的只有这个

http://david.pilato.fr/blog/2016/10/16/creating-a-plugin-for-elasticsearch-5-dot-0-using-maven-updated-for-ga/

这没什么帮助。有没有人有好的link?

目前ES5.x我们有org.elasticsearch.plugins.AnalysisPlugin,这是创建自定义分析组件的要点。您需要调整您的插件代码,以便您可以注册您拥有的任何自定义 analyzer/tokenizer/etc。

插件示例,应该可以满足您的需要:

public class MyAnalyzerPlugin implements AnalysisPlugin {

@Override
public Map<String, AnalysisModule.AnalysisProvider<AnalyzerProvider<? extends Analyzer>>> getAnalyzers() {
    final Map<String, AnalysisModule.AnalysisProvider<AnalyzerProvider<? extends Analyzer>>> objectObjectHashMap = new HashMap<>();
    objectObjectHashMap.put("my_analyzer", new MyAnalyzerProviderFactory());
    return objectObjectHashMap;
}

class MyAnalyzerProviderFactory implements AnalysisModule.AnalysisProvider<AnalyzerProvider<?>> {

    private final MyAnalyzerProvider analyzerProvider;

    public MyAnalyzerProviderFactory() {
        analyzerProvider = new MyAnalyzerProvider(AnalyzerScope.INDICES);
    }

    public AnalyzerProvider<?> create(String name, Settings settings) {
        Version indexVersion = Version.indexCreated(settings);
        if (!Version.CURRENT.equals(indexVersion)) {
            PreBuiltAnalyzers preBuiltAnalyzers = PreBuiltAnalyzers.getOrDefault(name, null);
            if (preBuiltAnalyzers != null) {
                Analyzer analyzer = preBuiltAnalyzers.getAnalyzer(indexVersion);
                return new MyAnalyzerProvider(AnalyzerScope.INDICES);
            }
        }

        return analyzerProvider;
    }

    @Override
    public AnalyzerProvider<?> get(IndexSettings indexSettings, Environment environment, String name, Settings settings)
            throws IOException {
        return create(name, settings);
    }

    public Analyzer analyzer() {
        return analyzerProvider.get();
    }
}


class MyAnalyzerProvider implements AnalyzerProvider<StandardAnalyzer> {

    private final StandardAnalyzer analyzer;
    private final AnalyzerScope scope;

    public MyAnalyzerProvider(AnalyzerScope scope) {
        this.scope = scope;
        this.analyzer = new StandardAnalyzer();
    }

    @Override
    public String name() {
        return "my-standard-analyzer";
    }

    @Override
    public AnalyzerScope scope() {
        return scope;
    }

    @Override
    public StandardAnalyzer get() {
        return analyzer;
    }
}

当然,你也需要调整你的分析器,因为 Lucene 版本已经改变,一些 API 可能被弃用或删除。

看来您已经修正了错误。

但是,我想我会补充我的知识,以防有人 ERROR: 'elasticsearch' directory is missing in the plugin zip 因为我犯了同样的错误。

正如 Elasticsearch 文档 (https://www.elastic.co/guide/en/elasticsearch/plugins/current/plugin-authors.html) 中所述,在将文件夹压缩为 zip 文件之前,插件的文件夹名称应为 "elasticsearch"。

所以,不管zip文件的名字是"elasticsearch-analysis-mecab-ko-5.5.3.0.zip",压缩前的插件文件夹应该叫"elasticsearch"。如果文件夹名称不是 "elasticsearch",当你 运行 elasticsearch-plugin 安装时,你的 elasticsearch 只会给你 ERROR: 'elasticsearch' directory is missing in the plugin zip

因此,在您创建或修改自定义插件文件夹后,将其压缩:

$ zip -r elasticsearch-analysis-mecab-ko-5.5.3.0.zip elasticsearch

然后安装插件

$ ./elasticsearch-plugin install file:///Users/btaek/Desktop/ElasticSearch/elasticsearch-analysis-mecab-ko-5.5.3.0.zip