如何在 WebSphere 中管理 ClassPath
我的 Websphere v6.1 中的 Web 模块类路径有问题。
在我的 WEB-INF/lib 中,我有大量的 jar 文件,其中包括 xercesImpl.jar 和 xmlparserv2.jar。 我需要两个罐子都存在,但它们似乎相互冲突。 具体来说,每个 jar 都包含一个 META-INF/services 目录,因此,当我们尝试通过 JAXP 获取 DocumentBuilderFactory 的实例时,我们获取的实例取决于这两个 jar 在类路径中出现的顺序。
我总是想要使用 DocumentBuildFactory 的 xerces 实例,因此我想将 xercesImpl.jar 推送到类路径的前面。 我尝试通过在 War 文件的清单文件中指定类路径部分来实现此目的,但是我在 WAS 模块复合类加载器中实际获得的类路径非常奇怪。 我似乎得到了 WAS 放置的一些标准内容,后面是按字母顺序排列的 WEB-INF lib 的内容,后面是 Manifest 文件指定的类路径。
如果我根本不将清单文件放入战争中,我会得到标准内容,然后是 WEB-INF/lib 的内容,但顺序是任意的。
我缺少什么? 有没有一种方法可以将类路径设置为我想要的?
戴夫
I have a problem with my web module classpath in Websphere v6.1.
In my WEB-INF/lib I have a largish number of jar files which include xercesImpl.jar and xmlparserv2.jar. I need both jars to be present, but they appear to confict with each other. Specifically, each jar contains a META-INF/services directory so, when we try to get an instance of a DocumentBuilderFactory via JAXP, which instance we get depends upon the order in which these two jars appear in the classpath.
I always want to use the xerces instance of the DocumentBuildFactory, so I want to push xercesImpl.jar to the front of the classpath. I've tried to do this by specifying a Class-Path section in the Manifest file for the war file, but the class path that I actually get in my WAS Module Compound CLass Loader in is very strange. I seem to get some standard stuff that WAS puts on, followed by the contents of WEB-INF lib in alphabetical order, followed by the classpath specified by the Manifest file.
If I don't put a manifest file into the war at all, I get the standard stuff followed by the contents of WEB-INF/lib but in an arbitrary order.
What am I missing? Is there a way in which I can set the class path up to be exactly what I want?
Dave
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为 WebSphere 是指常规的 J2EE 应用程序服务器(而不是 Community Edition 之类的东西;WebSphere 是应用于许多 IBM 产品的品牌名称)。
我认为你的选择是有限的。 由于依赖关系看起来非常明确,因此我更喜欢编程方法,而不是依赖于类路径的变幻莫测(例如显式创建工厂实例而不是依赖 SPI)。
如果这不是一个选项,您可能需要考虑将依赖项之一制作为 EAR 项目实用程序 JAR,并使用 WAR 上的 PARENT_LAST 类加载策略配置 MODULE 类加载。 这可以通过浏览器管理控制台进行配置(或者通过 RAD 工具(如果您使用它)) 。
我要查看的另一件事是 WAS 共享库功能(在浏览器管理控制台的环境下)。 这些可以是 与服务器关联或应用。 缺点是这需要更多配置。
I assume by WebSphere, you mean the regular J2EE Application Server (and not something like Community Edition; WebSphere is a brand name applied to a number of IBM products).
I think your options are limited. Since the dependencies look quite explicit, I would prefer a programmatic approach rather than relying on the vagaries of the classpath (like creating factory instances explicitly rather than relying on the SPI).
If that isn't an option, you might want to look at making one of your dependencies an EAR project utility JAR and configure MODULE classloading with a PARENT_LAST classloading policy on the WAR. This can be configured via the browser admin console (or via the RAD tooling if you use it).
Another thing I'd look at is the WAS Shared Libraries feature (under Environment in the browser admin console). These can be associated with servers or applications. The downside is that this requires more configuration.
在 IBM Websphere Application Server 6.1 中,Web 模块有自己的类加载器,通常在 PARENT_FIRST 模式下使用。 这意味着 Web 模块类加载器会在加载任何新类之前尝试将类加载委托给父类加载器。
如果您希望在 XML 解析器 v2(我假设是 Oracle XML v2 解析器)类之前加载 Xerces 类,那么 Xerces 类必须由父类加载器加载 - 在这种情况下,最好是应用程序类加载器。 这可以通过将 Xerces jar 放在 EAR 文件的根目录中(如果有的话)或使用 xerces.jar 和根目录中的 WAR 文件准备 EAR 文件来完成。 然后,应将 xmlparserv2 jar 放置在 WEB-INF\lib 中。
您还可以尝试创建一个 Xerces 共享库以供您的应用程序使用。
您可以在 IBM WebSphere Application Server V6.1:系统管理和配置。 详细信息请参阅第 12 章。
In IBM Websphere Application Server 6.1, web modules have their own class loaders that are usually used in the PARENT_FIRST mode. This means that the web module class loaders attempt to delegate class loading to the parent class loaders, before loading any new classes.
If you wish to have the Xerces classes loaded before the XML parser v2 (I'm assuming Oracle XML v2 parser) classes, then the Xerces classes will have to be loaded by a parent class loader - in this case, preferably the application class loader. This can be done by placing the Xerces jar in the root of the EAR file (if you have one) or prepare the EAR file with xerces.jar and your WAR file in the root. The xmlparserv2 jar should then be placed in WEB-INF\lib.
You could also attempt creating an Xerces shared library for usage by your application.
You can find more information about this in the IBM WebSphere Application Server V6.1: System Management and Configuration. Details are available in Chapter 12.
JAXP 如何选择解析器
您可能想知道该程序实际使用哪个解析器。 毕竟,JAXP 相当独立于解析器。 答案取决于类路径中安装了哪些解析器以及如何设置某些系统属性。 默认情况下使用由
javax.xml.parsers.DocumentBuilderFactory
系统属性命名的类。 例如,如果您想确保使用 Xerces 来解析文档,那么您可以像这样运行 JAXPChecker:如果未设置 javax.xml.parsers.DocumentBuilderFactory 属性,则 JAXP 会查找JRE 目录中的 lib/jaxp.properties 属性文件来确定 javax.xml.parsers.DocumentBuilderFactory 系统属性的默认值。 如果您想始终使用某个 DOM 解析器,例如
gnu.xml.dom.JAXPFactory
,请将以下行放入该文件中:如果无法找到解析器,接下来 JAXP 会查找 <运行时可用的所有 JAR 文件中的 code>META-INF/services/javax.xml.parsers.DocumentBuilderFactory 文件可查找具体的
DocumentBuilderFactory
子类的名称。最后,如果失败,则
DocumentBuilderFactory.newInstance()
返回一个默认类,通常是来自也提供 JAXP 类的供应商的解析器。 例如,JDK JAXP 类默认选择org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
,但 Ælfred JAXP 类则选择gnu.xml.dom.JAXPFactory
。How JAXP Chooses Parsers
You may be wondering which parser this program actually uses. JAXP, after all, is reasonably parser-independent. The answer depends on which parsers are installed in your class path and how certain system properties are set. The default is to use the class named by the
javax.xml.parsers.DocumentBuilderFactory
system property. For example, if you want to make sure that Xerces is used to parse documents, then you would run JAXPChecker like this:If the
javax.xml.parsers.DocumentBuilderFactory
property is not set, then JAXP looks in the lib/jaxp.properties properties file in the JRE directory to determine a default value for thejavax.xml.parsers.DocumentBuilderFactory
system property. If you want to consistently use a certain DOM parser, for instancegnu.xml.dom.JAXPFactory
, place the following line in that file:If this fails to locate a parser, next JAXP looks for a
META-INF/services/javax.xml.parsers.DocumentBuilderFactory
file in all JAR files available to the runtime to find the name of the concreteDocumentBuilderFactory
subclass.Finally, if that fails, then
DocumentBuilderFactory.newInstance()
returns a default class, generally the parser from the vendor who also provided the JAXP classes. For example, the JDK JAXP classes pickorg.apache.crimson.jaxp.DocumentBuilderFactoryImpl
by default but the Ælfred JAXP classes pickgnu.xml.dom.JAXPFactory
instead.您还可以尝试设置系统属性以选择实现。
例如,更喜欢 xmlparserv2 dom 解析器,设置
javax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory
You could also try setting system property to prefer an implementation.
e.g. to prefer xmlparserv2 dom parser, set
javax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory