0

我知道这个问题已经被问过了,但是风格不同,所以我再次从我的 POV 中问。

在我们的应用程序服务器中存在多个 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 结果,但这不起作用(太糟糕了,被调用的库通过捕获原始异常来掩盖异常并通过仅获取原始消息来抛出新异常,这不足以说明问题)

我正在寻找一种在线程级别隔离属性更改的方法,但无法弄清楚。

有什么想法吗?谢谢!

4

1 回答 1

0

好的,我想出了如何解决这个问题。

我实际上写了一个假 DocumentBuilder,它接受一个静态字段,即需要获取深红色实现的线程。所以,只有这个线程会变成深红色,所有其他线程都会得到 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 ); }    
}
于 2014-01-31T10:11:02.320 回答