Re: Bug in DTD catalog resolution

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 Wednesday, 19 March 2008 16:57:17 UTC