jboss中调用webservice时报java.lang.RuntimeException: Cannot create a secure XMLInputFactory的异常

来源:互联网 发布:不能用数据上网 编辑:程序博客网 时间:2024/06/07 11:51

需求是这样的:现在写了一个调用webservice的程序,而需要将这个程序部署到jboss5.x服务器上来供前端调用,在本地调用webservice没有问题,但是部署到服务器上就会报这个错误了。

java.lang.RuntimeException: Cannot create a secure XMLInputFactory        at org.apache.cxf.staxutils.StaxUtils.createXMLInputFactory(StaxUtils.java:315)        at org.apache.cxf.staxutils.StaxUtils.getXMLInputFactory(StaxUtils.java:265)        at org.apache.cxf.staxutils.StaxUtils.createXMLStreamReader(StaxUtils.java:1701)        at org.apache.cxf.interceptor.StaxInInterceptor.handleMessage(StaxInInterceptor.java:123)        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)        at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:802)        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1638)        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1527)        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1330)        at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)        at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:638)        at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)        at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)

网上众说纷纭,也不知道该如何解决,看来还是直接看源码吧。

    public static XMLInputFactory createXMLInputFactory(boolean nsAware) {        XMLInputFactory factory = null;        try {            factory = XMLInputFactory.newInstance();        } catch (Throwable t) {            factory = null;        }        if (factory == null || !setRestrictionProperties(factory)) {            try {                factory = createWoodstoxFactory();            } catch (Throwable t) {                //ignore for now            }            if (!setRestrictionProperties(factory)) {                if (allowInsecureParser) {                    LOG.log(Level.WARNING, "INSECURE_PARSER_DETECTED", factory.getClass().getName());                } else {                    throw new RuntimeException("Cannot create a secure XMLInputFactory");                }            }        }        setProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, nsAware);        setProperty(factory, XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);        setProperty(factory, XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);        setProperty(factory, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);        factory.setXMLResolver(new XMLResolver() {            public Object resolveEntity(String publicID, String systemID,                                        String baseURI, String namespace)                throws XMLStreamException {                throw new XMLStreamException("Reading external entities is disabled");            }        });        return factory;    }

从源代码可以看出,抛出异常的原因是allowInsecureParser为false,那我们再看看allowInsecureParser到底是何方神圣。

   static {        int i = getInteger("org.apache.cxf.staxutils.pool-size", 20);        NS_AWARE_INPUT_FACTORY_POOL = new ArrayBlockingQueue<XMLInputFactory>(i);        OUTPUT_FACTORY_POOL = new ArrayBlockingQueue<XMLOutputFactory>(i);        //old names        innerElementCountThreshold = getInteger(INNER_ELEMENT_COUNT_SYSTEM_PROP, innerElementCountThreshold);        innerElementLevelThreshold = getInteger(INNER_ELEMENT_LEVEL_SYSTEM_PROP, innerElementLevelThreshold);        //new names        innerElementCountThreshold = getInteger(MAX_CHILD_ELEMENTS, innerElementCountThreshold);        innerElementLevelThreshold = getInteger(MAX_ELEMENT_DEPTH, innerElementLevelThreshold);        maxAttributeCount = getInteger(MAX_ATTRIBUTE_COUNT, maxAttributeCount);         maxAttributeSize = getInteger(MAX_ATTRIBUTE_SIZE, maxAttributeSize);        maxTextLength = getInteger(MAX_TEXT_LENGTH, maxTextLength);         maxElementCount = getLong(MAX_ELEMENT_COUNT, maxElementCount);        maxXMLCharacters = getLong(MAX_XML_CHARACTERS, maxXMLCharacters);        **String s = SystemPropertyAction.getPropertyOrNull(ALLOW_INSECURE_PARSER);**        if (!StringUtils.isEmpty(s)) {            allowInsecureParser = "1".equals(s) || Boolean.parseBoolean(s);        }        XMLInputFactory xif = null;        try {            xif = createXMLInputFactory(true);            String xifClassName = xif.getClass().getName();            if (!xifClassName.contains("ctc.wstx") && !xifClassName.contains("xml.xlxp")                    && !xifClassName.contains("xml.xlxp2") && !xifClassName.contains("bea.core")) {                xif = null;            }        } catch (Throwable t) {            //ignore, can always drop down to the pooled factories            xif = null;        }        SAFE_INPUT_FACTORY = xif;        XMLOutputFactory xof = null;        try {            xof = XMLOutputFactory.newInstance();            String xofClassName = xof.getClass().getName();            if (!xofClassName.contains("ctc.wstx") && !xofClassName.contains("xml.xlxp")                && !xofClassName.contains("xml.xlxp2") && !xofClassName.contains("bea.core")) {                xof = null;            }        } catch (Throwable t) {            //ignore, can always drop down to the pooled factories        }        SAFE_OUTPUT_FACTORY = xof;      }

####从源代码可以看出,allowInsecureParser是类StaxUtils的一个静态变量,而这个变量的值取决于SystemPropertyAction.getPropertyOrNull(ALLOW_INSECURE_PARSER);
继续往下走,我们可以看看SystemPropertyAction是什么(SystemPropertyAction.java):

public final class SystemPropertyAction implements PrivilegedAction<String> {    private static final Logger LOG = LogUtils.getL7dLogger(SystemPropertyAction.class);    private final String property;    private final String def;    private SystemPropertyAction(String name) {        property = name;        def = null;    }    private SystemPropertyAction(String name, String d) {        property = name;        def = d;    }    /* (non-Javadoc)     * @see java.security.PrivilegedAction#run()     */    public String run() {        if (def != null) {            return System.getProperty(property, def);        }        return System.getProperty(property);    }    public static String getProperty(String name) {        return AccessController.doPrivileged(new SystemPropertyAction(name));    }    public static String getProperty(String name, String def) {        try {            return AccessController.doPrivileged(new SystemPropertyAction(name, def));        } catch (SecurityException ex) {            LOG.log(Level.FINE, "SecurityException raised getting property " + name, ex);            return def;        }    }    /**     * Get the system property via the AccessController, but if a SecurityException is      * raised, just return null;     * @param name     */    public static String getPropertyOrNull(String name) {        try {            return AccessController.doPrivileged(new SystemPropertyAction(name));        } catch (SecurityException ex) {            LOG.log(Level.FINE, "SecurityException raised getting property " + name, ex);            return null;        }    }}

从代码中可以看出,实际上最后返回的值时System.getProperty(ALLOW_INSECURE_PARSER)。而这种方式得到的值需要在JVM Options中添加-D($ALLOW_INSECURE_PARSER)=true,其中ALLOW_INSECURE_PARSER=org.apache.cxf.stax.allowInsecureParser。这个值需要在jboss的run.conf中添加。

0 0
原创粉丝点击