Hallo zusammen,
ich arbeite derzeit an einem größeren Projekt und stehe grade vor einem Rätsel mit dem XML-Encoder. Hier eine (vereinfachte) Version des Codes (Erklärung gleich danach):
Was soll die obige Methode machen? Ein Object in XML konvertieren, wobei die Klasse, zu der das Objekt gehört, dynamisch per URLClassloader dazu geladen werden muss. Ich gehe also wie folgt vor:
1) URLClassloader mit der Jar-Datei erzeugen
2) Referenz auf den aktuellen ContextClassLoader des Threads rücksichern
3) ContextClassLoader des aktuellen Threads mit dem neuen URLClassLoader überschreiben
4) Konvertierung zu XML durchführen
5) Dem aktuellen Thread wieder den alten ContextClassLoader zuweisen
Dabei ist das zu konvertierende Objekt wirklich von sehr einfacher Natur, im Wesentlichen enthält es nur einige primitive Felder (hauptsächlich Strings). Trotzdem passiert dann bei "encoder.writeObject(javaObject)" (Zeile 19) folgendes:
... wobei sich die letzten 5 Zeilen des Stacktraces noch einige Male wiederholen, das habe ich jetzt nicht alles kopiert ^^'
In Bezug auf den XMLEncoder wurde überhaupt nichts verändert, also keine Methoden überschrieben etc. es handelt sich wirklich um den Standard XMLEncoder, wie er von Java6 bereitgestellt wird.
Meine Frage ist: hat irgendjemand eine Idee, wie hier diese Endlos-Rekursion zustande gekommen sein könnte? Gibt es einige "übliche Verdächtige", die diesen Fehler auslösen könnten? Ich sitze jetzt schon eine ziemlich lange Zeit an dem Problem, hab das Internet nach Lösungen durchsucht und selber einiges ausprobiert, aber ich finde einfach die Ursache des Problems nicht...
Danke im Voraus,
Alan
ich arbeite derzeit an einem größeren Projekt und stehe grade vor einem Rätsel mit dem XML-Encoder. Hier eine (vereinfachte) Version des Codes (Erklärung gleich danach):
Java:
public static String encodeToXML(final Object javaObject) {
// retrieve the jar file containing the neccessary classes
File jarFile = new File(.....);
// create the new class loader including the jar
URL[] loaderURLs = new URL[1];
try {
loaderURLs = new URL[] { jarFile.toURI().toURL() };
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLClassLoader loader = new URLClassLoader(loaderURLs);
// store the current class loader to re-assign it later on
ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
// assign the new class loader to the thread
Thread.currentThread().setContextClassLoader(loader);
// do the conversion to XML
ByteArrayOutputStream bos = new ByteArrayOutputStream();
XMLEncoder encoder = new XMLEncoder(bos);
encoder.writeObject(javaObject);
encoder.close();
String xmlEncoding = bos.toString();
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
// re-assign the former classloader to the thread
Thread.currentThread().setContextClassLoader(currentLoader);
// return the XML
return xmlEncoding;
}
Was soll die obige Methode machen? Ein Object in XML konvertieren, wobei die Klasse, zu der das Objekt gehört, dynamisch per URLClassloader dazu geladen werden muss. Ich gehe also wie folgt vor:
1) URLClassloader mit der Jar-Datei erzeugen
2) Referenz auf den aktuellen ContextClassLoader des Threads rücksichern
3) ContextClassLoader des aktuellen Threads mit dem neuen URLClassLoader überschreiben
4) Konvertierung zu XML durchführen
5) Dem aktuellen Thread wieder den alten ContextClassLoader zuweisen
Dabei ist das zu konvertierende Objekt wirklich von sehr einfacher Natur, im Wesentlichen enthält es nur einige primitive Felder (hauptsächlich Strings). Trotzdem passiert dann bei "encoder.writeObject(javaObject)" (Zeile 19) folgendes:
java.lang.StackOverflowError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.sun.beans.finder.ClassFinder.findClass(ClassFinder.java:63)
at com.sun.beans.finder.ClassFinder.findClass(ClassFinder.java:105)
at com.sun.beans.finder.ClassFinder.resolveClass(ClassFinder.java:165)
at com.sun.beans.finder.ClassFinder.resolveClass(ClassFinder.java:132)
at java.beans.Statement.invokeInternal(Statement.java:183)
at java.beans.Statement.access$000(Statement.java:56)
at java.beans.Statement$2.run(Statement.java:158)
at java.security.AccessController.doPrivileged(Native Method)
at java.beans.Statement.invoke(Statement.java:154)
at java.beans.Expression.getValue(Expression.java:115)
at java.beans.Encoder.getValue(Encoder.java:105)
at java.beans.Encoder.get(Encoder.java:225)
at java.beans.PersistenceDelegate.writeObject(PersistenceDelegate.java:110)
at java.beans.Encoder.writeObject(Encoder.java:74)
at java.beans.XMLEncoder.writeObject(XMLEncoder.java:274)
at java.beans.Encoder.writeExpression(Encoder.java:304)
at java.beans.XMLEncoder.writeExpression(XMLEncoder.java:389)
at java.beans.PersistenceDelegate.writeObject(PersistenceDelegate.java:113)
... wobei sich die letzten 5 Zeilen des Stacktraces noch einige Male wiederholen, das habe ich jetzt nicht alles kopiert ^^'
In Bezug auf den XMLEncoder wurde überhaupt nichts verändert, also keine Methoden überschrieben etc. es handelt sich wirklich um den Standard XMLEncoder, wie er von Java6 bereitgestellt wird.
Meine Frage ist: hat irgendjemand eine Idee, wie hier diese Endlos-Rekursion zustande gekommen sein könnte? Gibt es einige "übliche Verdächtige", die diesen Fehler auslösen könnten? Ich sitze jetzt schon eine ziemlich lange Zeit an dem Problem, hab das Internet nach Lösungen durchsucht und selber einiges ausprobiert, aber ich finde einfach die Ursache des Problems nicht...
Danke im Voraus,
Alan