Java 如何在 WebSphere 中管理 ClassPath
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/427837/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I manage the ClassPath in WebSphere
提问by DaveH
I have a problem with my web module classpath in Websphere v6.1.
我在 Websphere v6.1 中的 Web 模块类路径有问题。
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.
在我的 WEB-INF/lib 中,我有大量的 jar 文件,其中包括 xercesImpl.jar 和 xmlparserv2.jar。我需要两个罐子都在场,但它们似乎相互冲突。具体来说,每个 jar 都包含一个 META-INF/services 目录,因此,当我们尝试通过 JAXP 获取 DocumentBuilderFactory 的实例时,我们获得的实例取决于这两个 jar 在类路径中出现的顺序。
I alwayswant 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.
我总是想用DocumentBuildFactory的Xerces的实例,所以我要推xercesImpl.jar到classpath的前面。我试图通过在清单文件中为 war 文件指定一个类路径部分来做到这一点,但是我在我的 WAS 模块复合类加载器中实际获得的类路径非常奇怪。我似乎得到了一些 WAS 提供的标准内容,然后是按字母顺序排列的 WEB-INF 库的内容,然后是 Manifest 文件指定的类路径。
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.
如果我根本不将清单文件放入战争中,我会得到标准内容,然后是 WEB-INF/lib 的内容,但顺序是任意的。
What am I missing? Is there a way in which I can set the class path up to be exactly what I want?
我错过了什么?有没有一种方法可以将类路径设置为我想要的?
Dave
戴夫
采纳答案by McDowell
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).
我假设 WebSphere 是指常规的 J2EE 应用程序服务器(而不是社区版之类的东西;WebSphere 是应用于许多 IBM 产品的品牌名称)。
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).
我认为你的选择是有限的。由于依赖关系看起来很明确,我更喜欢编程方法而不是依赖类路径的变幻莫测(比如显式创建工厂实例而不是依赖 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 RADtooling if you use it).
如果这不是一个选项,您可能需要考虑将您的依赖项之一设为 EAR 项目实用程序 JAR,并使用 WAR 上的 PARENT_LAST 类加载策略配置 MODULE 类加载。这可以通过浏览器管理控制台进行配置(或者通过RAD工具,如果你使用它)。
Another thing I'd look at is the WAS Shared Librariesfeature (under Environmentin the browser admin console). These can be associated with serversor applications. The downside is that this requires more configuration.
我要看的另一件事是 WAS共享库功能(在浏览器管理控制台的环境下)。这些可以与服务器或应用程序相关联。缺点是这需要更多配置。
回答by Vineet Reynolds
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.
在 IBM Websphere Application Server 6.1 中,Web 模块有自己的类加载器,这些类加载器通常用于 PARENT_FIRST 模式。这意味着 Web 模块类加载器会在加载任何新类之前尝试将类加载委托给父类加载器。
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.
如果您希望在 XML 解析器 v2(我假设是 Oracle XML v2 解析器)类之前加载 Xerces 类,那么 Xerces 类将必须由父类加载器加载 - 在这种情况下,最好是应用程序类加载器. 这可以通过将 Xerces jar 放在 EAR 文件(如果有)的根目录中来完成,或者在根目录中准备带有 xerces.jar 和 WAR 文件的 EAR 文件。然后应将 xmlparserv2 jar 放置在 WEB-INF\lib 中。
You could also attempt creating an Xerces shared library for usage by your application.
您还可以尝试创建一个 Xerces 共享库供您的应用程序使用。
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.
您可以在IBM WebSphere Application Server V6.1:系统管理和配置 中找到关于此的更多信息。详细信息请参见第 12 章。
回答by Shreeni
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
您还可以尝试设置系统属性以更喜欢实现。例如,更喜欢 xmlparserv2 dom 解析器,设置 javax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory
回答by Ivan
How JAXP Chooses Parsers
JAXP 如何选择解析器
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:
您可能想知道这个程序实际使用的是哪个解析器。毕竟,JAXP 是相当独立于解析器的。答案取决于您的类路径中安装了哪些解析器以及某些系统属性的设置方式。默认是使用由javax.xml.parsers.DocumentBuilderFactory
系统属性命名的类。例如,如果您想确保使用 Xerces 来解析文档,那么您可以像这样运行 JAXPChecker:
D:\books\XMLJAVA>java -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl JAXPChecker file:///D:/books/xmljava/dom.xml
> file:///D:/books/xmljava/dom.xml is well-formed.
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 the javax.xml.parsers.DocumentBuilderFactory
system property. If you want to consistently use a certain DOM parser, for instance gnu.xml.dom.JAXPFactory
, place the following line in that file:
如果javax.xml.parsers.DocumentBuilderFactory
未设置该属性,那么 JAXP 将在 JRE 目录中的 lib/jaxp.properties 属性文件中查找以确定javax.xml.parsers.DocumentBuilderFactory
系统属性的默认值。例如,如果您想始终使用某个 DOM 解析器gnu.xml.dom.JAXPFactory
,请将以下行放在该文件中:
javax.xml.parsers.DocumentBuilderFactory=gnu.xml.dom.JAXPFactory
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 concrete DocumentBuilderFactory
subclass.
如果这无法找到解析器,那么接下来的 JAXP 会META-INF/services/javax.xml.parsers.DocumentBuilderFactory
在所有可供运行时使用的 JAR 文件中查找一个文件,以找到具体DocumentBuilderFactory
子类的名称。
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 pick org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
by default but the ?lfred JAXP classes pick gnu.xml.dom.JAXPFactory
instead.
最后,如果失败,则DocumentBuilderFactory.newInstance()
返回一个默认类,通常是来自也提供 JAXP 类的供应商的解析器。例如,JDK JAXP 类org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
默认选择,但 ?lfred JAXP 类选择gnu.xml.dom.JAXPFactory
。