Index: lucene/core/src/java/org/apache/lucene/codecs/Codec.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/Codec.java (revision 1365957) +++ lucene/core/src/java/org/apache/lucene/codecs/Codec.java (working copy) @@ -86,6 +86,21 @@ return loader.availableServices(); } + /** + * Reloads the codec list from the given {@link ClassLoader}. + * Changes to the codecs are visible after the method ends, all + * iterators ({@link #availableCodecs()},...) stay consistent. + * + *
NOTE: Only new codecs are added, existing ones are + * never removed or replaced. + * + *
This method is expensive and should only be called for discovery
+ * of new codecs on the given classpath/classloader!
+ */
+ public static void reloadCodecs(ClassLoader classloader) {
+ loader.reload(classloader);
+ }
+
private static Codec defaultCodec = Codec.forName("Lucene40");
/** expert: returns the default codec used for newly created
Index: lucene/core/src/java/org/apache/lucene/codecs/PostingsFormat.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/PostingsFormat.java (revision 1365957)
+++ lucene/core/src/java/org/apache/lucene/codecs/PostingsFormat.java (working copy)
@@ -70,4 +70,19 @@
public static Set NOTE: Only new postings formats are added, existing ones are
+ * never removed or replaced.
+ *
+ * This method is expensive and should only be called for discovery
+ * of new postings formats on the given classpath/classloader!
+ */
+ public static void reloadPostingsFormats(ClassLoader classloader) {
+ loader.reload(classloader);
+ }
}
Index: lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java (revision 1365957)
+++ lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java (working copy)
@@ -28,16 +28,34 @@
* Helper class for loading named SPIs from classpath (e.g. Codec, PostingsFormat).
* @lucene.internal
*/
-// TODO: would be nice to have case insensitive lookups.
public final class NamedSPILoader NOTE: Only new service providers are added, existing ones are
+ * never removed or replaced.
+ *
+ * This method is expensive and should only be called for discovery
+ * of new service providers on the given classpath/classloader!
+ */
+ public void reload(ClassLoader classloader) {
+ final LinkedHashMap implements Iterable {
- private final Map clazz;
public NamedSPILoader(Class clazz) {
+ this(clazz, Thread.currentThread().getContextClassLoader());
+ }
+
+ public NamedSPILoader(Class clazz, ClassLoader classloader) {
this.clazz = clazz;
- final SPIClassIterator loader = SPIClassIterator.get(clazz);
- final LinkedHashMap loader = SPIClassIterator.get(clazz, classloader);
while (loader.hasNext()) {
final Class extends S> c = loader.next();
try {
Index: solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
===================================================================
--- solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java (revision 1365958)
+++ solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java (working copy)
@@ -37,6 +37,8 @@
import org.apache.lucene.analysis.util.TokenFilterFactory;
import org.apache.lucene.analysis.util.TokenizerFactory;
import org.apache.lucene.analysis.util.AnalysisSPILoader;
+import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.util.WeakIdentityMap;
import org.apache.solr.common.ResourceLoader;
import org.apache.solr.handler.admin.CoreAdminHandler;
@@ -112,7 +114,7 @@
this.classLoader = createClassLoader(null, parent);
addToClassLoader("./lib/", null);
-
+ // reloadCodecSPI(); -> already done by the line above
this.coreProperties = coreProperties;
}
@@ -143,6 +145,7 @@
void addToClassLoader(final String baseDir, final FileFilter filter) {
File base = FileUtils.resolvePath(new File(getInstanceDir()), baseDir);
this.classLoader = replaceClassLoader(classLoader, base, filter);
+ reloadCodecSPI();
}
/**
@@ -163,11 +166,17 @@
return pathname.equals(file);
}
});
+ reloadCodecSPI();
} else {
log.error("Can't find (or read) file to add to classloader: " + file);
}
}
+ private void reloadCodecSPI() {
+ Codec.reloadCodecs(this.classLoader);
+ PostingsFormat.reloadPostingsFormats(this.classLoader);
+ }
+
private static URLClassLoader replaceClassLoader(final URLClassLoader oldLoader,
final File base,
final FileFilter filter) {