- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
考虑这段代码(完全基于飞碟的“入门”代码,保留他们的权利):
package flyingsaucerpdf;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.xhtmlrenderer.pdf.ITextRenderer;
public class PDFMaker {
public static void main(String[] args) throws Exception {
new PDFMaker().go();
}
public void go() throws Exception {
String inputFile = "sample.html";
String url = new File(inputFile).toURI().toURL().toString();
String outputFile = "firstdoc.pdf";
OutputStream os = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
renderer.layout();
renderer.createPDF(os);
os.close();
}
}
一些事实:
Caused by: org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. at org.apache.xerces.dom.AttrNSImpl.setName(Unknown Source) at org.apache.xerces.dom.AttrNSImpl.(Unknown Source) at org.apache.xerces.dom.CoreDocumentImpl.createAttributeNS(Unknown Source) at org.apache.xerces.dom.ElementImpl.setAttributeNS(Unknown Source) at org.apache.xml.utils.DOMBuilder.startElement(DOMBuilder.java:307) ... 19 more
After looking for a while in the wrong place (for example, I created a child-first / parent-last class loader suspecting xalan / xerces jars, but it still fails), I finally narrowed down the root cause:
It seems that the web application that loads my code, has an old xalan.jar, specification version 1.2
I did a little test, I ran the code above as standalone (which worked fine before) but this time I added the xalan.jar from the web app to it's classpath, and bingo, the same error as in the web app scenario
So I inspected that old xalan.jar and wondered, what can cause the JVM to load it's old xalan implementation instead of the JDK's? after all my child-first class loader is also parent-last e.g. system in the middle, to say: searching the system classloader before the parent (to avoid loading parent overriden JDK jars, just like this case of the parent's xalan.jar overriding the JDK's xalan implementation)
Then something cought my eyes - a file in: xalan.jar/META-INF/services/ named javax.xml.transform.TransformerFactory with this content:
org.apache.xalan.processor.TransformerFactoryImpl
所以我立即在 eclipse 中按下 Ctrl+T 并寻找完整的合格名称......只在 xalan.jar 中!
然后我只搜索“TransformerFactoryImpl”,这就是 JDK 的内容:
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
容易看出区别
所以,如果您读到这里,我的底线问题是:如何让我的 TransformerFactory 使用 JDK 的实现而不是旧 Xalan 的实现?(我无法从中删除那个 jar我的代码将从中加载的网络应用程序)
最佳答案
看来答案比我想象的要简单。
在您的类加载器中,将此文件夹添加到类路径(不需要 jar):/META-INF/services/
在其中,创建一个名为 javax.xml.transform.TransformerFactory
对其进行编辑并将其设置为:com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
就是这样!
为什么有效?请参阅 Java 用于加载 Xalan 实现的此类。
请注意,对于特定的“META-INF”条目(与常规 Java 类加载器的工作方式相反,例如,父优先/子优先),它似乎实际上是父优先(或子优先)加载器但如果我错了,请随时纠正我
来自 javax.xml.datatype.FactoryFinder
的片段
/*
* Try to find provider using Jar Service Provider Mechanism
*
* @return instance of provider class if found or null
*/
private static Object findJarServiceProvider(String factoryId)
throws ConfigurationError
{
String serviceId = "META-INF/services/" + factoryId;
InputStream is = null;
// First try the Context ClassLoader
ClassLoader cl = ss.getContextClassLoader();
if (cl != null) {
is = ss.getResourceAsStream(cl, serviceId);
// If no provider found then try the current ClassLoader
if (is == null) {
cl = FactoryFinder.class.getClassLoader();
is = ss.getResourceAsStream(cl, serviceId);
}
} else {
// No Context ClassLoader, try the current
// ClassLoader
cl = FactoryFinder.class.getClassLoader();
is = ss.getResourceAsStream(cl, serviceId);
}
if (is == null) {
// No provider found
return null;
}
...
关于java - 如何防止具有 META-INF\services\javax.xml.transform.TransformerFactory 的 xalan.jar 接管 Xalan 实现中内置的 JDK 1.6?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5447633/
我有一段这样的代码。我发现 myResults = writer.getBuffer().toString(); 对某些用例返回 EMPTY STRING,但对其他用例则不返回。 我查看了服务器,但在
如何使用 javascript 通过 id 更改元素中的 -webkit-transform 、-moz-transform 、-o-transform 和 -ms-transform css? 这段
我正在使用 javax.xml.transform.Transformer.transform() 通过 xsl 样式表将一个 xml 转换为另一个 xml。我想以编程方式设置第一级 child 的排
为了使 seaborn.pairplot() 正常工作,在 jupyter notebook 中执行了以下步骤。 /usr/local/lib/python2.7/site-packages/matp
假设这个输入 XML 编写这些代码行: StreamSource source = new StreamSource(new StringReader(/* the above XML*/));
如何在 spring 框架中配置 java.xml.transform.Transformer ?我需要转换器的实例来通过 xslt 将 xml 转换为文本。因此,配置的转换器应该了解 xslt 样式
我一直在核心数据中使用可转换属性,将图像和颜色等复杂对象转换为原始数据。我拿了this ... The idea behind transformable attributes is that you
我正在尝试打开 XML 文件,添加一些更改,然后保存到其他 XML 文件结果。我正在使用标准 javax.xml.parsers.* 和 javax.xml.transform* 类。 但在保存的文档
Transformer(变换方法)对输入源的大小有限制吗? 我正在尝试转换一个相当长的 (18M) XML,但收到一个奇怪的错误 "The element type "HR" must be term
我正在尝试解析一个非常简单的示例: 100 我使用的样式表如下: 这在 libxs
来自文档 for from_pretrained ,我知道我不必每次都下载预训练的向量,我可以使用以下语法保存它们并从磁盘加载: - a path to a `directory` contain
默认缓存目录磁盘容量不足,我需要更改默认缓存目录的配置。 最佳答案 您可以在每次加载模型时指定缓存目录 .from_pretrained通过设置参数cache_dir .您可以通过导出环境变量 TRA
有一个函数,例如: CATransform3DGetAffineTransform Returns the affine transform represented by 't'. If 't' ca
我有一个包含 WCF 设置的配置文件: “add”元素只有一个 baseAddress 属性,所以我不能使用 Match 定位器。一种方法如何像我的示例中那样转换多个元素? 最
在收到下面链接中描述的错误后,我已将实体属性的 Transfomer 设置为 NSSecureUnarchiveFromData(之前为 nil)。 CoreData crash error Xcod
当我写Document时使用 Transformer 的 transform() 方法转换为 XML,生成的 XML 文档的格式很好 - 所有元素都写在单独的行上并缩进。除了第一个元素与定义写在同一行
我不明白 StreamResult 实例会发生什么。我看到 Transformer 对象接收 source 和 streamResult: transformer.transform(sour
从下面的代码片段我应该得出结论,std::transform 比 boost::transform 更受欢迎,因为前者使用更少的初始化和析构函数可能更有效比后者? #include #include
transform() 可以将函数应用到序列的元素上,并将这个函数返回的值保存到另一个序列中,它返回的迭代器指向输出序列所保存的最后一个元素的下一个位置。 这个算法有一个版本和 for_each()
我是 react-native 的新手。在项目上将 react-native 从 0.48.3 升级到 0.62.2 后,运行“react-native run-ios”命令时出现错误:“index.
我是一名优秀的程序员,十分优秀!