Reputation: 2319
When I try to install the plugin I built by calling
./elasticsearch-plugin install file:///fullpath/to/zipfile/custome_plugin.zip
It gives me this error:
ERROR: `elasticsearch` directory is missing in the plugin zip
I was reading some other similar posts and many tried to install a .jar instead of .zip. I did try installing .zip, but this same error still shows.
Additionally (might not be related to this issue), when I manually unzip the zip file and put it into plugin folder, doing elasticsearch-plugins list
does list out the custom plugin. In this case the plugin is a custom analyzer, but somehow the mapping doesn't recognize the analyzer. Is it because I did not install it properly?
EDIT:
adding a little info, when I shut down the cluster and then restart after the plugin is manually unzipped and put into the plugin
directory, the cluster wouldn't start. I got error that looks like
[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$5.<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
It seems like this Analysis
Is there some library I'm missing?
EDIT 2: After some more digging, I found this site
http://snacktrace.com/artifacts/org.elasticsearch/elasticsearch/1.7.3/org.elasticsearch.index.analysis.AnalysisModule$AnalysisBinderProcessor$AnalyzersBindings
Seems like this AnalyzersBindings
is only for ES 1.x and 2.x (<2.4)? I need a way to replace this.
EDIT 3: As requested, here's how AnalyzerBinding is used originally
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) {
}
}
then in my AnalyzerPlugin.java I have
public class AnalyzerPlugin extends Plugin {
//some other code here that's not related to Binder
public void onModule(AnalysisModule module) {
module.addProcessor(new AnalyzerBinderProcessor());
}
}
EDIT 4: this is neverending.......
if I keep the @Override, it throws
[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
Also, facing an issue of
[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
because overridden method is final
Is that an update from old Plugin
to new? I'm so lost......
I feel like I need a thorough tutorial of how to create a plugin for custom analyzer, all I can find so far is this
which doesn't help much. Does anyone have a good link?
Upvotes: 0
Views: 4087
Reputation: 572
Looks like you already have fixed your error.
However, I thought I would add my learning in case there are people who are getting ERROR: 'elasticsearch' directory is missing in the plugin zip
becasue of the same mistake that I made.
As it is stated in Elasticsearch documentation (https://www.elastic.co/guide/en/elasticsearch/plugins/current/plugin-authors.html), the folder name of the plugin should be "elasticsearch" before the folder is compressed to a zip file.
So, regardless of the zip file's name like "elasticsearch-analysis-mecab-ko-5.5.3.0.zip", the plugin folder before compressed should be called "elasticsearch". If the folder name is not "elasticsearch", when you run elasticsearch-plugin install, your elasticsearch simply gives you ERROR: 'elasticsearch' directory is missing in the plugin zip
Thus, after you make or amend your custom plugin folder, compress it:
$ zip -r elasticsearch-analysis-mecab-ko-5.5.3.0.zip elasticsearch
then install the plugin
$ ./elasticsearch-plugin install file:///Users/btaek/Desktop/ElasticSearch/elasticsearch-analysis-mecab-ko-5.5.3.0.zip
Upvotes: 6
Reputation: 9320
Currently, in ES 5.x we have org.elasticsearch.plugins.AnalysisPlugin
, which is the main point for creating custom analysis components. You need to adapt your plugin code, so you could register whatever custom analyzer/tokenizer/etc you have.
Example of the plugin, that should do the trick for you:
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;
}
}
Of course, you need to adapt your Analyzer as well, since Lucene version has been changed and some API may be deprecated or removed.
Upvotes: 1