Sto usando Java SE 6 su Mac OS X e Saxon-HE 9.3.0.5. ServiceLoader non è in grado di trovare l'implementazione Saxon di javax.xml.xpath.XPathFactory
.Errore di sintassi in javax.xml.xpath.XPathFactory file di configurazione del provider di Saxon-HE 9.3
mac:test2 ludo$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)
Javadoc del metodo newInstance
di javax.xml.xpath.XPathFactory
stati al punto 3 della procedura di ricerca per localizzare un'implementazione che:
Il caricatore di classe è chiesto per i file di provider di configurazione del provider di servizi corrispondenti javax. xml.xpath.XPathFactory nella directory delle risorse META-INF/services. Vedere la specifica del file JAR per il formato del file e le regole di analisi.
La Service Provider section della specifica JAR File afferma che:
Il file dovrebbe contenere un elenco separato da fine riga di nomi concreti unici provider di classe.
Ma se ho estratto il file saxon9he.jar e guardo nella directory META-INF, vedo:
mac:Java ludo$ mkdir test
mac:Java ludo$ cd test
mac:test ludo$ jar fx ../saxon9he.jar
mac:test ludo$ cat META-INF/services/javax.xml.xpath.XPathFactory
net.sf.saxon.xpath.XPathFactoryImpl
http\://java.sun.com/jaxp/xpath/dom: net.sf.saxon.xpath.XPathFactoryImpl
http\://saxon.sf.net/jaxp/xpath/om: net.sf.saxon.xpath.XPathFactoryImpl
La prima linea è corretta, ma non riesco a vedere il motivo per cui ci sono due extra linee e sembra che quelle linee stiano causando problemi a ServiceLoader. Ho visto il problema con un esempio di prova che ho scritto per capire il meccanismo usato per trovare un fornitore. Possiamo vedere che saxon9he.jar si trova nel CLASSPATH.
mac:services ludo$ java ServicesTest
CLASSPATH = ..., /Users/ludo/Library/Java/saxon9he.jar, ...
Service XPathFactory: java.util.ServiceLoader[javax.xml.xpath.XPathFactory]
ServiceConfigurationError: javax.xml.xpath.XPathFactory: jar:file:/Users/ludo/Library/Java/saxon9he.jar!/META-INF/services/javax.xml.xpath.XPathFactory:2: Illegal configuration-file syntax
La linea di interesse:
jar:file:/Users/ludo/Library/Java/saxon9he.jar!/META-INF/services/javax.xml.xpath.XPathFactory:2: Illegal configuration-file syntax
Si tratta di un bug di Saxon o di una sintassi estesa non supportato dal mio sistema? Cosa potrei fare per risolvere il problema?
Nota che se scelgo esplicitamente la classe per l'implementazione, posso ottenere una fabbrica. Ma voglio usare il meccanismo dei servizi. Il seguente codice funziona:
XPathFactory xpf = XPathFactory.newInstance(
XPathFactory.DEFAULT_OBJECT_MODEL_URI,
"net.sf.saxon.xpath.XPathFactoryImpl",
ClassLoader.getSystemClassLoader());
Ho aggiunto l'intero programma di test Java di seguito.
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import javax.xml.xpath.XPathFactory;
public class ServicesTest {
public static String getClasspathString() {
StringBuilder classpath = new StringBuilder();
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader) classLoader).getURLs();
for (int i = 0; i < urls.length - 1; i++) {
classpath.append(urls[i].getFile()).append(", ");
}
if (urls.length > 0) {
classpath.append(urls[urls.length - 1].getFile());
}
return classpath.toString();
}
public static void availableProviders(ServiceLoader sl) {
Iterator it = sl.iterator();
int index = 0;
for (;;) {
try {
if (!it.hasNext()) {
break;
}
index++;
Object o = it.next();
System.out.printf("%03d Concrete class name: %s\n", index, o.getClass().getName());
} catch (ServiceConfigurationError e) {
System.err.printf("ServiceConfigurationError: %s\n", e.getMessage());
}
}
}
public static void main(String[] args) {
System.out.printf("CLASSPATH = %s\n", getClasspathString());
System.out.println();
ServiceLoader<XPathFactory> slXPathFactory = ServiceLoader.load(XPathFactory.class);
System.out.printf("Service XPathFactory: %s\n", slXPathFactory.toString());
availableProviders(slXPathFactory);
}
}
È possibile estrarre il file direttamente sulla riga di comando in un passaggio con "decomprimi -p /path/to/lib/jarfile.jar META-INF/services/javax.xml.xpath.XPathFactory" –