Skip to content

Commit 4f918b6

Browse files
committed
Work around version skews with XML libraries
Sometimes (I am looking at you, OME!), obsolete XML components are shipped as part of an OMERO-insight installation, intended to support Java 1.5 which does not have its own XML libraries). When multiple projects do that (I am looking at you, Batik!), the XML components can easily cause trouble when the order of the individual .jar files cannot guarantee that an appropriate xalan/xerces pairings is discovered via the class path. Now, in this time and age, Java 6 is thankfully common enough that we can always fall back to the XML library contained in the JRE. Which is exactly what this workaround is all about. Jan Eglinger was very helpful in diagnosing the issue that he reported in http://fiji.sc/bugzilla/show_bug.cgi?id=749. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 7015070 commit 4f918b6

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

src/main/java/org/scijava/util/XML.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,40 @@ public XML(final Document doc) {
113113
public XML(final String path, final Document doc) {
114114
this.path = path;
115115
this.doc = doc;
116-
xpath = XPathFactory.newInstance().newXPath();
116+
117+
// Protect against class skew: some ImageJ projects find it funny to ship
118+
// outdated xalan, sometimes causing problems due to incompatible
119+
// xalan/xerces combinations.
120+
//
121+
// We work around that by letting the XPathFactory try with the current
122+
// context class loader, and fall back onto its parent until it succeeds
123+
// (because the XPathFactory will ask the context class loader to find the
124+
// configured services, including the
125+
// com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl).
126+
XPath xpath = null;
127+
final Thread thread = Thread.currentThread();
128+
final ClassLoader contextClassLoader = thread.getContextClassLoader();
129+
try {
130+
ClassLoader loader = contextClassLoader;
131+
for (;;) try {
132+
xpath = XPathFactory.newInstance().newXPath();
133+
try {
134+
// make sure that the current xalan/xerces pair can evaluate
135+
// expressions (i.e. *not* throw NoSuchMethodErrors).
136+
xpath.evaluate("//dummy", doc);
137+
} catch (Throwable t) {
138+
throw new Error(t);
139+
}
140+
break;
141+
} catch (Error e) {
142+
loader = loader.getParent();
143+
if (loader == null) throw e;
144+
thread.setContextClassLoader(loader);
145+
}
146+
this.xpath = xpath;
147+
} finally {
148+
thread.setContextClassLoader(contextClassLoader);
149+
}
117150
}
118151

119152
// -- XML methods --

0 commit comments

Comments
 (0)