Search code examples
javasecurityrestletxerces

Restlet client on Java 1.7 xml parse error "FEATURE_SECURE_PROCESSING: Cannot set the feature to false when security manager is present."


EDIT : 31/OCT/2014 The fix for this is now available in both Restlet 2.2 and master (future 2.3) branches

Our Netbeans Platform Restlet client app runs okay on Java 1.6 but with 1.7.0_11, I get security runtime errors.

Is there a easy way to prevent this?

WARN org.restlet.log():241 - Unable to unmarshal the XML representation
javax.xml.bind.JAXBException: Unable to create customized SAX source
 - with linked exception:
[javax.xml.parsers.ParserConfigurationException: FEATURE_SECURE_PROCESSING: Cannot set the feature to false when security manager is present.]
            at org.restlet.ext.jaxb.internal.Unmarshaller.unmarshal(Unmarshaller.java:201)
            at org.restlet.ext.jaxb.JaxbRepresentation.getObject(JaxbRepresentation.java:417)
            at org.restlet.ext.jaxb.JaxbConverter.toObject(JaxbConverter.java:172)
            at org.restlet.service.ConverterService.toObject(ConverterService.java:167)
            at org.restlet.resource.Resource.toObject(Resource.java:828)
            at org.restlet.engine.resource.ClientInvocationHandler.invoke(ClientInvocationHandler.java:240)
            <SNIP>
Caused by: javax.xml.parsers.ParserConfigurationException: FEATURE_SECURE_PROCESSING: Cannot set the feature to false when security manager is present.
            at com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:122)
            at org.restlet.ext.jaxb.internal.Unmarshaller.unmarshal(Unmarshaller.java:190)
            ... 23 more

In both java runtimes, my System.getSecurityManager() is a instance of org.netbeans.TopSecurityManager

EDIT 1

After a bit more research into Restlet source as mentioned in answer from Simon Lehmann I see JaxbConverter.java invokes

new JaxbRepresentation<T>(Representation source, Class<T> target).getObject();

Then ...

public JaxbRepresentation(Representation xmlRepresentation, Class<T> type) { ...}

Then ...

public JaxbRepresentation(Representation xmlRepresentation, String contextPath, ValidationEventHandler validationHandler, ClassLoader classLoader) {
    super((xmlRepresentation == null) ? null : xmlRepresentation
            .getMediaType());
    this.classLoader = classLoader;
    this.contextPath = contextPath;
    this.object = null;
    this.validationEventHandler = validationHandler;
    this.xmlRepresentation = xmlRepresentation;
}

In this particular constructor, this.secureProcessing always remains false so later we get errors with Java 7 secure processing feature of the XML parser if there is any security manager present.

Not sure if this is a bug in restlet or if I am doing something wrong ?

EDIT 2 (Simple Java 7 app vs one in full app)

I wrote small restlet client test program on 1.7.0_11 which works ok with our server. I am guessing in my full client app that there is something 'bad' in the classpath ?

In both the small app and the full app I print the factories and it is same in both :

 [exec] DocumentBuilderFactory implementation: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl loaded from: Java Runtime
 [exec] XPathFactory implementation: com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl loaded from: Java Runtime
 [exec] TransformerFactory implementation: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl loaded from: Java Runtime
 [exec] SAXParserFactory implementation: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl loaded from: Java Runtime

I switch on extra JAXP logging via System.setProperty("jaxp.debug", "true"); and see it is different in each :


Small working app

[junit] JAXP: find factoryId =javax.xml.datatype.DatatypeFactory
[junit] JAXP: loaded from fallback value: com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl
[junit] JAXP: created new instance of class com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl using ClassLoader: null

[junit] JAXP: find factoryId =javax.xml.datatype.DatatypeFactory
[junit] JAXP: loaded from fallback value: com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl
[junit] JAXP: created new instance of class com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl using ClassLoader: null
[junit] JAXP: using thread context class loader (sun.misc.Launcher$AppClassLoader@6c5bdfae) for search
[junit] JAXP: Looking up system property 'javax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom'
[junit] JAXP: The property is undefined.
[junit] JAXP: found null in $java.home/jaxp.properties
[junit] JAXP: no META-INF/services/javax.xml.xpath.XPathFactory file was found
[junit] JAXP: attempting to use the platform default W3C DOM XPath lib
[junit] JAXP: createInstance(com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl)
[junit] JAXP: loaded com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl from jar:file:/Library/Java/JavaVirtualMachines/jdk1.7.0_11.jdk/Contents/Home/jre/lib/rt.jar!/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.class
[junit] JAXP: factory 'com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl' was found for http://java.sun.com/jaxp/xpath/dom

[junit] JAXP: find factoryId =javax.xml.transform.TransformerFactory
[junit] JAXP: loaded from fallback value: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
[junit] JAXP: created new instance of class com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl using ClassLoader: null

Full Netbeans app (failing)

 [exec] JAXP: using thread context class loader (SystemClassLoader[420 modules]) for search
 [exec] JAXP: Looking up system property 'javax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom'
 [exec] JAXP: The property is undefined.
 [exec] JAXP: found null in $java.home/jaxp.properties
 [exec] JAXP: no META-INF/services/javax.xml.xpath.XPathFactory file was found
 [exec] JAXP: attempting to use the platform default W3C DOM XPath lib
 [exec] JAXP: createInstance(com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl)
 [exec] JAXP: loaded com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl from jar:file:/Library/Java/JavaVirtualMachines/jdk1.7.0_11.jdk/Contents/Home/jre/lib/rt.jar!/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.class
 [exec] JAXP: factory 'com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl' was found for http://java.sun.com/jaxp/xpath/dom
 [exec] JAXP: find factoryId =javax.xml.transform.TransformerFactory
 [exec] JAXP: found jar resource=META-INF/services/javax.xml.transform.TransformerFactory using ClassLoader: SystemClassLoader[420 modules]
 [exec] JAXP: loaded from fallback value: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
 [exec] JAXP: created new instance of class com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl using ClassLoader: null

Solution

  • I encountered the same problem - exactly - when I upgraded from restlet 2.2m1 running on Java 6 to restlet 2.2m5 running on Java 7.

    The solution I resorted to was to initialize the secureProcessor flag in the JaxbRepresentation constructor you mentioned to true (and rebuild the restlet code). That resolved the problem for me. It is not clear if the lack of initialization of the secureProcessing flag in that constructor is intentional or is an oversight.

    I filed a bug about it: https://github.com/restlet/restlet-framework-java/issues/785