Plugins: Plugin failed to load since #8666
The method Path.endsWith(String s) doesn't work exactly the same way as String.endsWith() (see http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html#endsWith(java.nio.file.Path)). This blocks the loading of plugins.
This commit is contained in:
parent
d732077900
commit
97ec8f94ae
|
@ -21,7 +21,6 @@ package org.elasticsearch.plugins;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.*;
|
import com.google.common.collect.*;
|
||||||
import com.google.common.primitives.Chars;
|
|
||||||
import org.apache.lucene.util.Constants;
|
import org.apache.lucene.util.Constants;
|
||||||
import org.apache.lucene.util.IOUtils;
|
import org.apache.lucene.util.IOUtils;
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
|
@ -42,13 +41,13 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.file.*;
|
||||||
import java.nio.file.DirectoryStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.elasticsearch.common.io.FileSystemUtils.isAccessibleDirectory;
|
import static org.elasticsearch.common.io.FileSystemUtils.isAccessibleDirectory;
|
||||||
|
@ -61,6 +60,9 @@ public class PluginsService extends AbstractComponent {
|
||||||
public static final String ES_PLUGIN_PROPERTIES = "es-plugin.properties";
|
public static final String ES_PLUGIN_PROPERTIES = "es-plugin.properties";
|
||||||
public static final String LOAD_PLUGIN_FROM_CLASSPATH = "load_classpath_plugins";
|
public static final String LOAD_PLUGIN_FROM_CLASSPATH = "load_classpath_plugins";
|
||||||
|
|
||||||
|
private static final PathMatcher PLUGIN_LIB_MATCHER = FileSystems.getDefault().getPathMatcher("glob:**.{jar,zip}");
|
||||||
|
|
||||||
|
|
||||||
private final Environment environment;
|
private final Environment environment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -368,6 +370,7 @@ public class PluginsService extends AbstractComponent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(pluginsDirectory)) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(pluginsDirectory)) {
|
||||||
|
|
||||||
for (Path plugin : stream) {
|
for (Path plugin : stream) {
|
||||||
// We check that subdirs are directories and readable
|
// We check that subdirs are directories and readable
|
||||||
if (!isAccessibleDirectory(plugin, logger)) {
|
if (!isAccessibleDirectory(plugin, logger)) {
|
||||||
|
@ -389,7 +392,7 @@ public class PluginsService extends AbstractComponent {
|
||||||
|
|
||||||
// if there are jars in it, add it as well
|
// if there are jars in it, add it as well
|
||||||
for (Path libFile : libFiles) {
|
for (Path libFile : libFiles) {
|
||||||
if (!(libFile.getFileName().endsWith(".jar") || libFile.getFileName().endsWith(".zip"))) {
|
if (!hasLibExtension(libFile)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
addURL.invoke(classLoader, libFile.toUri().toURL());
|
addURL.invoke(classLoader, libFile.toUri().toURL());
|
||||||
|
@ -401,6 +404,10 @@ public class PluginsService extends AbstractComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static boolean hasLibExtension(Path lib) {
|
||||||
|
return PLUGIN_LIB_MATCHER.matches(lib);
|
||||||
|
}
|
||||||
|
|
||||||
private Path[] files(Path from) throws IOException {
|
private Path[] files(Path from) throws IOException {
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(from)) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(from)) {
|
||||||
return Iterators.toArray(stream.iterator(), Path.class);
|
return Iterators.toArray(stream.iterator(), Path.class);
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.plugins;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.elasticsearch.action.admin.cluster.node.info.PluginInfo;
|
||||||
|
import org.elasticsearch.common.collect.Tuple;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.nodesinfo.SimpleNodesInfoTests;
|
||||||
|
import org.elasticsearch.plugins.loading.classpath.InClassPathPlugin;
|
||||||
|
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||||
|
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||||
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
|
||||||
|
@ClusterScope(scope= ElasticsearchIntegrationTest.Scope.TEST, numDataNodes=0, numClientNodes = 1, transportClientRatio = 0)
|
||||||
|
public class PluginServiceTests extends ElasticsearchIntegrationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPluginLoadingFromClassName() throws URISyntaxException {
|
||||||
|
Settings settings = settingsBuilder()
|
||||||
|
// Defines a plugin in classpath
|
||||||
|
.put("plugins." + PluginsService.LOAD_PLUGIN_FROM_CLASSPATH, true)
|
||||||
|
.put("plugins." + PluginsService.ES_PLUGIN_PROPERTIES_FILE_KEY, "es-plugin-test.properties")
|
||||||
|
// Defines a plugin in settings
|
||||||
|
.put("plugin.types", InSettingsPlugin.class.getName())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SimpleNodesInfoTests.startNodeWithPlugins(settings, "/org/elasticsearch/plugins/loading/");
|
||||||
|
|
||||||
|
Plugin plugin = getPlugin("in-settings-plugin");
|
||||||
|
assertNotNull("InSettingsPlugin (defined below in this class) must be loaded", plugin);
|
||||||
|
assertThat(plugin, instanceOf(InSettingsPlugin.class));
|
||||||
|
|
||||||
|
plugin = getPlugin("in-classpath-plugin");
|
||||||
|
assertNotNull("InClassPathPlugin (defined in package ) must be loaded", plugin);
|
||||||
|
assertThat(plugin, instanceOf(InClassPathPlugin.class));
|
||||||
|
|
||||||
|
plugin = getPlugin("in-jar-plugin");
|
||||||
|
assertNotNull("InJarPlugin (packaged as a JAR file in a plugins directory) must be loaded", plugin);
|
||||||
|
assertThat(plugin.getClass().getName(), endsWith("InJarPlugin"));
|
||||||
|
|
||||||
|
plugin = getPlugin("in-zip-plugin");
|
||||||
|
assertNotNull("InZipPlugin (packaged as a Zipped file in a plugins directory) must be loaded", plugin);
|
||||||
|
assertThat(plugin.getClass().getName(), endsWith("InZipPlugin"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasLibExtension() {
|
||||||
|
Path p = Paths.get("path", "to", "plugin.jar");
|
||||||
|
assertTrue(PluginsService.hasLibExtension(p));
|
||||||
|
|
||||||
|
p = Paths.get("path", "to", "plugin.zip");
|
||||||
|
assertTrue(PluginsService.hasLibExtension(p));
|
||||||
|
|
||||||
|
p = Paths.get("path", "to", "plugin.tar.gz");
|
||||||
|
assertFalse(PluginsService.hasLibExtension(p));
|
||||||
|
|
||||||
|
p = Paths.get("path", "to", "plugin");
|
||||||
|
assertFalse(PluginsService.hasLibExtension(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Plugin getPlugin(String pluginName) {
|
||||||
|
assertNotNull("cannot check plugin existence with a null plugin's name", pluginName);
|
||||||
|
PluginsService pluginsService = internalCluster().getInstance(PluginsService.class);
|
||||||
|
ImmutableList<Tuple<PluginInfo, Plugin>> plugins = pluginsService.plugins();
|
||||||
|
|
||||||
|
if ((plugins != null) && (!plugins.isEmpty())) {
|
||||||
|
for (Tuple<PluginInfo, Plugin> plugin:plugins) {
|
||||||
|
if (pluginName.equals(plugin.v1().getName())) {
|
||||||
|
return plugin.v2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class InSettingsPlugin extends AbstractPlugin {
|
||||||
|
|
||||||
|
private final Settings settings;
|
||||||
|
|
||||||
|
public InSettingsPlugin(Settings settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "in-settings-plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String description() {
|
||||||
|
return "A plugin defined in settings";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.plugins.loading.classpath;
|
||||||
|
|
||||||
|
import org.elasticsearch.plugins.AbstractPlugin;
|
||||||
|
|
||||||
|
public class InClassPathPlugin extends AbstractPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "in-classpath-plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String description() {
|
||||||
|
return "A plugin defined in class path";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
################################################################
|
||||||
|
# Licensed to Elasticsearch under one or more contributor
|
||||||
|
# license agreements. See the NOTICE file distributed with
|
||||||
|
# this work for additional information regarding copyright
|
||||||
|
# ownership. Elasticsearch licenses this file to you under
|
||||||
|
# the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
################################################################
|
||||||
|
plugin=org.elasticsearch.plugins.loading.classpath.InClassPathPlugin
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue