You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2021/03/10 09:45:55 UTC
[lucene] 14/21: fixed SolrCOreAware and ResourceLoaderAware bugs
This is an automated email from the ASF dual-hosted git repository.
dweiss pushed a commit to branch jira/solr14155
in repository https://gitbox.apache.org/repos/asf/lucene.git
commit e501ef59ec0f1a21193eead845c773d6307d3409
Author: noble <no...@apache.org>
AuthorDate: Sat Dec 28 01:16:31 2019 +1100
fixed SolrCOreAware and ResourceLoaderAware bugs
---
.../src/java/org/apache/solr/core/PluginInfo.java | 18 ++--
.../java/org/apache/solr/core/SolrClassLoader.java | 7 +-
.../org/apache/solr/core/SolrResourceLoader.java | 24 +++++-
.../org/apache/solr/handler/SchemaHandler.java | 6 +-
.../java/org/apache/solr/pkg/PackageLoader.java | 14 ++++
.../org/apache/solr/pkg/PackagePluginHolder.java | 4 +
.../java/org/apache/solr/schema/IndexSchema.java | 97 ++++++++++++++--------
7 files changed, 117 insertions(+), 53 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/core/PluginInfo.java b/solr/core/src/java/org/apache/solr/core/PluginInfo.java
index cfef933..021fcea 100644
--- a/solr/core/src/java/org/apache/solr/core/PluginInfo.java
+++ b/solr/core/src/java/org/apache/solr/core/PluginInfo.java
@@ -41,7 +41,7 @@ import static org.apache.solr.schema.FieldType.CLASS_NAME;
*/
public class PluginInfo implements MapSerializable {
public final String name, className, type, pkgName;
- public final ClassName cName;
+ public final ParsedClassName cName;
public final NamedList initArgs;
public final Map<String, String> attributes;
public final List<PluginInfo> children;
@@ -52,7 +52,7 @@ public class PluginInfo implements MapSerializable {
public PluginInfo(String type, Map<String, String> attrs, NamedList initArgs, List<PluginInfo> children) {
this.type = type;
this.name = attrs.get(NAME);
- cName = new ClassName(attrs.get(CLASS_NAME));
+ cName = new ParsedClassName(attrs.get(CLASS_NAME));
this.className = cName.klas;
this.pkgName = cName.pkg;
this.initArgs = initArgs;
@@ -65,13 +65,13 @@ public class PluginInfo implements MapSerializable {
* This checks if it is a package name prefixed classname.
*/
- public static class ClassName {
+ public static class ParsedClassName {
public final String pkg;
public final String klas;
- private final String actual;
+ public final String original;
- public ClassName(String name) {
- this.actual = name;
+ public ParsedClassName(String name) {
+ this.original = name;
String pkgName = null;
String className = name;
if (name != null) {
@@ -88,7 +88,7 @@ public class PluginInfo implements MapSerializable {
@Override
public String toString() {
- return actual;
+ return original;
}
}
@@ -96,7 +96,7 @@ public class PluginInfo implements MapSerializable {
public PluginInfo(Node node, String err, boolean requireName, boolean requireClass) {
type = node.getNodeName();
name = DOMUtil.getAttr(node, NAME, requireName ? err : null);
- cName = new ClassName(DOMUtil.getAttr(node, CLASS_NAME, requireClass ? err : null));
+ cName = new ParsedClassName(DOMUtil.getAttr(node, CLASS_NAME, requireClass ? err : null));
className = cName.klas;
pkgName = cName.pkg;
initArgs = DOMUtil.childNodesToNamedList(node);
@@ -128,7 +128,7 @@ public class PluginInfo implements MapSerializable {
}
this.type = type;
this.name = (String) m.get(NAME);
- cName = new ClassName((String) m.get(CLASS_NAME));
+ cName = new ParsedClassName((String) m.get(CLASS_NAME));
this.className = cName.klas;
this.pkgName = cName.pkg;
attributes = unmodifiableMap(m);
diff --git a/solr/core/src/java/org/apache/solr/core/SolrClassLoader.java b/solr/core/src/java/org/apache/solr/core/SolrClassLoader.java
index b260e07..8995c80 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrClassLoader.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrClassLoader.java
@@ -19,10 +19,13 @@ package org.apache.solr.core;
import java.io.Closeable;
-/**A generic interface to load classes
+import org.apache.lucene.analysis.util.ResourceLoader;
+
+/**
+ * A generic interface to load classes and resources. This helps us to avoid using {@link SolrResourceLoader} directly
*
*/
-public interface SolrClassLoader extends Closeable {
+public interface SolrClassLoader extends Closeable, ResourceLoader {
<T> T newInstance(String cname, Class<T> expectedType, String... subpackages);
diff --git a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
index 2ad001b..3927911 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
@@ -82,7 +82,7 @@ import org.slf4j.LoggerFactory;
/**
* @since solr 1.3
*/
-public class SolrResourceLoader implements ResourceLoader, SolrClassLoader {
+public class SolrResourceLoader implements SolrClassLoader {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
static final String project = "solr";
@@ -698,6 +698,12 @@ public class SolrResourceLoader implements ResourceLoader, SolrClassLoader {
"Error instantiating class: '" + clazz.getName() + "'", e);
}
+ registerForCallbacks(obj);
+
+ return obj;
+ }
+
+ protected <T> void registerForCallbacks(T obj) {
if (!live) {
if (obj instanceof SolrCoreAware) {
assertAwareCompatibility(SolrCoreAware.class, obj);
@@ -712,8 +718,6 @@ public class SolrResourceLoader implements ResourceLoader, SolrClassLoader {
infoMBeans.add((SolrInfoBean) obj);
}
}
-
- return obj;
}
@@ -742,6 +746,18 @@ public class SolrResourceLoader implements ResourceLoader, SolrClassLoader {
live = true;
}
+ public void registerSolrCoreAware(SolrCoreAware obj) {
+ assertAwareCompatibility(SolrCoreAware.class, obj);
+ if (live) {
+ //this core is already live
+ if (this.core != null) {
+ obj.inform(this.core);
+ }
+ } else {
+ waitingForCore.add(obj);
+ }
+ }
+
/**
* Tell all {@link ResourceLoaderAware} instances about the loader
*/
@@ -924,7 +940,7 @@ public class SolrResourceLoader implements ResourceLoader, SolrClassLoader {
/**
* Utility function to throw an exception if the class is invalid
*/
- static void assertAwareCompatibility(Class aware, Object obj) {
+ public static void assertAwareCompatibility(Class aware, Object obj) {
Class[] valid = awareCompatibility.get(aware);
if (valid == null) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
diff --git a/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java b/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
index f6a7c95..b33629b 100644
--- a/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
@@ -226,12 +226,12 @@ public class SchemaHandler extends RequestHandlerBase implements SolrCoreAware,
Object v = nl.get("class");
if (v instanceof String) {
String klas = (String) v;
- PluginInfo.ClassName className = new PluginInfo.ClassName(klas);
- if (className.pkg != null) {
+ PluginInfo.ParsedClassName parsedClassName = new PluginInfo.ParsedClassName(klas);
+ if (parsedClassName.pkg != null) {
req.getCore().getPackageListeners().forEachListener(listener -> {
PluginInfo pluginInfo = listener.pluginInfo();
if (pluginInfo == null) return;
- if (Objects.equals(pluginInfo.cName.toString(), className.toString())) {
+ if (Objects.equals(pluginInfo.cName.toString(), parsedClassName.toString())) {
nl.add("_packageinfo_", listener.getPackageVersion());
}
});
diff --git a/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java b/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java
index c9ef000..178d3a5 100644
--- a/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java
+++ b/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java
@@ -34,6 +34,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import org.apache.lucene.analysis.util.ResourceLoaderAware;
import org.apache.solr.common.MapWriter;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.core.CoreContainer;
@@ -269,6 +270,19 @@ public class PackageLoader implements Closeable {
protected void initSPI() {
//no op
}
+
+ @Override
+ protected <T> void registerForCallbacks(T obj) {
+ if (obj instanceof ResourceLoaderAware) {
+ assertAwareCompatibility(ResourceLoaderAware.class, obj);
+ try {
+ ((ResourceLoaderAware) obj).inform(this);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+ }
};
} catch (MalformedURLException e) {
log.error("Could not load classloader ", e);
diff --git a/solr/core/src/java/org/apache/solr/pkg/PackagePluginHolder.java b/solr/core/src/java/org/apache/solr/pkg/PackagePluginHolder.java
index b15c524..1cdd104 100644
--- a/solr/core/src/java/org/apache/solr/pkg/PackagePluginHolder.java
+++ b/solr/core/src/java/org/apache/solr/pkg/PackagePluginHolder.java
@@ -24,6 +24,7 @@ import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.RequestParams;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrCore;
+import org.apache.solr.util.plugin.SolrCoreAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -120,6 +121,9 @@ public class PackagePluginHolder<T> extends PluginBag.PluginHolder<T> {
Object instance = SolrCore.createInstance(pluginInfo.className,
pluginMeta.clazz, pluginMeta.getCleanTag(), core, newest.getLoader());
PluginBag.initInstance(instance, pluginInfo);
+ if (instance instanceof SolrCoreAware) {
+ core.getResourceLoader().registerSolrCoreAware((SolrCoreAware) instance);
+ }
T old = inst;
inst = (T) instance;
if (old instanceof AutoCloseable) {
diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
index ab8d49b..8650b6d 100644
--- a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
+++ b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
@@ -21,6 +21,7 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import java.io.Closeable;
import java.io.IOException;
+import java.io.InputStream;
import java.io.Writer;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
@@ -228,52 +229,38 @@ public class IndexSchema implements Closeable {
}
@Override
+ public InputStream openResource(String resource) throws IOException {
+ return loader.openResource(resource);
+ }
+
+ @Override
+ public <T> T newInstance(String cname, Class<T> expectedType) {
+ return loadWithRightPackageLoader(cname, expectedType,
+ (pkgloader, name) -> pkgloader.newInstance(name, expectedType));
+ }
+
+ @Override
public <T> T newInstance(String cname, Class<T> expectedType, String... subpackages) {
return loadWithRightPackageLoader(cname, expectedType,
(pkgloader, name) -> pkgloader.newInstance(name, expectedType, subpackages));
}
private <T> T loadWithRightPackageLoader(String cname, Class expectedType, BiFunction<SolrClassLoader, String, T> fun) {
- PluginInfo.ClassName className = new PluginInfo.ClassName(cname);
- if (className.pkg == null) {
- return fun.apply(loader, className.klas);
+ PluginInfo.ParsedClassName parsedClassName = new PluginInfo.ParsedClassName(cname);
+ if (parsedClassName.pkg == null) {
+ return fun.apply(loader, parsedClassName.klas);
} else {
- PackageLoader.Package pkg = core.getCoreContainer().getPackageLoader().getPackage(className.pkg);
+ PackageLoader.Package pkg = core.getCoreContainer().getPackageLoader().getPackage(parsedClassName.pkg);
PackageLoader.Package.Version ver = PackagePluginHolder.getRightVersion(pkg, core);
- T inst = fun.apply(ver.getLoader(),className.klas);
+ T result = fun.apply(ver.getLoader(), parsedClassName.klas);
+ if (result instanceof SolrCoreAware) {
+ loader.registerSolrCoreAware((SolrCoreAware) result);
+ }
classNameVsPkg.put(cname, ver.getVersionInfo());
- PackageListeners.Listener listener = new PackageListeners.Listener() {
-
- PluginInfo info = new PluginInfo(expectedType.getSimpleName(), singletonMap("class", cname));
-
- @Override
- public String packageName() {
- return className.pkg;
- }
-
- @Override
- public PluginInfo pluginInfo() {
- return info;
- }
-
- @Override
- public void changed(PackageLoader.Package pkg, PackageListeners.Ctx ctx) {
- PackageLoader.Package.Version rightVersion = PackagePluginHolder.getRightVersion(pkg, core);
- if (rightVersion == null ) return;
- PackageAPI.PkgVersion v = classNameVsPkg.get(className.toString());
- if(Objects.equals(v.version ,rightVersion.getVersionInfo().version)) return; //nothing has changed no need to reload
- Runnable old = ctx.getPostProcessor(PackageAwarePluginLoader.class.getName());// just want to do one refresh for every package laod
- if (old == null) ctx.addPostProcessor(PackageAwarePluginLoader.class.getName(), reloadSchemaRunnable);
- }
-
- @Override
- public PackageAPI.PkgVersion getPackageVersion() {
- return classNameVsPkg.get(cname);
- }
- };
+ PackageListeners.Listener listener = new SchemaPluginPackageListener(expectedType, cname, parsedClassName);
listeners.add(listener);
core.getPackageListeners().addListener(listener);
- return inst;
+ return result;
}
}
@@ -296,6 +283,46 @@ public class IndexSchema implements Closeable {
}
}
+
+ private class SchemaPluginPackageListener implements PackageListeners.Listener {
+
+ private final Class expectedType;
+ private final String cname;
+ private final PluginInfo.ParsedClassName parsedClassName;
+ PluginInfo info;
+
+ public SchemaPluginPackageListener(Class expectedType, String cname, PluginInfo.ParsedClassName parsedClassName) {
+ this.expectedType = expectedType;
+ this.cname = cname;
+ this.parsedClassName = parsedClassName;
+ info = new PluginInfo(expectedType.getSimpleName(), singletonMap("class", cname));
+ }
+
+ @Override
+ public String packageName() {
+ return parsedClassName.pkg;
+ }
+
+ @Override
+ public PluginInfo pluginInfo() {
+ return info;
+ }
+
+ @Override
+ public void changed(PackageLoader.Package pkg, PackageListeners.Ctx ctx) {
+ PackageLoader.Package.Version rightVersion = PackagePluginHolder.getRightVersion(pkg, core);
+ if (rightVersion == null ) return;
+ PackageAPI.PkgVersion v = classNameVsPkg.get(parsedClassName.toString());
+ if(Objects.equals(v.version ,rightVersion.getVersionInfo().version)) return; //nothing has changed no need to reload
+ Runnable old = ctx.getPostProcessor(PackageAwarePluginLoader.class.getName());// just want to do one refresh for every package laod
+ if (old == null) ctx.addPostProcessor(PackageAwarePluginLoader.class.getName(), reloadSchemaRunnable);
+ }
+
+ @Override
+ public PackageAPI.PkgVersion getPackageVersion() {
+ return classNameVsPkg.get(cname);
+ }
+ }
}
/**