Re: Bug in DTD catalog resolution

I raised the bug a long time ago... I took me only 3 months to test the 
workaround on Java 5 and 6 ;-)

I checked in the change in the ExtendedCatalogResolver class as it works 
fine in Java 5, Java 6, and fixes the bug I had when using the JAR with 
a Jigsaw server.

Note that apart from saying "the class loader behaves weirdly", I still 
can't explain why the bug appeared in the first place though :-(

Francois.


Sean Owen wrote:
> This whole area has been problematic. I think your change is fine --
> try it out. I'd just say try it on *both Java 5 and Java 6* since they
> apparently work differently regarding file:// URLs, and I've had to
> hack around that in our code and also third party libraries. This is
> what that "file:///" business is about.
> 
> On Wed, Mar 19, 2008 at 12:43 PM, Francois Daoust <fd@w3.org> wrote:
>>  Hi folks,
>>
>>  As it stands, the "in-JAR" DTD catalog works fine when the checker is
>>  run from the command-line, but the checker fails to resolve well-known
>>  DTDs when the JAR is imported in a JSP page (at least using Jigsaw, it
>>  may work with other Web servers)
>>
>>  The problem lies in the ExtendedCatalogResolver class and in particular
>>  in the resolveEntity method. The call to "delegate.resolveEntity" fails
>>  because for some reason the mapping to an "in-JAR" file doesn't work in
>>  that case. It fails to resolve something like "[file path to mobileOK
>>  jar]/dtd/whatever", which should fetch the file in the JAR. I don't know
>>  why, I'm just seeing it doesn't work...
>>
>>  The subsequent lines of codes in the resolveEntity method seem to be
>>  willing to handle a similar case (where the systemId would already be a
>>  local file), but does not cover this one, because the only way to enter
>>  the loop is to have a systemId that already starts with "file://". It
>>  could easily be adapted to handle this more generic case.
>>
>>  My proposed patch for ExtendedCatalogResolver.resolveEntity:
>>
>>  public InputSource resolveEntity(final String publicId, String systemId)
>>  throws IOException {
>>   InputSource source = delegate.resolveEntity(publicId, systemId);
>>   if (source == null) {
>>    if (!systemId.startsWith("file://")) {
>>     systemId = delegate.getCatalog().resolveSystem(systemId);
>>    }
>>    if (systemId != null) {
>>     if (!systemId.startsWith("file:///")) {
>>      systemId = "file:///" + systemId.substring(7);
>>     }
>>     try {
>>      source = new InputSource(new URL(systemId).openStream());
>>     } catch (FileNotFoundException fnfe) {
>>      final String resourceName = getResourceFromAbsoluteFilename(systemId);
>>      final InputStream is = getClass().getResourceAsStream("/" +
>>  resourceName);
>>      source = new InputSource(is);
>>     }
>>     source.setSystemId(systemId);
>>     source.setPublicId(publicId);
>>    }
>>   }
>>   return source;
>>  }
>>
>>
>>  The only changed lines are at the beginning of the inner loop:
>>   if (source == null) {
>>    if (!systemId.startsWith("file://")) {
>>     systemId = delegate.getCatalog().resolveSystem(systemId);
>>    }
>>
>>  instead of:
>>   if (source == null && systemId.startsWith("file://")) {
>>
>>  Note that I'm not crazy about this patch as the case is handled by the
>>  "catch" line, so that means using exceptions as regular code flow... not
>>  really a good practice. Anything better?
>>
>>  Also note that's not related to the failures that occur when the checker
>>  doesn't have a DTD in its catalog, it's really about being able to read
>>  an existing file in the catalog when the JAR is imported in a JSP page.
>>
>>  François.
>>
>>

Received on Monday, 23 June 2008 12:57:41 UTC