Closed Dc1975 closed 8 years ago
Maybe you need to pass the JCL class loader to the ServiceLoader? https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html#load(java.lang.Class, java.lang.ClassLoader)
Otherwise it might be a problem with how JCL deals with resources (i.e., ServiceLoader not being able to locate and load META-INF/services/org.apache.lucene.codecs.Codec)
It seems that JCL classloader does not work with SPI at all. Normally when you run the following program with lucene-core-4.7.0.jar
in the classpath:
import java.util.Iterator;
import java.util.ServiceLoader;
public class SPITest {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader jcl = SPITest.class.getClassLoader();
Class<?> codecClass = jcl.loadClass("org.apache.lucene.codecs.Codec");
ServiceLoader<?> loader = ServiceLoader.load(codecClass);
int c = 0;
for( Iterator<?> iterator = loader.iterator(); iterator.hasNext(); ) {
c++;
System.out.println("Codec: " + iterator.next());
}
System.out.println("Codecs count: " + c);
}
}
it prints the available codecs list
Codec: Lucene40
Codec: Lucene3x
Codec: Lucene41
Codec: Lucene42
Codec: Lucene45
Codec: Lucene46
Codecs count: 6
But similar program using JCL and loading lucene-core jar dynamically (lucene core jar not in the classpath) does not find any codecs:
import java.util.Iterator;
import java.util.ServiceLoader;
import org.xeustechnologies.jcl.JarClassLoader;
public class SPITest2 {
public static void main(String[] args) throws Exception {
JarClassLoader jcl = new JarClassLoader();
jcl.add("lucene-core-4.7.0.jar");
Class<?> codecClass = jcl.loadClass("org.apache.lucene.codecs.Codec");
ServiceLoader<?> loader = ServiceLoader.load(codecClass, jcl);
int c = 0;
for( Iterator<?> iterator = loader.iterator(); iterator.hasNext(); ) {
System.out.println("Codec: " + iterator.next());
c++;
}
System.out.println("Codecs count: " + c);
}
}
Output: Codecs count: 0
The JCL is instance is provided to service loader.
This is a dealbreak for me and a reason why I need to throw jcl away and go back to URLClassLoader.
Will look into this issue.
any ETA for fixing this issue?
This will be fixed in the next release, due this week.
Fixed in version 2.7.
Any chance I can reopen this?
I just jumped from 2.4 to 2.7 (to fix the intermittent Java8 concurrent modification exception), and now I can no longer create an Elasticsearch (1.7 aka Lucene 2.10.4) Client
object, eg
Thread.currentThread().setContextClassLoader(jcl_classloader);
final ImmutableSettings.Builder test_settings =
ImmutableSettings.settingsBuilder()
.put("cluster.name", "aleph2")
.put("node.gateway.type", "none")
.put("index.store.type", "memory")
.put("index.number_of_replicas", 0)
.put("index.number_of_shards", 1)
.put("node.http.enabled", false);
NodeBuilder.nodeBuilder().settings(test_settings).loadConfigSettings(false).node();
will exception out with
An SPI class of type org.apache.lucene.codecs.Codec with name 'Lucene410' does not exist. You need to add the corresponding JAR file supporting this SPI to your classpath. The current classpath supports the following names: []: IllegalArgumentException]:[NamedSPILoader.java:109:org.apache.lucene.util.NamedSPILoader:lookup]
Identical code works with 2.4, 2.5, 2.6
(EDIT: obviously I can provide more details, just wanted to give an overview of the issue to start with)
I load the "lucene-core-4.10.3.jar" via JCL, it works fine.
Then I create my Class as follows : Object[] arguments = new Object[] { "Param" }; Class[] parameter = new Class[] { String.class };
The constructor of my implementation creates the Lucene "IndexWriterConfig" object which uses the SPI "META-INF/services/org.apache.lucene.codecs.Codec" of the "lucene-core-4.10.3.jar".
The problem is that the SPI - classes were not loaded. Is this a problem of my coding, has anyone a suggestion?