JDK-6656846 : JNLP 6.0 DTD is invalid
  • Type: Bug
  • Component: deploy
  • Sub-Component: webstart
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-01-30
  • Updated: 2011-02-16
  • Resolved: 2008-10-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u10 b33Fixed 7Fixed
Description
FULL PRODUCT VERSION :
C:\Documents and Settings\Administrator>java -version
java version "1.6.0_10-ea"
Java(TM) SE Runtime Environment (build 1.6.0_10-ea-b08)
Java HotSpot(TM) Client VM (build 1.6.0_10-ea-b08, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
'multiple OSes'.  This is not relevant to the client system, but a document on Sun's site.

A DESCRIPTION OF THE PROBLEM :
The JNLP 6.0 DTD used for validating the launch files of webstart (JWS) applications is itself invalid!

  Bug 6421585*, ('closed, fixed' now) mentioned errors in both the 1.5 and 1.6 DTDs.

* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6421585

The 1.5 DTD seems OK, but the 1.6 DTD is still invalid.

Would it be possible to?
a) Correct the invalid 1.6 DTD, as well as..
b) Add a Validation step to the upload process of the DTD(s)

The code provided, checks DTDs for validity.  The third (valid, JNLP 6.0) DTD is at my site, with corrections thanks to Piotr Kobzda, who also provided the validation code.

A translation of that into XSD (with further tightening of checking) is available in http://www.physci.org/JNLP-6.0.xsd.  Though note that after carefully trawling through the Spec., I have concluded that the memorySizeType can be widened again to include the upper case M & K size multipliers.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the supplied code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Mon Jan 14 09:26:41 ACT 2008
validating http://java.sun.com/dtd/JNLP-1.5.dtd...
valid
validating http://java.sun.com/dtd/JNLP-6.0.dtd...
valid
validating http://www.physci.org/JNLP-6.0.dtd...
valid
ACTUAL -
Mon Jan 14 09:26:41 ACT 2008
validating http://java.sun.com/dtd/JNLP-1.5.dtd...
valid
validating http://java.sun.com/dtd/JNLP-6.0.dtd...
FATAL ERROR: (domain=http://www.w3.org/TR/1998/REC-xml-19980210,key=MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL)
:http://java.sun.com/dtd/JNLP-6.0.dtd:http://java.sun.com/dtd/JNLP-6.0.dtd:http:
//java.sun.com/dtd/JNLP-6.0.dtd:204:17:5090:White space is required after the element type "update" in the element type declaration.
:http://java.sun.com/dtd/JNLP-6.0.dtd:http://java.sun.com/dtd/JNLP-6.0.dtd:http:
//java.sun.com/dtd/JNLP-6.0.dtd:204:17:5090:White space is required after the element type "update" in the element type declaration.
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:365)
        at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1411)
        at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanElementDecl(XMLDTDScannerImpl.java:864)
        at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:1980)
        at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDExternalSubset(XMLDTDScannerImpl.java:320)
        at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader.loadGrammar(XMLDTDLoader.java:407)
        at ValidateDTD.isDTDValid(ValidateDTD.java:39)
        at ValidateDTD.main(ValidateDTD.java:22)
invalid
validating http://www.physci.org/JNLP-6.0.dtd...
valid

ERROR MESSAGES/STACK TRACES THAT OCCUR :
(Validation message)
MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.URL;

import com.sun.org.apache.xerces.internal.impl.dtd.XML11DTDProcessor;
import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;

public class ValidateDTD {

    public static void main(String[] args) throws Exception {
		System.out.println(new java.util.Date());
        for(String dtdId : new String[] {
                "http://java.sun.com/dtd/JNLP-1.5.dtd",
                "http://java.sun.com/dtd/JNLP-6.0.dtd",
                "http://www.physci.org/JNLP-6.0.dtd"
            }) {
            URL dtd = new URL(dtdId);
            System.out.println("validating " + dtd + "...");
            boolean valid = isDTDValid(null, dtd.toURI().toString());
            System.out.println(valid ? "valid" : "invalid");
        }
    }

    public static boolean isDTDValid(String publicId, String systemId)
        throws IOException, NoClassDefFoundError {
        XMLDTDLoader dtdLoader
        //    = new XMLDTDLoader();
            = new XML11DTDProcessor();  // use commented out before for DTD 1.0

        Handler eh = new Handler();
        dtdLoader.setErrorHandler(eh);

        XMLInputSource in = new XMLInputSource(publicId, systemId, null);

        try {
            dtdLoader.loadGrammar(in);
        } catch(XNIException ne) {
            ne.printStackTrace();
            return false;
        }

        return !eh.handledAnyError() && !eh.handledAnyFatalError();
    }

    static class Handler implements XMLErrorHandler {
        int errorCount;
        int fatalErrorCount;
        int warningCount;

        public boolean handledAnyError() {
            return errorCount != 0;
        }

        public boolean handledAnyFatalError() {
            return fatalErrorCount != 0;
        }

        public boolean handledAnyWarning() {
            return warningCount != 0;
        }

        public void error(String domain, String key, XMLParseException
exception) throws XNIException {
            ++errorCount;
            System.err.println("ERROR: (domain=" + domain + ", key=" + key + ")");
            System.err.println(exception);
        }

        public void fatalError(String domain, String key,
XMLParseException exception) throws XNIException {
            ++fatalErrorCount;
            System.err.println("FATAL ERROR: (domain=" + domain + ",key=" + key + ")");
            System.err.println(exception);
            throw exception;
        }

        public void warning(String domain, String key,
XMLParseException exception) throws XNIException {
            ++warningCount;
            System.err.println("WARNING: (domain=" + domain + ", key="
+ key + ")");
            System.err.println(exception);
        }
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Validate JNLP files against http://www.physci.org/JNLP-6.0.xsd or http://www.physci.org/JNLP-6.0.dtd instead.

Comments
EVALUATION I marked this as fixed and verified in 6u10 fcs, even though this fix is not "in" the release, but instead these dtds are posted to http://java.sun.com/dtds. I have validated the currently posted 1.5.0 and 6.0 DTD's using the given tool - and will use this to validate new DTD versions before pushing to java.sun.com.
07-10-2008