Die zum Erstellen des JAXBContext erforderliche Zeit reduzieren
Bei jedem Aufruf einer Web-Service-Anwendung wird der Klassenlader nach potenziellen JAXB-Klassen durchsucht. Wenn der Suchvorgang für Ihre Anwendung sehr lang ist, gibt es bestimmte Vorgehensweisen, um die Zeit, die das System zum Erstellen des JAXBContext für Ihre Anwendung benötigt, zu reduzieren.
- Erstellen der Liste der Pakete, die JAXB-Klassen enthalten können.
Die Liste wird basierend auf dem Inhalt der WSDL und der Annotationen erstellt. Die Zeit, die zum Erstellen der Liste mit Paketen benötigt wird, kann nicht reduziert werden. Es ist jedoch wichtig zu wissen, dass es in bestimmten Ausnahmefällen und besonderen Szenarien vorkommen kann, dass ein Paket in die Paketliste aufgenommen wird, das keine JAXB-Klassen enthält. Im folgenden Beispiel wird eine Tracenachricht gezeigt, die meldet, dass ein Paket aufgenommen wurde, das keine JAXB-Klassen enthält.
Dieser Beispieltrace zeigt die folgende Situation: 12/2/11 6:24:40:548 PST] 0000003e JAXBUtils 1 org.apache.axis2.jaxws.message.databinding.JAXBUtils createJAXBContextValue Package com.company.queryall.v1 does not have any JAXB classes. It is removed from the JAXB context path.
Für jeden einzelnen Fall, in dem diese Nachricht angezeigt wird, müssen Sie eine leere Datei des Typs "jaxb.index" in das Paket aufnehmen, um anzugeben, dass keine JAXB-Klassen vorhanden sind. Andernfalls wird eine zeitaufwändige Suche nach JAXB-Klassen durchgeführt.
- Signatur der aufzurufenden JAXBContext.newInstance() bestimmen. Da JAXBContext.newInstance() entweder mit einer Liste von Paketen oder einer Liste von JAXB-Klassen aufgerufen werden kann, müssen Sie abhängig von Ihren Zielen entscheiden, welche Vorgehensweise verwendet werden soll.
- JAXBContext.newInstance() aufrufen, wodurch das Objekt JAXBContext erstellt wird.
Durch Ausführen der folgenden Aktionen können Sie die Zeit, die zum Erstellen des JAXBContext erforderlich ist, reduzieren:
- Aktivieren Sie den persistenten Cache
der JAXB-Suchergebnisse. Damit der persistente Cache der Suchergebnisse für jedes Paket aktiviert wird, setzen Sie die angepasste
JVM-Eigenschaft "com.ibm.ws.websvcs.getJAXBContext.cacheClassList.persist" auf "true".
Wenn Pakete für einen JAXBContext keine "ObjectFactory" oder keine "jaxb.index"-Datei enthalten, wird für jedes Paket der Klassenlader nach potenziellen JAXB-Klassen durchsucht. Wenn ein großer Klassenlader beteiligt ist, kann diese Suche sehr zeitaufwändig sein. Sie können die angepasste JVM-Eigenschaft "com.ibm.ws.websvcs.getJAXBContext.cacheClassList.persist" verwenden, um die Suchergebnisse für jedes durchsuchte Paket permanent im Cache zu speichern. Später ausgeführte JAXBContext-Anforderungen verwenden die im Cache gespeicherte Klassenliste, anstatt erneut nach diesen Paketen zu suchen.
Bei Aktualisierung oder Deinstallation einer Anwendung wird der Cache entfernt. Zwar führt diese Vorgehensweise nicht so sehr zu einer Leistungsverbesserung als dass sie vielmehr eine Liste mit Paketen bereitstellt, allerdings erfordert sie keinerlei Änderungen an der Anwendung.
Diese Aktion wird als erster Schritt empfohlen, auch dann, wenn Sie die "jaxb.index"-Dateien verwenden möchten.
- Legen Sie eine
"jaxb.index"-Datei für jedes Paket fest, das keine
"ObjectFactory"-Klasse enthält. Durch diese Aktion kann das System die Suche nach
JAXB-Klassen vollständig umgehen. Diese Vorgehensweise erfordert eine Anwendungsmodifikation, die
das Hinzufügen der
"jaxb.index"-Dateien berücksichtigt.
Die Liste der Pakete, die JAXB-Klassen enthalten, kann dann verwendet werden, wenn jedes Paket entweder eine "ObjectFactory"-Klasse oder eine "jaxb.index"-Datei mit den JAXB-Klassen für das Paket enthält. Wenn Sie die Liste der JAXB-Klassen in der Klasse "ObjectFactory" oder in einer "jaxb.index"-Datei angeben, ist eine Suche nach JAXB-Klassen nicht erforderlich.
Wenn Sie eine Paketliste verwenden, kann dies eine größere Leistungsverbesserung zur Folge haben, aber Sie müssen die Dateien "jaxb.index" manuell erstellen und Änderungen an der Anwendung vornehmen. Wenn Sie diese Vorgehensweise verwenden, können Sie in den Debug-Trace-Protokollen nach Nachrichten mit dem Text does not contain an ObjectFactory (enthält keine ObjectFactory) suchen, um festzustellen, wie viele Pakete aktualisiert werden müssen.
Eine "jaxb.index"-Datei kann dann verwendet werden, wenn Sie eine optimale Leistung erzielen möchten und bereit sind, Änderungen an der Anwendung vorzunehmen. Die Klasse "ObjectFactory" wird normalerweise mit den Top-down-Tools (wsimport) erstellt. Alle mit Bottom-up-Tools wsgen entwickelten Pakete enthalten daher wahrscheinlich eine "ObjectFactory"-Klasse. Die Datei "jaxb.index" wird verwendet, um die JAXB-Klassen im Paket anzugeben und die für die Kontexterstellung benötigte Zeit zu verringern. Die Methode JAXBContext.newInstance() akzeptiert "jaxb.index"-Dateien auf dieselbe Art und Weise wie sie die "ObjectFactory"-Klasse akzeptiert.
Wenn Sie eine "jaxb.index"-Datei verwenden, müssen Sie alle Fälle, in denen in der Tracedatei festgestellt wird, dass ein Paket keine "ObjectFactory"-Klasse enthält, auswerten und die geeignete "jaxb.index"-Datei erstellen. Nachdem Sie im Trace nach Nachrichten mit dem Text does not contain an ObjectFactory gesucht haben, in denen die Pakete angegeben sind, für die die Datei "jaxb.index" erforderlich ist, müssen Sie wie folgt vorgehen:- Erstellen Sie eine "jaxb.index-"-Datei mit der Liste der JAXB-Klassen. Wenn das Paket keine JAXB-Klassen enthält, muss eine leere "jaxb.index"-Datei in das Paket aufgenommen werden.
- Führen Sie die Traceoperation erneut aus und stellen Sie sicher, dass keine weiteren Nachrichten mit dem Text does not contain an ObjectFactory im Trace vorhanden sind.
Wenn eine erforderliche JAXB-Klasse fehlt und nicht in der Datei "jaxb.index" enthalten ist, tritt ein Fehler auf. Dieser Fehler zeigt an, dass der JAXBContext die Klasse nicht kennt und dass die Klasse in die Datei jaxb.index aufgenommen werden sollte.
Jedes in einem JAXBContext verwendete Paket muss entweder eine "ObjectFactory"-Klasse oder eine "jaxb.index"-Datei enthalten. Dies bedeutet, dass die Tracedateien geprüft werden müssen und dass alle Fälle, in denen eine "ObjectFactory"-Klasse oder eine "jaxb.index"-Datei fehlt, gelöst werden müssen. Wenn für ein Paket für den JAXBContext ermittelt wird, dass es weder eine "ObjectFactory"-Klasse noch eine "jaxb.index-"-Datei enthält, wird die zeitaufwändige JAXB-Klassensuche ausgeführt. Das Format der Datei "jaxb.index" ist im Oracle-Javadoc für JAXBContext.newInstance() unter http://docs.oracle.com/javaee/5/api/javax/xml/bind/JAXBContext.html dokumentiert.
Hinweis zur Umstellung: Generierte Klassen werden in Version 7.0 auch dann nicht beibehalten, wenn sie mit wsgen erstellt werden. Die Spezifikation "JAX-WS Specification 2.2" erfordert jedoch, dass generierte Klassen beibehalten werden. Daher platziert wsgen die generierten Klassen im Verzeichnis "packagename/jaxws". Aus diesem Grund enthält die Liste der Pakete, die durchsucht werden, jetzt auch das Verzeichnis "packagename/jaxws", das in der EAR-Datei nicht vorhanden ist. Wenn diese Situation vorliegt, erhalten Sie eine ähnliche Fehlernachricht wie die folgende:
Um diesen Fehler zu umgehen, können Sie wie folgt vorgehen:6/21/12 17:07:36:477 CDT] 0000001a JAXBContextTr 1 org.apache.axis2.jaxws.message.databinding.JAXBUtils createJAXBContextValue JAXBContextCreate: Package somepackage.jaxws does not contain an ObjectFactory or package-info class. Searching for JAXB classes
- Erstellen Sie zwei verschiedene EAR-Dateien: eine EAR-Datei ohne die "jaxb.index"-Datei "somepackage.jaxws", die in Version 7.0 verwendet werden kann, und eine EAR-Datei mit der "jaxb.index"-Datei "somepackage.jaxws", die in der aktuellen Version des Produkts verwendet werden kann.
- Wenn Sie für beide Versionen des Produkts eine einzelne EAR-Datei verwenden möchten, fügen Sie die generierten Klassen und die Datei "jaxb.index" der EAR-Datei hinzu. Wenn Sie diese Option verwenden, sollten Sie auch die WSDL mit den generierten Klassen hinzufügen.
- Verwenden Sie anstelle der "jaxb.index"-Dateien den persistenten Cache. In diesem Fall durchsucht JAX-RS weiterhin jedes Paket einmal nach JAXB-Klassen. Die Ergebnisse werden jedoch im Cache gespeichert, so dass keine erneute Suche ausgeführt werden muss, solange die Anwendung nicht aktualisiert wird.
- Wenn die Ausführung von
JAXBContext.newInstance() lange dauert, können Sie die angepasste JVM-Eigenschaft
"jaxws.JAXBContext.permStoreCostThresholdMsec" verwenden, um
einen festen Referenzcache mit
JAXBContext-Objekten zu erstellen, der während der Garbage-Collection nicht verloren geht.
Es gibt keine Möglichkeiten, den tatsächlichen Prozess der JAXBContext-Instanzerstellung zu ändern oder zu verbessern. Die Zeit, die benötigt wird, um eine Instanz des Kontextes zu erstellen, wird von vielen Faktoren beeinflusst, beispielsweise von der Anzahl der JAXB-Klassen, der Anzahl Pakete und der Größe des Klassenpfads. Der erstellte JAXBContext wird in einem variablen Referenzcache im Speicher beibehalten. Folglich kann ein JAXBContext bei der Garbage-Collection gelöscht werden, wenn zu wenig Speicher verfügbar ist. Die nächste Anforderung, die den gelöschten JAXBContext benötigt, muss den JAXBContext dann erneut erstellen. Dieser Prozess der erneuten Erstellung ist für den JAXBContext in der Regel nicht von großer Bedeutung. Es gibt aber Ausnahmen, bei denen der Schritt newInstance() selbst eine erhebliche Menge Zeit benötigt.
Wenn der JAXBContext für eine Anwendung eine lange newInstance()-Erstellungszeit hat, können Sie die folgenden angepassten JVM-Eigenschaften verwenden, um den JAXBContext in einem Cache zu speichern, der bis zum Neustart der JVM oder der Anwendung bestehen bleibt.
- jaxws.JAXBContext.permStoreCostThresholdMsec
- Setzen Sie diese Eigenschaft auf einen Wert ungleich null in Millisekunden. Kontexte, deren Erstellung länger als die angegebene Zeit dauert, werden im Cache gespeichert. Empfohlen wird ein Wert ab 5000. Der Standardwert ist 0. Wenn diese Eigenschaft auf 0 gesetzt ist, wird der Cache nicht verwendet.
- jaxws.JAXBContext.permStoreMaxSize
- Setzen Sie diese Eigenschaft auf die maximale Anzahl Einträge, die im Cache gespeichert werden sollen. Der Standardwert ist 32. Wenn der Cache voll ist, wird der JAXBContext, der am schnellsten erstellt werden kann, aus dem Cache entfernt, um für einen JAXBContext mit längerer Erstellungszeit Platz zu machen.
- jaxws.JAXBContext.permStoreStaleThresholdHours
- Legen Sie für diese Eigenschaft die Zeit in Stunden fest, während der Einträge im Cache gespeichert bleiben sollen. Cacheeinträge, auf die während der angegebenen Anzahl von Stunden nicht zugegriffen wurde, werden entfernt, bevor neue Einträge im Cache gespeichert werden. Der Standardwert ist 24 Stunden.