调用解析 xml 数据的时候提示 ClassNotFoundException

发现问题:调用解析 xml 数据的时候提示 ClassNotFoundException

ClassNotFoundException : SAXParserFactoryImpl

解决方案1: (摘录文章

 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6350682 

A DESCRIPTION OF THE PROBLEM :
SAXParserFactory.newInstance() throws FactoryConfigurationError if in current contextClassLoader=null. Version 1.5_04, 1.5_05 works ok. As result of this change of the behaviour, maven tool can't work under mustang.

问题的解决:

引起问题的原因是eclipse找到的虚拟机是1.3.1_01版本的,而此版本的JVM根本不自带javax.xml.parsers.SAXParserFactory这样一个类
我猜测根目录下的eclipse.exe与%Java_Home%/bin/java.exe 是同样的功能,就是定位到底运行哪一个JVM
根据<Java深度历险>上所说java.exe 按照如下顺序搜索JVM
1 自己当前目录下有没有JRE(原书说这种说法不够精确)
2 父目录下有没有JRE
3 查询注册表(HKey_Local_Machine/Software/JavaSoft/Java Runtime Environmet/)
所以我把整个eclipse目录下的文件复制到我的%Java_Home%/ 目录下面,按照上面的说法,它会先去寻找%Java_Home%/JRE 找到后就直接执行此目录下的虚拟机,而此虚拟机是1.5版的,这样eclipse就可以正常启动了.

疑惑

原来Eclipse找到的JVM1.3.1_01是我装好操作系统后装的第一个JRE,位于C:/Program Files/IBM/JRE/1.1/bin 而这个JRE 根本没有在注册表里面注册    按照<Java深度历险>书上的内容它是不可能被找到的.   所以eclipse.exe启动时选择JRE 的机制还需要高人来指点.

摘录bug文章

ERROR MESSAGES/STACK TRACES THAT OCCUR :
错误信息/栈 追踪发生
C:\>java -showversion -Djaxp.debug=1 JAXPTest
java version "1.6.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-rc-b60)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b60, mixed mode, sharing)

JAXP: find factoryId =javax.xml.parsers.SAXParserFactory
JAXP: found jar resource=META-INF/services/javax.xml.parsers.SAXParserFactory using ClassLoader: nul
l
JAXP: found in resource, value=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
Exception in thread "main" javax.xml.parsers.FactoryConfigurationError: Provider com.sun.org.apache.
xerces.internal.jaxp.SAXParserFactoryImpl could not be instantiated: java.lang.NullPointerException
        at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)
        at JAXPTest.main(JAXPTest.java:8)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.xml.parsers.SAXParserFactory;

public class JAXPTest
{
 public static void main(String[] args) throws Exception
 {
  Thread.currentThread().setContextClassLoader(null);
  SAXParserFactory.newInstance();
 }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Don't set context class loader to null.

Release Regression From : 5.0u5
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

 

方案2:(摘录文章

出现这个报错主要有3种可能

1、项目中的配置文件配置错误,配置文件错误有时会在报错中提示有时不会,没有具体提示的时候可以去最近更改过的配置文件中查找

2、web.xml 中启动任务中的报错,这个可以根据报错提示去相应的启动任务中查找

3、tomcat非正常关闭导致,通过重启tomcat服务可以解决

方案3:(摘录文章

工作中,使用JAVA的JAXP读取解析XML文件中,就碰到了一件奇件的事。在Web工程中,调试发现JAXP实际使用的是Xerces解析器, 
可是,当将工程中的一个小Swing工具,与Web使用一样的jar包,打成一个可执行的jar包时,调试却发现JAXP实际使用的是Crimson 
解析器,还会发现解析XML文件时出现错误,经过分析,发现Crimson解析器是Sun公司开发的(实际使用发现Crimson没有Xerces解析器稳定), 
打包在JAVA_HOME/lib/dt.jar包中,这个dt.jar被设置在环境变量CLASSPATH中了,当运行可执行的jar包是,JAXP会使用CLASSPATH的解析器, 
在Web工程中的War包则不会。 
通过阅读JDK源码javax.xml.parsers.FactoryFinder,javax.xml.parsers.SAXParserFactory以及DocumentBuilderFactory发现JDK按照如下顺序:

1 系统属性javax.xml.parsers.DocumentBuilderFactory或javax.xml.parsers.SAXParserFactory

2 在jdk-dir/lib/jaxp.properties中设定的javax.xml.parsers.DocumentBuilderFactory或javax.xml.parsers.SAXParserFactory属性

3 运行时jar包中META-INF/services/javax.xml.parsers.DocumentBuilderFactory或javax.xml.parsers.SAXParserFactory文件中设定的值

4. 如果上面的解析器都没有找到,则使用Crimson。如果还没有。。。。。。那报ClassNotFound异常了。通过JAXP查找解析器的顺序,我们可以使用下面方式来决定,我们使用的实际解析器,
1 在程序中写死实际的解析器

    javax.xml.parsers.DocumentBuilderFactory factory= new org.apache.crimson.jaxp.DocumentBuilderFactoryImpl();
2 使用JAXP的 DocumentBuilderFactory 工厂类,如

    javax.xml.parsers.DocumentBuilderFactory factory= javax.xml.parsers.DocumentBuilderFactory.newInstance();
    再通过下面的方式来指定实际的解析器类
    方法一: 
    在运行java时,通过设置(java命令) java -D javax.xml.parsers.DocumentBuilderFactory=new org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
    方法二: 
    在程序中调用

System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.crimson.jaxp.DocumentBuilderFactoryImpl");
    来设定实际的XML解析器.
    方法三: 

      编写一个 jaxp.properties 文件,在其中加入如下内容
javax.xml.parsers.DocumentBuilderFactory=org.apache.crimson.jaxp.DocumentBuilderFactoryImpl

再将此文件放入JAVA_HOME/lib/  (目录)下
方法四:在打jar包下,在目录 META-INF/ 下新建一个services目录,在此目录新建一个文件名为javax.xml.parsers.DocumentBuilderFactory 的文件
文件内容写上实际使用的解析器类,如写 org.apache.crimson.jaxp.DocumentBuilderFactoryImpl 
通过,上面,我们就可以对 JAXP 有一个比较深的了解。
其实, JAVA 中有许多这种思想的做法,这种思想,指的是什么的,就是平台无关性,发展到不依赖于具体的实现。
如我们熟悉的JNDI,JDBC,JAXP等。

JNDI是抽像各种目录服务操作的类库,目录服务器厂商太多了,如SUN公司的ldapsdk,还有novell公司等等;

JDBC是抽像各种数据库操作的类库,数据库厂商也太多了,如ORACLE,SQLSERVER,MYSQL,INFORMIX等等;

JAXP就是抽像各种XML解析器和转换器产品的类库,XML解析器和转换器产品够多的了。

访问AIX系统中部署在OC4J中的web 模块的页面时遇到这个错误:
javax.xml.parsers.FactoryConfigurationError: Provider null could not be instantiated: 
java.lang.NullPointerException
at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)
at org.apache.commons.digester.Digester.getFactory(Digester.java:478)
at org.apache.commons.digester.Digester.getParser(Digester.java:683)
at org.apache.commons.digester.Digester.getXMLReader(Digester.java:891)
at org.apache.commons.digester.Digester.parse(Digester.java:1591)
at org.apache.struts.action.ActionServlet.initServlet(ActionServlet.java:1433)
at org.apache.struts.action.ActionServlet.init(ActionServlet.java:466)
at javax.servlet.GenericServlet.init(GenericServlet.java:256)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) ].server.http.HttpApplication.loadServlet(HttpApplication.java:2231)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) ].server.http.HttpApplication.findServlet(HttpApplication.java:4617)
……
或者这样的异常:
javax.servlet.jsp.JspException: Can't get definitions factory from context.
at org.apache.struts.taglib.tiles.InsertTag.processDefinitionName(InsertTag.java:583)
at org.apache.struts.taglib.tiles.InsertTag.createTagHandler(InsertTag.java:487)
at org.apache.struts.taglib.tiles.InsertTag.doStartTag(InsertTag.java:451)
at _welcome._jspService(_welcome.java:54)
[SRC:/welcome.jsp:4]

而当在Windows环境下部署时就没有问题。

这里是因为IBM的 AIX系统 使用的是IBM的JDK。而出现这个问题正是因为 IBM和SUN 的 JDK 的差异。

 具体是因为  $JAVA_HOME/jre/lib/jaxp.properties 这个文件。

这个文件以key=value的形式配置和指定实际使用的XML解析器实现类(譬如:javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl)。在 XML解析器 初始化之前,JDK首先会搜索System的properties寻找解析器的配置项,如果没有则会搜索 $JAVA_HOME/jre/lib 路径下的 jaxp.properties 文件,如果还没有,接下来会在classpath上的.jar包中寻找,仍然没有的话就会使用默认的解析器。   实际上这个文件(jaxp.properties)在 SUN的 JDK 中是不存在的。在找不到文件的情况下,最终将使用 默认解析器。在IBM的JDK中存在 jaxp.properties 这个文件。但是这个文件中默认所有的配置项是注释掉的,所以在搜索到此处时,不再继续向下搜索,但是由于读取不到配置项,所以会返回null ,于是出现了上文的第一个错误。第二个异常大概是因为访问使用 tiles框架 的页面时,由于 XML解析器 初始化出错,所以 tiles框架 的配置文件也就读取不了了。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值