2009-11-25 11 views
27

Ich möchte diagnostische Informationen darüber, welche JAXP-Implementierung verwendet wird, und welche JAR-Datei, aus der es geladen wurde, bereitstellen.Wie finde ich heraus, welche JAXP-Implementierung verwendet wird und woher sie geladen wurde?

Eine Möglichkeit, dies zu erreichen, ist in Instanz, zum Beispiel zu erstellen, ein DocumentBuilderFactory und überprüft dann die Eigenschaften dieser Klasse:

private static String GetJaxpImplementation() { 
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 
    Class<? extends DocumentBuilderFactory> c = documentBuilderFactory.getClass(); 
    Package p = c.getPackage(); 
    CodeSource source = c.getProtectionDomain().getCodeSource(); 
    return MessageFormat.format(
      "Using JAXP implementation ''{0}'' ({1}) version {2} ({3}){4}", 
      p.getName(), 
      p.getImplementationVendor(), 
      p.getSpecificationVersion(), 
      p.getImplementationVersion(), 
      source == null ? "." : " loaded from: " + source.getLocation()); 
} 

Gibt es einen besseren Weg, dies zu erreichen, vielleicht ohne um eine DocumentBuilderFactory zu erstellen?

Antwort

47

Es ist ziemlich schwierig vorherzusagen, welche konkrete JAXP-Factory-Implementierung geladen wird, ohne tatsächlich eine Instanz zu erstellen, da der Prozess eine Implementierung auswählt.

Von Official JAXP FAQ (Frage 14):

Wenn eine Anwendung will ein neuen JAXP DocumentBuilderFactory Instanz erstellen, ruft es die staic Methode DocumentBuilderFactory.newInstance(). Dies bewirkt, dass eine Suche nach dem Namen einer konkreten Unterklasse von DocumentBuilderFactory mit der folgenden Reihenfolge:

  1. Den Wert einer Systemeigenschaft wie javax.xml.parsers.DocumentBuilderFactory wenn es vorhanden ist und zugänglich ist.
  2. Der Inhalt der Datei $JAVA_HOME/jre/lib/jaxp.properties, wenn es existiert.
  3. Der Jar Service Provider-Erkennungsmechanismus, der in der Jar-Dateispezifikation angegeben ist. Eine JAR-Datei kann eine Ressource (d. H. Eine eingebettete Datei) wie META-INF/services/javax.xml.parsers.DocumentBuilderFactory enthalten, die den Namen der zu instanziierenden konkreten Klasse enthält.
  4. Die Standardimplementierung der Fallback-Plattform.

dieser Komplexität Hinzufügen jeder einzelne JAXP Fabrik kann eine unabhängige Implementierung angegeben haben. Es ist üblich, eine Parserimplementierung und eine andere XSLT-Implementierung zu verwenden, aber die Granularität des obigen Auswahlmechanismus ermöglicht es Ihnen, noch mehr zu mischen und zu vergleichen.

Der folgende Code wird Ausgangsinformation über die vier Haupt JAXP Fabriken:

private static void OutputJaxpImplementationInfo() { 
    System.out.println(getJaxpImplementationInfo("DocumentBuilderFactory", DocumentBuilderFactory.newInstance().getClass())); 
    System.out.println(getJaxpImplementationInfo("XPathFactory", XPathFactory.newInstance().getClass())); 
    System.out.println(getJaxpImplementationInfo("TransformerFactory", TransformerFactory.newInstance().getClass())); 
    System.out.println(getJaxpImplementationInfo("SAXParserFactory", SAXParserFactory.newInstance().getClass())); 
} 

private static String getJaxpImplementationInfo(String componentName, Class componentClass) { 
    CodeSource source = componentClass.getProtectionDomain().getCodeSource(); 
    return MessageFormat.format(
      "{0} implementation: {1} loaded from: {2}", 
      componentName, 
      componentClass.getName(), 
      source == null ? "Java Runtime" : source.getLocation()); 
} 

Die folgende Beispielausgabe veranschaulicht eine Mix-and-Match von drei verschiedenen JAXP Implementierungen (Built-in Xerces und externe JAR-Dateien für Xerces 2.8 und Xalan) arbeiten zusammen:

DocumentBuilderFactory implementation: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl loaded from: file:/C:/Projects/Scratch/lib/xerces-2.8.0.jar 
XPathFactory implementation: com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl loaded from: Java Runtime 
TransformerFactory implementation: org.apache.xalan.processor.TransformerFactoryImpl loaded from: file:/C:/Projects/Scratch/lib/xalan.jar 
SAXParserFactory implementation: org.apache.xerces.jaxp.SAXParserFactoryImpl loaded from: file:/C:/Projects/Scratch/lib/xerces-2.8.0.jar 
1

Es hängt davon ab, aber im Allgemeinen nicht.

DocumentBuilderFactory.newInstance() wird entweder die Umsetzung des DocumentBuilderFactory zurück, die in der Systemeigenschaft „javax.xml.parsers.DocumentBuilderFactory“ oder die JRE-Standard Fabrik, wenn die Systemeigenschaft nicht festgelegt konfiguriert ist. Die Standardfactory ist höchstwahrscheinlich in der Implementierung der newInstance-Methode fest codiert und ansonsten nicht zugänglich.

Wenn die Systemeigenschaft festgelegt ist, können Sie mindestens die getResource-Methode für den relevanten Klassenlader verwenden, um die URL abzurufen, von der der Klassenlader die entsprechende Klassendatei lädt. Wenn es aus einer JAR-Datei stammt, sollten Sie in der Lage sein, den Dateinamen (oder die Quell-URL) aus der jar: URL zu extrahieren. Detaillierte Paketinformationen sollten auch verfügbar sein, wenn Sie die Metadaten-Dateien aus dem Klassenpfad manuell lesen können.

Wenn die Systemeigenschaft nicht festgelegt ist, bin ich ziemlich sicher, dass Sie keine Möglichkeit haben, die gesuchten Informationen zu erhalten, ohne tatsächlich eine neue Fabrik zu erstellen, wie Sie es bereits tun.

1

Es gibt eine andere Lage ist, die vor der „Ausweich Plattform defa gesucht ult Implementierung“und das ist das java.endorsed.dirs Verzeichnis wie in den Java Endorsed Standards Override Mechanism dokumentiert

Die Standards Befürworteten Aufhebungsmechanismus ein Mittel bereitstellt, wobei spätere Versionen von Klassen und Schnittstellen, die Standards oder Standalone-Technologien zu implementieren ausgestellt haben, können in die Java-Plattform integriert werden.

+0

Welche BTW seit 8u40 veraltet ist, können Sie überprüfen, ob es noch mit '-XX verwendet wird: + CheckEndorsedAndExtDirs'. – eckes

2

es ist einfach, Sie setzen nur

System.setProperty("jaxp.debug", "1"); 

die Strecke wird Ihnen sagen, whick impl und whick Weise jaxp Einsatz.