Regressions from gcj 4.2 to 4.3 involving XML
Fri Mar 9 17:23:00 GMT 2007
I've been mystified why Xerces suddenly stopped working with this
release of gcj. I think I've found the root cause that triggered
In sumary: in gcj 4.2 and previous releases, the handling of "core"
URLs was broken. As a result of this, we never found
libgcj, so we used Xerces' DocumentBuilderFactory instead. This
Now, the handling of "core" URLs is fixed, so we do find
libgcj, which is incompatible with Xerces.
The reason Xerces worked for us in the past is this bug. We have
*never* used gnu.xml.dom.DomDocumentBuilderFactory in gcj before now.
In gcj 4.2, getFactoryClassName() returns
"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl" when invoked with
xerces in the classpath, but gcj 4.3 returns
This happens because in gcj 4.3,
"/META-INF/services/javax.xml.parsers.DocumentBuilderFactory" is found
in libgcj.so as a "core" resource, whereas in gcj 4.2
"file:/usr/share/java/xerces-j2.jar!/META-INF/services/javax.xml.parsers.DocumentBuilderFactory" is found as a "jar" resource.
So, why does gcj 4.2 not find
"/META-INF/services/javax.xml.parsers.DocumentBuilderFactory" as a
Because the string passed to _Jv_FindCore is
Note the two slashes: "//"
Why does this happen in gcj 4.2? It's because we do this in
/** get resource with the name "name" in the core url */
Resource getResource(String name)
Core core = Core.find (dir + name);
if (core != null)
return new CoreResource(this, name, core);
where dir is "/" and name is
We don't do this in gcj 4.3: instead we do
* Get a remote resource.
* Returns null if no such resource exists.
public Resource getResource(String name)
URL url = new URL(baseURL, name, cache.get(factory, protocol));
URLConnection connection = url.openConnection();
// Open the connection and check the stream
// just to be sure it exists.
int length = connection.getContentLength();
InputStream stream = connection.getInputStream();
// We can do some extra checking if it is a http request
if (connection instanceof HttpURLConnection)
int response =
if (response / 100 != 2)
if (stream != null)
return new RemoteResource(this, name, url, stream, length);
catch (IOException ioe)
which eventually finds its way down to
// If not connected, then file needs to be opened.
core = Core.create (url.getFile());
so the error of adding another "/" to the start of the filename never
More information about the Java