mirror of https://github.com/apache/lucene.git
LUCENE-7883: Lucene/Solr no longer uses the context class loader when resolving resources
This commit is contained in:
parent
38f29b2674
commit
5de15ff403
|
@ -151,6 +151,11 @@ Other
|
||||||
current classloader that defined the interface class (lucene-core.jar).
|
current classloader that defined the interface class (lucene-core.jar).
|
||||||
See MIGRATE.txt for more information! (Uwe Schindler, Dawid Weiss)
|
See MIGRATE.txt for more information! (Uwe Schindler, Dawid Weiss)
|
||||||
|
|
||||||
|
* LUCENE-7883: Lucene no longer uses the context class loader when resolving
|
||||||
|
resources in CustomAnalyzer or ClassPathResourceLoader. Resources are only
|
||||||
|
resolved against Lucene's class loader by default. Please use another builder
|
||||||
|
method to change to a custom classloader. (Uwe Schindler)
|
||||||
|
|
||||||
======================= Lucene 6.7.0 =======================
|
======================= Lucene 6.7.0 =======================
|
||||||
|
|
||||||
New Features
|
New Features
|
||||||
|
|
|
@ -35,12 +35,19 @@ If you are migrating your project to Java 9 Jigsaw module system, keep in mind
|
||||||
that Lucene currently does not yet support `module-info.java` declarations of
|
that Lucene currently does not yet support `module-info.java` declarations of
|
||||||
service provider impls (`provides` statement). It is therefore recommended
|
service provider impls (`provides` statement). It is therefore recommended
|
||||||
to keep all of Lucene in one Uber-Module and not try to split Lucene into
|
to keep all of Lucene in one Uber-Module and not try to split Lucene into
|
||||||
several modules. As soon as Lucene will migrate to Java 9 as minimum requirement,
|
several modules. As soon as Lucene will migrate to Java 9 as minimum
|
||||||
we will work on improving that.
|
requirement, we will work on improving that.
|
||||||
|
|
||||||
For OSGI, the same applies. You have to create a bundle with all of Lucene for
|
For OSGI, the same applies. You have to create a bundle with all of Lucene for
|
||||||
SPI to work correctly.
|
SPI to work correctly.
|
||||||
|
|
||||||
|
## CustomAnalyzer resources (LUCENE-7883)##
|
||||||
|
|
||||||
|
Lucene no longer uses the context class loader when resolving resources in
|
||||||
|
CustomAnalyzer or ClassPathResourceLoader. Resources are only resolved
|
||||||
|
against Lucene's class loader by default. Please use another builder method
|
||||||
|
to change to a custom classloader.
|
||||||
|
|
||||||
## Query.hashCode and Query.equals are now abstract methods (LUCENE-7277)
|
## Query.hashCode and Query.equals are now abstract methods (LUCENE-7277)
|
||||||
|
|
||||||
Any custom query subclasses should redeclare equivalence relationship according
|
Any custom query subclasses should redeclare equivalence relationship according
|
||||||
|
|
|
@ -76,17 +76,21 @@ import org.apache.lucene.util.Version;
|
||||||
*/
|
*/
|
||||||
public final class CustomAnalyzer extends Analyzer {
|
public final class CustomAnalyzer extends Analyzer {
|
||||||
|
|
||||||
/** Returns a builder for custom analyzers that loads all resources from classpath.
|
/**
|
||||||
* All path names given must be absolute with package prefixes. */
|
* Returns a builder for custom analyzers that loads all resources from
|
||||||
|
* Lucene's classloader. All path names given must be absolute with package prefixes.
|
||||||
|
*/
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
return builder(new ClasspathResourceLoader());
|
return builder(new ClasspathResourceLoader(CustomAnalyzer.class.getClassLoader()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a builder for custom analyzers that loads all resources from the given
|
/**
|
||||||
|
* Returns a builder for custom analyzers that loads all resources from the given
|
||||||
* file system base directory. Place, e.g., stop word files there.
|
* file system base directory. Place, e.g., stop word files there.
|
||||||
* Files that are not in the given directory are loaded from classpath. */
|
* Files that are not in the given directory are loaded from Lucene's classloader.
|
||||||
|
*/
|
||||||
public static Builder builder(Path configDir) {
|
public static Builder builder(Path configDir) {
|
||||||
return builder(new FilesystemResourceLoader(configDir));
|
return builder(new FilesystemResourceLoader(configDir, CustomAnalyzer.class.getClassLoader()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a builder for custom analyzers that loads all resources using the given {@link ResourceLoader}. */
|
/** Returns a builder for custom analyzers that loads all resources using the given {@link ResourceLoader}. */
|
||||||
|
|
|
@ -20,6 +20,8 @@ package org.apache.lucene.analysis.util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.apache.lucene.util.SuppressForbidden;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple {@link ResourceLoader} that uses {@link ClassLoader#getResourceAsStream(String)}
|
* Simple {@link ResourceLoader} that uses {@link ClassLoader#getResourceAsStream(String)}
|
||||||
* and {@link Class#forName(String,boolean,ClassLoader)} to open resources and
|
* and {@link Class#forName(String,boolean,ClassLoader)} to open resources and
|
||||||
|
@ -30,9 +32,17 @@ public final class ClasspathResourceLoader implements ResourceLoader {
|
||||||
private final ClassLoader loader;
|
private final ClassLoader loader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance using the context classloader to load Resources and classes.
|
* Creates an instance using the context classloader to load resources and classes.
|
||||||
* Resource paths must be absolute.
|
* Resource paths must be absolute.
|
||||||
|
*
|
||||||
|
* @deprecated You should not use this ctor, because it uses the thread's context
|
||||||
|
* class loader, which is bad programming style. Please specify a reference class or
|
||||||
|
* a {@link ClassLoader} instead.
|
||||||
|
* @see #ClasspathResourceLoader(ClassLoader)
|
||||||
|
* @see #ClasspathResourceLoader(Class)
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@SuppressForbidden(reason = "Deprecated method uses thread's context classloader, but there for backwards compatibility")
|
||||||
public ClasspathResourceLoader() {
|
public ClasspathResourceLoader() {
|
||||||
this(Thread.currentThread().getContextClassLoader());
|
this(Thread.currentThread().getContextClassLoader());
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,27 @@ public final class FilesystemResourceLoader implements ResourceLoader {
|
||||||
* base directory (may be {@code null} to refer to CWD).
|
* base directory (may be {@code null} to refer to CWD).
|
||||||
* Files not found in file system and class lookups are delegated to context
|
* Files not found in file system and class lookups are delegated to context
|
||||||
* classloader.
|
* classloader.
|
||||||
|
*
|
||||||
|
* @deprecated You should not use this ctor, because it uses the thread's context
|
||||||
|
* class loader as fallback for resource lookups, which is bad programming style.
|
||||||
|
* Please specify a {@link ClassLoader} instead.
|
||||||
|
* @see #FilesystemResourceLoader(Path, ClassLoader)
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public FilesystemResourceLoader(Path baseDirectory) {
|
public FilesystemResourceLoader(Path baseDirectory) {
|
||||||
this(baseDirectory, new ClasspathResourceLoader());
|
this(baseDirectory, new ClasspathResourceLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a resource loader that resolves resources against the given
|
||||||
|
* base directory (may be {@code null} to refer to CWD).
|
||||||
|
* Files not found in file system and class lookups are delegated to context
|
||||||
|
* classloader.
|
||||||
|
*/
|
||||||
|
public FilesystemResourceLoader(Path baseDirectory, ClassLoader delegate) {
|
||||||
|
this(baseDirectory, new ClasspathResourceLoader(delegate));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a resource loader that resolves resources against the given
|
* Creates a resource loader that resolves resources against the given
|
||||||
* base directory (may be {@code null} to refer to CWD).
|
* base directory (may be {@code null} to refer to CWD).
|
||||||
|
|
|
@ -27,6 +27,10 @@ java.util.Properties#load(java.io.InputStream)
|
||||||
java.util.Properties#save(java.io.OutputStream,java.lang.String)
|
java.util.Properties#save(java.io.OutputStream,java.lang.String)
|
||||||
java.util.Properties#store(java.io.OutputStream,java.lang.String)
|
java.util.Properties#store(java.io.OutputStream,java.lang.String)
|
||||||
|
|
||||||
|
@defaultMessage The context classloader should never be used for resource lookups, unless there is a 3rd party library that needs it. Always pass a classloader down as method parameters.
|
||||||
|
java.lang.Thread#getContextClassLoader()
|
||||||
|
java.lang.Thread#setContextClassLoader(java.lang.ClassLoader)
|
||||||
|
|
||||||
java.lang.Character#codePointBefore(char[],int) @ Implicit start offset is error-prone when the char[] is a buffer and the first chars are random chars
|
java.lang.Character#codePointBefore(char[],int) @ Implicit start offset is error-prone when the char[] is a buffer and the first chars are random chars
|
||||||
java.lang.Character#codePointAt(char[],int) @ Implicit end offset is error-prone when the char[] is a buffer and the last chars are random chars
|
java.lang.Character#codePointAt(char[],int) @ Implicit end offset is error-prone when the char[] is a buffer and the last chars are random chars
|
||||||
|
|
||||||
|
|
|
@ -309,6 +309,10 @@ Other Changes
|
||||||
option to PointsField to ignore 'precisionStep' attribute. This change also begins to attempt to randomize
|
option to PointsField to ignore 'precisionStep' attribute. This change also begins to attempt to randomize
|
||||||
'docValues' on numeric field types unless tests explicity enable/disable them. (hossman, Steve Rowe)
|
'docValues' on numeric field types unless tests explicity enable/disable them. (hossman, Steve Rowe)
|
||||||
|
|
||||||
|
* LUCENE-7883: Solr no longer uses the context class loader when resolving
|
||||||
|
resources, they are only resolved against Solr's own or "core" class loader
|
||||||
|
by default. (Uwe Schindler)
|
||||||
|
|
||||||
================== 6.7.0 ==================
|
================== 6.7.0 ==================
|
||||||
|
|
||||||
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
|
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.apache.commons.lang.ObjectUtils;
|
import org.apache.commons.lang.ObjectUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
@ -40,6 +41,7 @@ import org.apache.solr.common.params.HighlightParams;
|
||||||
import org.apache.solr.common.params.SolrParams;
|
import org.apache.solr.common.params.SolrParams;
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||||
|
import org.apache.solr.common.util.SuppressForbidden;
|
||||||
import org.apache.solr.core.SolrCore;
|
import org.apache.solr.core.SolrCore;
|
||||||
import org.apache.solr.handler.clustering.ClusteringEngine;
|
import org.apache.solr.handler.clustering.ClusteringEngine;
|
||||||
import org.apache.solr.handler.clustering.SearchClusteringEngine;
|
import org.apache.solr.handler.clustering.SearchClusteringEngine;
|
||||||
|
@ -162,21 +164,17 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
|
||||||
+ Arrays.toString(attributeXmls));
|
+ Arrays.toString(attributeXmls));
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread ct = Thread.currentThread();
|
withContextClassLoader(core.getResourceLoader().getClassLoader(), () -> {
|
||||||
ClassLoader prev = ct.getContextClassLoader();
|
try {
|
||||||
try {
|
AttributeValueSets avs = AttributeValueSets.deserialize(attributeXmls[0].open());
|
||||||
ct.setContextClassLoader(core.getResourceLoader().getClassLoader());
|
AttributeValueSet defaultSet = avs.getDefaultAttributeValueSet();
|
||||||
|
initAttributes.putAll(defaultSet.getAttributeValues());
|
||||||
AttributeValueSets avs = AttributeValueSets.deserialize(attributeXmls[0].open());
|
} catch (Exception e) {
|
||||||
AttributeValueSet defaultSet = avs.getDefaultAttributeValueSet();
|
throw new SolrException(ErrorCode.SERVER_ERROR,
|
||||||
initAttributes.putAll(defaultSet.getAttributeValues());
|
"Could not read attributes XML for clustering component: " + componentName, e);
|
||||||
} catch (Exception e) {
|
}
|
||||||
throw new SolrException(ErrorCode.SERVER_ERROR,
|
return null;
|
||||||
"Could not read attributes XML for clustering component: "
|
});
|
||||||
+ componentName, e);
|
|
||||||
} finally {
|
|
||||||
ct.setContextClassLoader(prev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,14 +203,7 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
|
||||||
// certain classes (e.g. custom tokenizer/stemmer) at initialization time.
|
// certain classes (e.g. custom tokenizer/stemmer) at initialization time.
|
||||||
// To make sure classes from contrib JARs are available,
|
// To make sure classes from contrib JARs are available,
|
||||||
// we swap the context class loader for the time of clustering.
|
// we swap the context class loader for the time of clustering.
|
||||||
Thread ct = Thread.currentThread();
|
withContextClassLoader(core.getResourceLoader().getClassLoader(), () -> this.controller.init(initAttributes));
|
||||||
ClassLoader prev = ct.getContextClassLoader();
|
|
||||||
try {
|
|
||||||
ct.setContextClassLoader(core.getResourceLoader().getClassLoader());
|
|
||||||
this.controller.init(initAttributes);
|
|
||||||
} finally {
|
|
||||||
ct.setContextClassLoader(prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
SchemaField uniqueField = core.getLatestSchema().getUniqueKeyField();
|
SchemaField uniqueField = core.getLatestSchema().getUniqueKeyField();
|
||||||
if (uniqueField == null) {
|
if (uniqueField == null) {
|
||||||
|
@ -246,15 +237,9 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
|
||||||
// certain classes (e.g. custom tokenizer/stemmer) at runtime.
|
// certain classes (e.g. custom tokenizer/stemmer) at runtime.
|
||||||
// To make sure classes from contrib JARs are available,
|
// To make sure classes from contrib JARs are available,
|
||||||
// we swap the context class loader for the time of clustering.
|
// we swap the context class loader for the time of clustering.
|
||||||
Thread ct = Thread.currentThread();
|
return withContextClassLoader(core.getResourceLoader().getClassLoader(),
|
||||||
ClassLoader prev = ct.getContextClassLoader();
|
() -> clustersToNamedList(controller.process(attributes,
|
||||||
try {
|
clusteringAlgorithmClass).getClusters(), sreq.getParams()));
|
||||||
ct.setContextClassLoader(core.getResourceLoader().getClassLoader());
|
|
||||||
return clustersToNamedList(controller.process(attributes,
|
|
||||||
clusteringAlgorithmClass).getClusters(), sreq.getParams());
|
|
||||||
} finally {
|
|
||||||
ct.setContextClassLoader(prev);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Carrot2 clustering failed", e);
|
log.error("Carrot2 clustering failed", e);
|
||||||
throw new SolrException(ErrorCode.SERVER_ERROR, "Carrot2 clustering failed", e);
|
throw new SolrException(ErrorCode.SERVER_ERROR, "Carrot2 clustering failed", e);
|
||||||
|
@ -562,4 +547,17 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressForbidden(reason = "Uses context class loader as a workaround to inject correct classloader to 3rd party libs")
|
||||||
|
private static <T> T withContextClassLoader(ClassLoader loader, Supplier<T> action) {
|
||||||
|
Thread ct = Thread.currentThread();
|
||||||
|
ClassLoader prev = ct.getContextClassLoader();
|
||||||
|
try {
|
||||||
|
ct.setContextClassLoader(loader);
|
||||||
|
return action.get();
|
||||||
|
} finally {
|
||||||
|
ct.setContextClassLoader(prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.solr.handler.dataimport;
|
||||||
|
|
||||||
import com.sun.mail.imap.IMAPMessage;
|
import com.sun.mail.imap.IMAPMessage;
|
||||||
|
|
||||||
|
import org.apache.solr.common.util.SuppressForbidden;
|
||||||
import org.apache.solr.handler.dataimport.config.ConfigNameConstants;
|
import org.apache.solr.handler.dataimport.config.ConfigNameConstants;
|
||||||
import org.apache.solr.util.RTimer;
|
import org.apache.solr.util.RTimer;
|
||||||
import org.apache.tika.Tika;
|
import org.apache.tika.Tika;
|
||||||
|
@ -37,6 +38,7 @@ import java.lang.invoke.MethodHandles;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.sun.mail.gimap.GmailFolder;
|
import com.sun.mail.gimap.GmailFolder;
|
||||||
import com.sun.mail.gimap.GmailRawSearchTerm;
|
import com.sun.mail.gimap.GmailRawSearchTerm;
|
||||||
|
@ -213,7 +215,14 @@ public class MailEntityProcessor extends EntityProcessorBase {
|
||||||
|
|
||||||
private Message getNextMail() {
|
private Message getNextMail() {
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
if (!connectToMailBox()) return null;
|
// this is needed to load the activation mail stuff correctly
|
||||||
|
// otherwise, the JavaMail multipart support doesn't get configured
|
||||||
|
// correctly, which leads to a class cast exception when processing
|
||||||
|
// multipart messages: IMAPInputStream cannot be cast to
|
||||||
|
// javax.mail.Multipart
|
||||||
|
if (false == withContextClassLoader(getClass().getClassLoader(), this::connectToMailBox)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
connected = true;
|
connected = true;
|
||||||
}
|
}
|
||||||
if (folderIter == null) {
|
if (folderIter == null) {
|
||||||
|
@ -358,13 +367,6 @@ public class MailEntityProcessor extends EntityProcessorBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean connectToMailBox() {
|
private boolean connectToMailBox() {
|
||||||
// this is needed to load the activation mail stuff correctly
|
|
||||||
// otherwise, the JavaMail multipart support doesn't get configured
|
|
||||||
// correctly, which leads to a class cast exception when processing
|
|
||||||
// multipart messages: IMAPInputStream cannot be cast to
|
|
||||||
// javax.mail.Multipart
|
|
||||||
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
if (System.getProperty("mail.debug") != null)
|
if (System.getProperty("mail.debug") != null)
|
||||||
|
@ -870,4 +872,17 @@ public class MailEntityProcessor extends EntityProcessorBase {
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressForbidden(reason = "Uses context class loader as a workaround to inject correct classloader to 3rd party libs")
|
||||||
|
private static <T> T withContextClassLoader(ClassLoader loader, Supplier<T> action) {
|
||||||
|
Thread ct = Thread.currentThread();
|
||||||
|
ClassLoader prev = ct.getContextClassLoader();
|
||||||
|
try {
|
||||||
|
ct.setContextClassLoader(loader);
|
||||||
|
return action.get();
|
||||||
|
} finally {
|
||||||
|
ct.setContextClassLoader(prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ public class SolrResourceLoader implements ResourceLoader,Closeable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* This loader will delegate to the context classloader when possible,
|
* This loader will delegate to Solr's classloader when possible,
|
||||||
* otherwise it will attempt to resolve resources using any jar files
|
* otherwise it will attempt to resolve resources using any jar files
|
||||||
* found in the "lib/" directory in the specified instance directory.
|
* found in the "lib/" directory in the specified instance directory.
|
||||||
* </p>
|
* </p>
|
||||||
|
@ -162,9 +162,10 @@ public class SolrResourceLoader implements ResourceLoader,Closeable
|
||||||
log.debug("new SolrResourceLoader for directory: '{}'", this.instanceDir);
|
log.debug("new SolrResourceLoader for directory: '{}'", this.instanceDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent == null)
|
if (parent == null) {
|
||||||
parent = Thread.currentThread().getContextClassLoader();
|
parent = getClass().getClassLoader();
|
||||||
this.classLoader = new URLClassLoader(new URL[0], parent);
|
}
|
||||||
|
this.classLoader = URLClassLoader.newInstance(new URL[0], parent);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip the lib subdirectory when we are loading from the solr home.
|
* Skip the lib subdirectory when we are loading from the solr home.
|
||||||
|
|
|
@ -357,11 +357,11 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String path = ZkStateReader.CONFIGS_ZKNODE + "/" + SYSTEM_COLL + "/schema.xml";
|
String path = ZkStateReader.CONFIGS_ZKNODE + "/" + SYSTEM_COLL + "/schema.xml";
|
||||||
byte[] data = IOUtils.toByteArray(Thread.currentThread().getContextClassLoader().getResourceAsStream("SystemCollectionSchema.xml"));
|
byte[] data = IOUtils.toByteArray(CollectionsHandler.class.getResourceAsStream("/SystemCollectionSchema.xml"));
|
||||||
assert data != null && data.length > 0;
|
assert data != null && data.length > 0;
|
||||||
cmdExecutor.ensureExists(path, data, CreateMode.PERSISTENT, zk);
|
cmdExecutor.ensureExists(path, data, CreateMode.PERSISTENT, zk);
|
||||||
path = ZkStateReader.CONFIGS_ZKNODE + "/" + SYSTEM_COLL + "/solrconfig.xml";
|
path = ZkStateReader.CONFIGS_ZKNODE + "/" + SYSTEM_COLL + "/solrconfig.xml";
|
||||||
data = IOUtils.toByteArray(Thread.currentThread().getContextClassLoader().getResourceAsStream("SystemCollectionSolrConfig.xml"));
|
data = IOUtils.toByteArray(CollectionsHandler.class.getResourceAsStream("/SystemCollectionSolrConfig.xml"));
|
||||||
assert data != null && data.length > 0;
|
assert data != null && data.length > 0;
|
||||||
cmdExecutor.ensureExists(path, data, CreateMode.PERSISTENT, zk);
|
cmdExecutor.ensureExists(path, data, CreateMode.PERSISTENT, zk);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -265,7 +265,7 @@ public class SolrDispatchFilter extends BaseSolrFilter {
|
||||||
*/
|
*/
|
||||||
public static NodeConfig loadNodeConfig(Path solrHome, Properties nodeProperties) {
|
public static NodeConfig loadNodeConfig(Path solrHome, Properties nodeProperties) {
|
||||||
|
|
||||||
SolrResourceLoader loader = new SolrResourceLoader(solrHome, null, nodeProperties);
|
SolrResourceLoader loader = new SolrResourceLoader(solrHome, SolrDispatchFilter.class.getClassLoader(), nodeProperties);
|
||||||
if (!StringUtils.isEmpty(System.getProperty("solr.solrxml.location"))) {
|
if (!StringUtils.isEmpty(System.getProperty("solr.solrxml.location"))) {
|
||||||
log.warn("Solr property solr.solrxml.location is no longer supported. " +
|
log.warn("Solr property solr.solrxml.location is no longer supported. " +
|
||||||
"Will automatically load solr.xml from ZooKeeper if it exists");
|
"Will automatically load solr.xml from ZooKeeper if it exists");
|
||||||
|
|
|
@ -486,7 +486,7 @@ public class SolrCLI {
|
||||||
private static List<Class<Tool>> findToolClassesInPackage(String packageName) {
|
private static List<Class<Tool>> findToolClassesInPackage(String packageName) {
|
||||||
List<Class<Tool>> toolClasses = new ArrayList<Class<Tool>>();
|
List<Class<Tool>> toolClasses = new ArrayList<Class<Tool>>();
|
||||||
try {
|
try {
|
||||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader classLoader = SolrCLI.class.getClassLoader();
|
||||||
String path = packageName.replace('.', '/');
|
String path = packageName.replace('.', '/');
|
||||||
Enumeration<URL> resources = classLoader.getResources(path);
|
Enumeration<URL> resources = classLoader.getResources(path);
|
||||||
Set<String> classes = new TreeSet<String>();
|
Set<String> classes = new TreeSet<String>();
|
||||||
|
|
|
@ -241,8 +241,8 @@ public class TestCoreContainer extends SolrTestCaseJ4 {
|
||||||
final CoreContainer cc = init(CONFIGSETS_SOLR_XML);
|
final CoreContainer cc = init(CONFIGSETS_SOLR_XML);
|
||||||
try {
|
try {
|
||||||
ClassLoader sharedLoader = cc.loader.getClassLoader();
|
ClassLoader sharedLoader = cc.loader.getClassLoader();
|
||||||
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader baseLoader = SolrResourceLoader.class.getClassLoader();
|
||||||
assertSame(contextLoader, sharedLoader.getParent());
|
assertSame(baseLoader, sharedLoader.getParent());
|
||||||
|
|
||||||
SolrCore core1 = cc.create("core1", ImmutableMap.of("configSet", "minimal"));
|
SolrCore core1 = cc.create("core1", ImmutableMap.of("configSet", "minimal"));
|
||||||
ClassLoader coreLoader = core1.getResourceLoader().getClassLoader();
|
ClassLoader coreLoader = core1.getResourceLoader().getClassLoader();
|
||||||
|
|
|
@ -193,8 +193,7 @@ public class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object fromJSONResource(String resourceName){
|
public static Object fromJSONResource(String resourceName){
|
||||||
return fromJSON(Thread.currentThread()
|
return fromJSON(Utils.class.getClassLoader().getResourceAsStream(resourceName));
|
||||||
.getContextClassLoader().getResourceAsStream(resourceName));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public static JSONParser getJSONParser(Reader reader){
|
public static JSONParser getJSONParser(Reader reader){
|
||||||
|
|
|
@ -313,7 +313,7 @@ public class ValidatingJsonMap implements Map<String, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValidatingJsonMap parse(String resourceName, String includeLocation) {
|
public static ValidatingJsonMap parse(String resourceName, String includeLocation) {
|
||||||
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName);
|
InputStream is = ValidatingJsonMap.class.getClassLoader().getResourceAsStream(resourceName);
|
||||||
if (is == null)
|
if (is == null)
|
||||||
throw new RuntimeException("invalid API spec: " + resourceName);
|
throw new RuntimeException("invalid API spec: " + resourceName);
|
||||||
ValidatingJsonMap map = null;
|
ValidatingJsonMap map = null;
|
||||||
|
|
|
@ -1891,7 +1891,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
||||||
* {@link Class#getResourceAsStream} using {@code this.getClass()}.
|
* {@link Class#getResourceAsStream} using {@code this.getClass()}.
|
||||||
*/
|
*/
|
||||||
public static File getFile(String name) {
|
public static File getFile(String name) {
|
||||||
final URL url = Thread.currentThread().getContextClassLoader().getResource(name.replace(File.separatorChar, '/'));
|
final URL url = SolrTestCaseJ4.class.getClassLoader().getResource(name.replace(File.separatorChar, '/'));
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
try {
|
try {
|
||||||
return new File(url.toURI());
|
return new File(url.toURI());
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class ExternalPaths {
|
||||||
try {
|
try {
|
||||||
file = new File("solr/conf");
|
file = new File("solr/conf");
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
file = new File(Thread.currentThread().getContextClassLoader().getResource("solr/conf").toURI());
|
file = new File(ExternalPaths.class.getClassLoader().getResource("solr/conf").toURI());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// If there is no "solr/conf" in the classpath, fall back to searching from the current directory.
|
// If there is no "solr/conf" in the classpath, fall back to searching from the current directory.
|
||||||
|
|
Loading…
Reference in New Issue