0

私の単純な Web サービスは XML ドキュメントの Zip ファイルを受け取り、XSD スキーマ ファイルを使用して XML を検証しようとしています。以下はコードスニペットです

        Schema schema = BlahSchemaFactory.newSchema("Blah.xsd");
        Validator validator = schema.newValidator();
        BlahErrorHandler eh = new BlahErrorHandler();
        validator.setErrorHandler(eh);

        ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipFileContentAsBytes));
        zis.getNextEntry(); 

        Source xmlSource = new StreamSource(zis);
        validator.validate(xmlSource);

BlahSchemaFactoryはシングルトンであり、渡された XSD ファイルごとに 1 回だけスキーマ オブジェクトを作成するのに役立ちます。ここで、いくつかの HTTP スレッドが上記のコードを通過するときに問題が発生します。これらは、validate() メソッドのコードの奥深くで互いにブロックしています。

以下は、HP 診断ツールから取得したスタック トレースです。

    "blah_thread_77" Id=472 in BLOCKED on lock=org.apache.xerces.impl.xpath.regex.RegularExpression@3c9d97f9
         owned by d1_thread_237 Id=21648
        at org.apache.xerces.impl.xpath.regex.RegularExpression.matches(Unknown Source)
        at org.apache.xerces.impl.xpath.regex.RegularExpression.matches(Unknown Source)
        at org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl.getActualValue(Unknown Source)
        at org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl.validate(Unknown Source)
        at org.apache.xerces.impl.xs.XMLSchemaValidator.processOneAttribute(Unknown Source)
        at org.apache.xerces.impl.xs.XMLSchemaValidator.processAttributes(Unknown Source)
        at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
        at org.apache.xerces.impl.xs.XMLSchemaValidator.emptyElement(Unknown Source)
        at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
        at org.apache.xerces.jaxp.validation.StreamValidatorHelper.validate(Unknown Source)
        at org.apache.xerces.jaxp.validation.ValidatorImpl.validate(Unknown Source)
        at javax.xml.validation.Validator.validate(Validator.java:124)
        at BlahPackage.BlahClass.uploadSaveFileRecord(BlahRecord.java:77)
        at sun.reflect.GeneratedMethodAccessor210.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.jboss.ws.common.invocation.AbstractInvocationHandlerJSE.invoke(AbstractInvocationHandlerJSE.java:111)
        at org.jboss.wsf.stack.cxf.JBossWSInvoker._invokeInternal(JBossWSInvoker.java:181)
        at org.jboss.wsf.stack.cxf.JBossWSInvoker.invoke(JBossWSInvoker.java:127)
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)

質問:スレッドのブロックを回避する方法はありますか? 提案してください !

4

1 に答える 1

0

以下は、XSDスキーマを使用してXMLを検証しようとしたときのスレッドブロッキングの問題を解決するコードスニペットです。必要がある :

  1. スレッドごとに新しいスキーマを作成してください
  2. SchemaFactoryでnewSchemaを呼び出すときは、呼び出しを同期してください(図を参照)。
  3. BlahObject.class.getClassLoader()。getResource(schemaFileOnClassPath)を呼び出す代わりに、ある種のシングルトンを使用してXSDのURLを1回だけ取得します。そうしないと、クラスローダーがリソースを見つけようとしているスレッドブロッキングが発生します(これは識別されました) HP診断ツールを使用)

        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        URL schemaURL = BlahSchemaSingleton.getSchemaURL("Blah.xsd");
        Schema schema = null; 
    
        synchronized(schemaFactory) {
            schema = schemaFactory.newSchema(schemaURL);
        }
    
        Validator validator = schema.newValidator();
        BlahErrorHandler eh = new BlahErrorHandler();
        validator.setErrorHandler(eh);
    
        ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipFileContentAsBytes));
        zis.getNextEntry(); 
    
        Source xmlSource = new StreamSource(zis);
        validator.validate(xmlSource);
    
于 2013-02-03T23:58:50.423 に答える