出处
http://topic.csdn.net/t/20050425/20/3965996.html#
首先感谢 ruby_cn(__ http://www.ruby-cn.org/ __)的blog!
按你说的,我删除了项目中和xml相关的所有包,一切如故。我干脆删了所有的包,除了jre和j2ee,还是如故。我将 DocumentBuilderFactory对象打印出:System.out.println(factory);令人惊讶的结果出现了:org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@1ad086a。我本来也猜测一定是某个第三方的包的类继承了javax.xml.parsers.DocumentBuilderFactory,发现 javax.xml.parsers.DocumentBuilderFactory是一个抽象类,所以的确很有可能,因为抽象类是不能产生对象的。但是也留下一个疑问,程序里并没有产生继承了javax.xml.parsers.DocumentBuilderFactory的类的对象,运行时怎么会自动产生它的子类对象。难道是sevlet容器干的好事?因为抽象类不能产生对象,自动产生继承这个抽象类的对象?类似于EJB容器产生实现home、 remote接口的对象?可是现在我把第三方的包全部删除了,怎么还会输出“apache”这个字眼?这时回想起用main方法不是一切正常的吗?于是跑了一下main,又是令人惊讶的结果:org.apache.crimson.jaxp.DocumentBuilderFactoryImpl@15601ea还是“apache”的实现,但是不同的类,这个类能完好的工作。不用说,一应定是jre或j2ee里有apache的东西。结果发现在jre/lib/rt.jar里有相当多的 apache的包。这个类也在这里。我才刚刚知道原来jre里不全是sun的东西。现在的问题是为什么到了sevlet就会产生 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl的对象。我找 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl类,找了很久发现他在xercesImpl包里。这个包在jboss-4.0.1sp1\lib\endorsed目录下。我把xercesImpl包倒入了那个工具类所在的项目。运行main方法,果然,输出了org.apache.xerces.jaxp.DocumentBuilderFactoryImpl。看来很清楚了,和sevlet容器没关系,只要这两个类被包含在同一个项目里,就会优先产生 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl对象。这是怎么回事呢,我猜想一定在 DocumentBuilderFactory的产生对象的方法有个选择逻辑。这时想到jdk是有源代码的,哈哈,太好了!察看 DocumentBuilderFactoryImpl的newInstance()方法:
return (DocumentBuilderFactory) FactoryFinder.find(
/* The default property name according to the JAXP spec */
"javax.xml.parsers.DocumentBuilderFactory",
/* The fallback implementation class name */
"org.apache.crimson.jaxp.DocumentBuilderFactoryImpl");
他调用了FactoryFinder.find()方法。注意在这里已经看到了"org.apache.crimson.jaxp.DocumentBuilderFactoryImpl"是的,字面意思这是作为一个后备的选择,也就是找不到其他实现了javax.xml.parsers.DocumentBuilderFactory的类,那么就返回 org.apache.crimson.jaxp.DocumentBuilderFactoryImpl的对象。赶紧去看 FactoryFinder.find()方法:三段注释揭露了一切:
// Use the system property first
// try to read from $java.home/lib/jaxp.properties
// try to find services in CLASSPATH
最后都找不到当然是返回后备的org.apache.crimson.jaxp.DocumentBuilderFactoryImpl啦。
String serviceId = "META-INF/services/" + factoryId;
打开xercesImpl包看看,果然有\META-INF\services目录。里面果然有个 javax.xml.parsers.DocumentBuilderFactory文件。打开一看文件内容果然是 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
。看来疑团都揭开啦。但是还有一点sevlet运行的classpath怎么会有endorsed\。打开run.bat看见:"%JAVA%" %JAVA_OPTS% "-Djava.endorsed.dirs=%JBOSS_ENDORSED_DIRS%" -classpath "%JBOSS_CLASSPATH%" org.jboss.Main % 看来endorsed是作为了一个java参数。好了,一切都明白了。现在要怎么解决呢。删除xercesImpl包是一定可以的但是关于 endorsed我也不懂,好像websvice要用到。关于endorsed:http://java.sun.com/j2se/1.4.2 /docs/guide/standards/ 所以我不敢删。想到的办法只有System.setProperty( "javax.xml.parsers.DocumentBuilderFactory","org.apache.crimson.jaxp.DocumentBuilderFactoryImpl" );因为// Use the system property first。好了,用完以后赶快System.setProperty( "javax.xml.parsers.DocumentBuilderFactory","org.apache.xerces.jaxp.DocumentBuilderFactoryImpl" );因为不知道jboss的那些类会用到org.apache.xerces.jaxp.DocumentBuilderFactoryImpl,所以还是要恢复过来的。好了,问题虽然解决了,但是感受到了不优雅的java。
分享到:
相关推荐
XML用于保存及交换数据,与读取配置文件的类在同一包,或在WEB-INF(或其子目录下),// 读取配置文件获得一个输入流 InputStream is = Demo1.class....Document document = documentBuilder.parse(is);
DocumentBuilder builder; try { builder = factory.newDocumentBuilder(); Document doc; try { doc = builder.parse(new File("C:\\fbw\\2014_15_I\\getDetailInfoByTrainCode.xml")); //经过...
C# 设置字体.docC# 设置字体.docC# 设置字体.docC# 设置字体.docC# 设置字体.docC# 设置字体.doc
使用aspose库操作office
Documentbuilder重新计算公式 使用ONLYOFFICE DocumentBuilder检查公式重新计算的小项目 如何使用 安装您要测试的DocumentBuilder版本 安装ruby 跑rake 结果将输出到控制台并保存到result.log
Document doc = dombuilder.parse(is); // 得到XML文档的根节点 Element root = doc.getDocumentElement(); // 得到节点的子节点 NodeList books = root.getChildNodes(); if (books != null) { // 轮循子...
static Connection conn=null; static String sql; public static void main(String[] args) { try { //链接数据库,取得数据 //Class.forName("oracle.jdbc.driver.OracleDriver");//oracle数据库 Class.forName(...
Aspose.Words 转图片后打印模糊 解决思路 :附件包含 word转图片方法源码 以及Aspose.Words dll
java的 private static void addSex() throws Exception{ ... Document document = buider.parse("src/person.xml"); NodeList list = document.getElementsByTagName("p1"); Node p1 = list.item(0);
代码如下所示: 代码如下: //Open document and create Documentbuilder Aspose.Words.Document doc = new Aspose.Words.Document(“demo.doc”); DocumentBuilder builder = new DocumentBuilder(doc); //Set ...
public static Document parse( String xmlFile ) throws Exception { // 绑定XML文件,建造DOM树 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf....
// 常见DOM解析器的工厂实例 DocumentBuilderFactory factory = DocumentBuilderFactory.new... Document doc = db.parse(file); // 获得需要的节点 NodeList movies = doc.getElementsByTagName("Movie");
往xml中更新节点的实例代码 /* System.out.println("2323");...Document parse = docbuilder .parse(new File("src/ProdQuery.xml")); // Element createElement2 = parse.createElement(""); Ele
Document doc = builder.parse(inputSource); return registerBeanDefinitions(doc, resource); 这个方法的目的一目了然,就是为了将资源解释成为Document对象,然后调用registerBeanDefinitions方法,这里...
Document Builder
&2.DTD(Document Type Difinition DTD文档是用于规定XML文档的结构。只有结构符合所引用的DTD文件的XML文件才能称之为有效的XML文件。 DTD(文档类型定义) !DOCTYPE 定义DTD文件名 !ELEMENT 定义元素中可用的数据...
return builder.parse(is); } finally { is.close(); } } /** * 通过xpath表达式解析某个xml节点。 * * @param obj * 要被解析的xml节点对象。 * @param xPath * xpath表达式。 * @...
Java调用XML的方法,使用Document方法,采用DocumentBuilder得到 DOM 解析器的工厂实例,然后从 DOM 工厂获得 DOM 解析器,把要解析的 XML 文档转化为输入流,以便 DOM 解析器解析它。
Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); // Add chart with default data. You can specify different chart types and sizes. Shape shape = builder.InsertChart...
Dom方式创建XML,应用了标准xml构造器 javax.xml.parsers.DocumentBuilder 来创建 XML 文档,需要导入以下内容 javax.xml.parsers javax.xml.parsers.DocumentBuilder javax.xml.parsers.DocumentBuilderFactory ...