【问题标题】:JSP - TransformerFactory.newInstance().newTransformer(xsl) returning null?JSP - TransformerFactory.newInstance().newTransformer(xsl) 返回 null?
【发布时间】:2010-11-04 11:45:33
【问题描述】:

java API 保证它永远不会返回 null - 但对我来说,它是!

http://download.oracle.com/javase/6/docs/api/javax/xml/transform/TransformerFactory.html#newTransformer(javax.xml.transform.Source)

相关代码:

xml = new StreamSource(new URL(mondialURL).openStream());
xsl = new StreamSource(new File("/REMOVED/countriesnofilter.xsl"));
result = new StreamResult(new PrintWriter(out));

transformer = TransformerFactory.newInstance().newTransformer(xsl);
transformer.transform(xml, result);

由于 xml、xsl 和 result 是使用 new 制作的,它们 - 必须 - 不包含 null,所以它必须是变成 null 的转换器。为什么会发生这种情况,我该如何解决?

抛出这个:

org.apache.jasper.JasperException:JSP 中的异常:/dca/ass2/a.jsp:46

43:  result = new StreamResult(new PrintWriter(out));
44:  
45:  transformer = TransformerFactory.newInstance().newTransformer(xsl);
46:  transformer.transform(xml, result);
47: 
48: %>
49:  <INPUT TYPE="SUBMIT" VALUE="Get one country">


Stacktrace:
 org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:451)
 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373)
 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
 org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
 sun.reflect.GeneratedMethodAccessor50.invoke(Unknown Source)
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 java.lang.reflect.Method.invoke(Method.java:597)
 org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:244)
 java.security.AccessController.doPrivileged(Native Method)
 javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
 org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:276)
 org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:162)
root cause

java.lang.NullPointerException
 org.apache.jsp.dca.ass2.a_jsp._jspService(a_jsp.java:104)
 org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
 org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
 sun.reflect.GeneratedMethodAccessor50.invoke(Unknown Source)
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 java.lang.reflect.Method.invoke(Method.java:597)
 org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:244)
 java.security.AccessController.doPrivileged(Native Method)
 javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
 org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:276)
 org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:162)

编辑:肯定是变压器以某种方式为空的情况。观看:

org.apache.jasper.JasperException:JSP 中的异常:/dca/ass2/a.jsp:49

46:     
47:     xml.getInputStream();
48:     xsl.getInputStream();
49:     transformer.reset();
50:     
51:     //transformer.transform(xml, result);
52: 

又是一个空指针异常。如果是因为 xml 为空,那么它会在 47 处抛出 NPE。

EDIT2:如果我将 newTransformer(xsl) 更改为 newTransformer() 它可以工作,所以这是 newTransformer(xsl) 的问题。

【问题讨论】:

  • 为什么你确定这个46: transformer.transform(xml, result);行引起的npe?堆栈跟踪中的行号是否与您提供的列表中的行号匹配?
  • org.apache.jasper.JasperException:JSP 中的异常:/dca/ass2/a.jsp:46。 46:transformer.transform(xml,结果);。所以 NPE 是由那条线引起的。
  • 我也有同样的问题:stackoverflow.com/questions/7470263/…。您找到解决方案了吗?

标签: java xml jsp xslt


【解决方案1】:

在向项目添加新的依赖项后,我的一些测试出错了,我遇到了同样的问题。想知道当它的 API 说不可能时,它怎么会返回 null,我再次修改它:

"获取一个新的TransformerFactory实例。这个静态方法创建一个新的工厂实例这个方法使用下面的顺序 确定 TransformerFactory 实现的查找过程 要加载的类:使用 javax.xml.transform.TransformerFactory 系统 财产。 ... [查找顺序] ... 一旦应用程序获得了 引用一个 TransformerFactory 它可以使用工厂来配置 并获取转换器实例。”

所以,我也查看了 TransformerFactory API,它说:

“确定要创建哪个工厂实现的系统属性名为“javax.xml.transform.TransformerFactory”。这个 属性命名 TransformerFactory 抽象的具体子类 班级。如果未定义该属性,则平台默认为 用过。”

正如我所提到的,当我向项目添加一个新依赖项时问题就开始了:另一个处理 XML 文档/签名的项目。我删除了依赖项,运行了测试(由于添加了依赖项而失败)并检索了 TransformerFactory 的特定类。我重新添加了依赖项并再次运行测试:它现在是一个不同的类。所以,正如我猜想的那样,查找过程实例化了一个错误的 TransformerFactory 实现,并在添加的 jar 中找到了它。

我不想修复它添加另一个系统属性,所以我改变了这样的代码:

private static final String TRANSFORMER_FACTORY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";

TransformerFactory factory = TransformerFactory.newInstance(TRANSFORMER_FACTORY_CLASS, null);
//null for default ClassLoader

一切正常。

【讨论】:

  • 您的解决方案帮助我解决了TransformerFactory.newInstance().newTransformer() 导致ClassNotFoundException 的问题。我仍然需要理解为什么,因为那行代码在过去很有魅力。
  • @MaxArt 我很高兴它有帮助。由于相同的解决方案对您有效,因此很可能某些依赖项(也使用 TransformerFactory 的库,但实现不同)已添加到您的项目中,或者您可能只是更新了现有的库到较新的版本。
  • 是的,确实,我猜到了这样的事情,但是......不幸的是,我完全忘记了可能发生的事情。
  • 似乎在最新版本的 Java 中,newInstance 方法不再接受参数。您必须依赖in the documentation 报告的程序。我发现最简单的方法是使用System.setProperty("javax.xml.transform.TransformerFactory", TRANSFORMER_FACTORY_CLASS)
  • 没错,我没有用最新版本的 Java 检查它。尽管查看了您评论中的链接,但我可以看到两种 newInstance 方法都存在(就像在以前的 Java 版本中一样):一个没有参数,另一个具有与我的答案相同的参数 :)
【解决方案2】:

This question 的回答似乎表明当 XSL 无效时会发生这种情况,这可以解释我目前遇到的问题。

在我们的具体案例中,使用的 XML 编辑器在文件的第一个位置静默插入了一个不可见字符。打印文件的前几个字节显示了这一点。使用更强大的编辑器,我们从文件中删除了有问题的字节,一切都很好。

【讨论】:

  • 对我来说是在 svn 更新之后,我没有看到 xsl 中存在冲突,导致 xsl 在无效 xml 中
【解决方案3】:

输入流为空。

【讨论】:

  • 我可以确认情况并非如此:org.apache.jasper.JasperException:JSP 中的异常:/dca/ass2/a.jsp:49 46:47: xml.getInputStream(); 48: xsl.getInputStream(); 49: 变压器.reset(); 50: 51: //transformer.transform(xml, result); 52:所以它抛出一个异常,因为transformer为空。
【解决方案4】:

在传递之前检查 xml 是否为空/空。我想你会发现它是空的。

例如new StreamSource(new URL(mondialURL).openStream()) 是返回 null 还是空对象?

【讨论】:

    猜你喜欢
    • 2011-06-18
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2014-03-05
    • 2012-06-24
    相关资源
    最近更新 更多