详细错误:
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.(Srx2SaxParser.java:181)
at org.languagetool.tokenizers.SrxTools.createSrxDocument(SrxTools.java:52)
at org.languagetool.tokenizers.SRXSentenceTokenizer.(SRXSentenceTokenizer.java:53)
at org.languagetool.tokenizers.SimpleSentenceTokenizer.(SimpleSentenceTokenizer.java:38)
at org.languagetool.Language.(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 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 find(Class 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();
}
- 编译相关源码参考
LINUX下载编译:segment.jar/net.loomchild.segment.srx.Srx2SaxParser_柳鲲鹏-CSDN博客