分享

如何解决Websphere中wsjar的问题

 wtf_soft 2006-04-19
如何解决Websphere中wsjar的问题
一,概述

我们知道,Websphere有自己的Classloader,它对类的加载做了一些自己的定制,但是往往由于有些定制的特殊性,而造成了人们在上面部署应用的不方面,这其中一个比较大麻烦就是,Webpshere中对jar包中资源的定位URL有自己特殊的格式,例如:

wsjar:file:/C:/dev/ws/default/sample_app/xsd.resources.jar!/org/eclipse/test.xml
我们知道URL是统一资源定位描述,Sun J2SE标准中,jar包中的资源的URL格式应该是以jar:开头,即类似如下的样子

jar:file:/C:/dev/ws/default/sample_app/xsd.resources.jar!/org/eclipse 
而目前大多数开源技术,在以URL做为参数来载入实际资源时,并没有考虑到wsjar开头的情况,因此当一个较为复杂的应用向Webpshere服务器部署时,往往就会出现关于这方面的报错,例如:

No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: 
wsjar:file:/F:/WebSphere/AppServer/lib/workplaceoa/ehcache-1.1.jar!/ehcache-failsafe.xml
如果你仍然觉得不知道在什么情况下会出现wsjar的情况,那么给你举一个例子:下面我们使用apache commons中的commons configuration来写一个代码片断

        Configuration configuration = (ConfigurationconfMap.get(name);
        if (configuration == null) {
            ConfigurationFactory factory = new ConfigurationFactory();
            URL url = PropertyGetter.class.getClassLoader().getResource("myconfig.xml");//你将myconfig.xml打在某个jar包中
              factory.setConfigurationURL(url);
            try {
                configuration = factory.getConfiguration();
            catch (Exception e) {
                logger.error("could not find the configuration ", e);
            }
        }
        String value=configuration.getString(propertyName);
将该代码片断放在websphere某个应用的某个jsp文件中,执行该页面时就会报如下的错误:

[06-4-18 14:31:03:500 CST73068638 Digester      E org.apache.commons.digester.Digester  Begin event threw exception
[06-4-18 14:31:03:516 CST73068638 Digester      E org.apache.commons.digester.Digester  TRAS0014I: 下列异常已记录 
org.apache.commons.configuration.ConfigurationException: java.lang.NullPointerException
    at org.apache.commons.configuration.AbstractFileConfiguration.load(AbstractFileConfiguration.java:283)
我们在出错之前,如果将此时的url打印出来,结果URL是以wsjar:开头的一个形式。我们此时只需做如下简单的转换,就可以让代码正常工作:

URL url = PropertyGetter.class.getClassLoader().getResource("myconfig.xml");//你将myconfig.xml打在某个jar包中
//加入url转化代码
String urlStr=url.toString();
if(urlStr.startsWith("wsjar:"){
    urlStr=urlString.substring(2);
    url=new URL(urlStr);
}
//转转换结束
factory.setConfigurationURL(url);
现在你应该明白了,为什么会在websphere中报wsjar有关的错误了吧。也许你会说,只要我们自己写代码时将wsjar的情况考虑进去不就可以避免了吗?是的,如果我们自己的应用考虑到了wsjar的情况,那么只能说我们自己的代码在websphere运行不会出现类似的问题,但是在许多情况下,我们所使用的开源技术的在很多情况下也会使用 XXXClass.class.getClassLoader().getResource("xxx.properties")的形式,那么如果他们自己没有考虑wsjar的情况,那么他们内部就会报出wsjar相关的错误,这样整个应用也往往因此而启动失败。

二,如何解决wsjar的问题

通过上面的描述,我们已经明白,wsjar的URL格式是Websphere自己特殊的URL格式,解决wsjar的问题,我们需要从几个方面入手
  • 对于我们自己的应用。
    • 我们自己在写与URL相关的代码时,将wsjar的格式考虑进去,例如我们可以提供一个URL转换类

public class URLPatternResolver {

    /** URL protocol for an entry from a jar file: "jar" */
    private static final String URL_PROTOCOL_JAR = "jar";

    /** URL protocol for an entry from a zip file: "zip" */
    private static final String URL_PROTOCOL_ZIP = "zip";

    /** URL protocol for an entry from a WebSphere jar file: "wsjar" */
    private static final String URL_PROTOCOL_WSJAR = "wsjar";

    /** Separator between JAR URL and file path within the JAR */
    private static final String JAR_URL_SEPARATOR = "!/";

    private static Log logger = LogFactory.getLog(URLPatternResolver.class);

    public URLPatternResolver() {
        super();
    }

    /**
     * TODO 增加对zip的转换
     
     @param url
     *            输入的url
     @return
     */
    public static URL getStandardURL(String url) {
        if (url == null) {
            return null;
        }
        if (logger.isDebugEnabled()) {
            logger.debug("解析URL:" + url);
        }
        URL urlObj = null;
        if (url.startsWith(URL_PROTOCOL_WSJAR)) {
            if (logger.isDebugEnabled()) {
                logger.debug("当前使用的是WAS的classloader");
            }
            try {
                url = url.substring(2);
                urlObj = new URL(url);
            catch (Exception e) {
                logger.error("URL转换出错!");
                return null;
            }
        else if (url.startsWith(URL_PROTOCOL_JAR)) {
            if (logger.isDebugEnabled()) {
                logger.debug("当前使用的是普通的classloader");
            }
            try {
                urlObj = new URL(url);
            catch (Exception e) {
                logger.error("URL转换出错!");
                return null;
            }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("当前使用的是普通的classloader");
            }
            try {
                urlObj = new URL(url);
            catch (Exception e) {
                logger.error("URL转换出错!");
                return null;
            }
        }
        return urlObj;
    }

}
    • 使用上面的转换类,在进行xx.class.getClassLoader().getResource(fileInJar)时,我们加入转换:

    ...
    URL url=xx.class.getClassLoader().getResource(fileInJar);
    url=URLPatternResolver.getStandardURL(url);
    ...
  • 对于应用中所使用到的开源技术
    • 如果我们要使用某些开源技术的某个类的方法,而该方法是以URL对象为输入参数,那么我们在输入URL之前,应该经过类似上面说的转换。
    • 到目前为止,一些开源技术例如Spring等,在他们的最新版本中已经加入了对wsjar这中URL格式的支持,如果可以,请替换掉你原先所使用的jar,使用最新版的jar包即可,可以说,现在比较重要的开源技术一般都开始对Websphere 的wsjar格式进行了支持,请检查你所使用的jar是不是最新版的,如果不是而且报错又来源于这个包,则下载一个最新版的。
    • 如果我们使用了尚未支持wsjar的开源技术,而且我们必须使用该技术,那么一个不得已的方法就是,下载该技术的开源代码,直接修改其代码使其支持wsjar的格式。
三,从wsjar问题看Websphere
  • 我们知道Sun规定的J2EE标准是一个基础标准,应用服务器厂商在实现时,往往都加入了一些甚至许多额外的特性和功能,那么同一个应用程序在向不同的J2EE服务器部署时,可能就会出现不同的问题,当然了一个简单的标准的J2EE应用,在任何J2EE标准服务器上部署应该都是没有太大问题的,但是我们实际中的应用往往都是比较或相当复杂的,当我们基于某个服务器开发时,往往就会在某些方面依赖于该服务器,当移植到其它服务器时,就必须做相应的修改。
  • Websphere是IBM的一个重量级J2EE商业服务器,它所实现的复杂程度要比一般的商业J2EE服务器和开源的J2EE服务器要大得多,它对服务器中类加载策略、服务器集群以及性能优化等方面做了大量的工作,就以其类加载策略为例:
    • 类加载策略可以在几个层次上进行设置:服务器级别(例如在server1中)、应用级别(例如你的application中)、Web模块级别(应用中如果存在war),在每个级别中,都可以选择parent last或者parent first等等。
    • 这多级别的类加载策略,websphere在管理时肯定会加入自己许多额外的东西。
  • 关于jar方面,websphere中也有多种层次的jar:webpshere自身的jar、应用自身的jar和共享库中的jar,这多种jar,websphere可能也需要不少额外的东西才能管理的过来,在Websphere中引入wsjar也许就有这方面的原因。
  • 但是无论如何,还是要批评Websphere中关于wsjar的引入,毕竟给人们带来了相当的不便,尤其是如何解决wsjar的问题,IBM相关部门、论坛、技术支持等基本都没有给出较好的意见和回复,写上面的文章,主要目的就是为了不让其它人再为wsjar的问题而困扰,不再为得不到IBM有效的支持而感到绝望,同时也希望IBM相关的技术论坛、信息中心(Info Center)能改一改那种官方的面孔,解决问题才是最关键的!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多