Xml 在同一Java虚拟机上使用不同的DocumentBuilder实现
我知道这个问题已经被问过了,但用的是另一种味道,所以我从我的视角再次问 在我们的应用服务器中,有几个EJB(因此,AFAIK,几个线程,每个EJB调用一个线程)。有些EJB为了正常运行,需要DocumentBuilder工厂来生成xerces实例,有些EJB需要crimson实例 目前,选择强制xerces作为默认值,因此xerces类被注入到适当的全局System.property中 据我所见,DocumentBuilder类首先查找System.property,然后查找JRE文件夹中的属性文件,然后再次查找JAR/Services中的属性文件 为了隔离需要crimson工作的库,我编写了一个自定义类加载器,因此它们的jar不在类路径中,我可以确保“套件”的其他部分是可靠的,不会受到干扰 但是,即使我隔离了那些JAR,它们也会利用DocumentBuilder,正如前面所说的那样,它会寻找实现。如果我在调用库所需的严格时间内更改System.property,我会冒其他EJB崩溃的风险,因为它们没有得到正确的实现 我还试图编写一个假DocumentBuilder类来根据调用线程切换newInstance结果,但这不起作用(太糟糕了,被调用的库通过捕获原始异常来屏蔽异常,并通过仅获取原始消息来抛出新异常,这不足以说明问题) 我正在寻找一种在线程级别隔离属性更改的方法,但无法解决它Xml 在同一Java虚拟机上使用不同的DocumentBuilder实现,xml,multithreading,jakarta-ee,global-variables,default-implementation,Xml,Multithreading,Jakarta Ee,Global Variables,Default Implementation,我知道这个问题已经被问过了,但用的是另一种味道,所以我从我的视角再次问 在我们的应用服务器中,有几个EJB(因此,AFAIK,几个线程,每个EJB调用一个线程)。有些EJB为了正常运行,需要DocumentBuilder工厂来生成xerces实例,有些EJB需要crimson实例 目前,选择强制xerces作为默认值,因此xerces类被注入到适当的全局System.property中 据我所见,DocumentBuilder类首先查找System.property,然后查找JRE文件夹中的属性
有什么想法吗?谢谢大家! 好的,我找到了解决这个问题的方法 我实际上写了一个假的DocumentBuilder,它在一个静态字段中接受需要获得crimson实现的线程。所以,只有这个线程会得到深红色,所有其他线程都会得到xerces。然后,我在javax.xml.parsers.DocumentBuilderFactory系统属性中设置这个类,并在完成时重置为原始值。我想,这个解决方案可以推广到处理线程请求的永久类 这里是假DocumentBuilder的来源:
public class DocumentBuilderFactoryTweak
extends DocumentBuilderFactory
{
private static Thread tweakingTH = null;
private DocumentBuilderFactory impl = null;
public DocumentBuilderFactoryTweak() {
super();
try {
this.impl =
Thread.currentThread() == tweakingTH
? (DocumentBuilderFactory)tweakingTH.getContextClassLoader().loadClass( "org.apache.crimson.jaxp.DocumentBuilderFactoryImpl" ).newInstance()
: (DocumentBuilderFactory)Class.forName( "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl" ).newInstance();
}
catch( Throwable exc ) { exc.printStackTrace(); }
}
public synchronized static void setTweakingThread( Thread th ) { tweakingTH = th; }
public boolean isCoalescing () { return this.impl.isCoalescing (); }
public boolean isExpandEntityReferences () { return this.impl.isExpandEntityReferences (); }
public boolean isIgnoringComments () { return this.impl.isIgnoringComments (); }
public boolean isIgnoringElementContentWhitespace () { return this.impl.isIgnoringElementContentWhitespace(); }
public boolean isNamespaceAware () { return this.impl.isNamespaceAware (); }
public boolean isValidating () { return this.impl.isValidating (); }
public void setCoalescing ( boolean v ) { this.impl.setCoalescing ( v ); }
public void setExpandEntityReferences ( boolean v ) { this.impl.setExpandEntityReferences ( v ); }
public void setIgnoringComments ( boolean v ) { this.impl.setIgnoringComments ( v ); }
public void setIgnoringElementContentWhitespace ( boolean v ) { this.impl.setIgnoringElementContentWhitespace ( v ); }
public void setNamespaceAware ( boolean v ) { this.impl.setNamespaceAware ( v ); }
public void setValidating ( boolean v ) { this.impl.setValidating ( v ); }
public javax.xml.parsers.DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { return this.impl.newDocumentBuilder (); }
public Object getAttribute ( String k ) { return this.impl.getAttribute ( k ); }
public void setAttribute ( String k, Object v ) { this.impl.setAttribute ( k, v ); }
}