详细错误:
Caused by: java.lang.UnsupportedOperationException: This parser does not support specification "null" version "null" at javax.xml.parsers.SAXParserFactory.setSchema(SAXParserFactory.java:394) at net.loomchild.segment.srx.io.Srx2SaxParser.<init>(Srx2SaxParser.java:181) at org.languagetool.tokenizers.SrxTools.createSrxDocument(SrxTools.java:52) at org.languagetool.tokenizers.SRXSentenceTokenizer.<init>(SRXSentenceTokenizer.java:53) at org.languagetool.tokenizers.SimpleSentenceTokenizer.<init>(SimpleSentenceTokenizer.java:38) at org.languagetool.Language.<clinit>(Language.java:66) ... 47 more
分析如下:
查了一下,说是跟xerces.jar有关。吾搜索了一下工程,并无此文件。
单独运行LanguageToolTest是对的。
整合到泰山OFFICE就错误了。
那么就是泰山OFFICE的某个包冲突了?吾随后把包复制到LanguageToolTest进行排查。一次5个,几次就定位到了。是一个pull-parser-2.jar导致的。将此文件删除,功能正常。
这事不能就这么结束了。为什么加个包就错了呢?于是通过源码跟踪,发现不同情形下,产生的SAXParserFactory不一样(这也是理所当然的):
错误 org.gjt.xpp.jaxp11.SAXParserFactoryImpl@2328c243 正确 com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl@6659c656 {http://xml.org/sax/features/namespaces=true, http://xml.org/sax/features/validation=false} true com.sun.org.apache.xerces.internal.jaxp.validation.SimpleXMLSchema@6d5380c2 false
产生SAXParserFactory的代码是:
public Srx2SaxParser(Map<String, Object> parameterMap) { factory = SAXParserFactory.newInstance(); } public static SAXParserFactory newInstance() { return FactoryFinder.find( /* The default property name according to the JAXP spec */ SAXParserFactory.class, /* The fallback implementation class name */ "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); } static <T> T find(Class<T> type, String fallbackClassName) throws FactoryConfigurationError { T provider = findServiceProvider(type); if (provider != null) { return provider; } }
到了这里其实就明白了:优先搜索jar包中是否有SAXParserFactory的类,如果有就使用;否则使用默认的。
原因找到了。怎么解决呢?首先修改JDK肯定不行。所以:
办法一:去掉有问题的包。这个想法是好的,现实则有可能实现不了。
办法二:在相关代码中直接指定工厂。具体代码:
SAXParserFactory factory = SAXParserFactory.newInstance(); try { Class<?> clazz = Class.forName("com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); factory = (SAXParserFactory)clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); }
编译相关源码参考