浏览 5338 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-11-07
限制:不能跨越框架的封装直接调用log4J的初始化类来初始化log4J。 版本:webMethods IS 6.1, log4J 1.2.8 log4J在第一次调用LogManager的时候最始化,代码: if(configurationOptionStr == null) { url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE); if(url == null) { url = Loader.getResource(DEFAULT_CONFIGURATION_FILE); } } else { try { url = new URL(configurationOptionStr); } catch (MalformedURLException ex) { // so, resource is not a URL: // attempt to get the resource from the class path url = Loader.getResource(configurationOptionStr); } } 这里的Loader是helpers下面的Loader类,getResource方法的代码如下: static public URL getResource(String resource) { ClassLoader classLoader = null; URL url = null; try { if(!java1) { classLoader = getTCL(); if(classLoader != null) { LogLog.debug("Trying to find ["+resource+"] using context classloader " +classLoader+"."); url = classLoader.getResource(resource); if(url != null) { return url; } } } // We could not find resource. Ler us now try with the // classloader that loaded this class. classLoader = Loader.class.getClassLoader(); if(classLoader != null) { LogLog.debug("Trying to find ["+resource+"] using "+classLoader +" class loader."); url = classLoader.getResource(resource); if(url != null) { return url; } } } catch(Throwable t) { LogLog.warn(TSTR, t); } // Last ditch attempt: get the resource from the class path. It // may be the case that clazz was loaded by the Extentsion class // loader which the parent of the system class loader. Hence the // code below. LogLog.debug("Trying to find ["+resource+ "] using ClassLoader.getSystemResource()."); return ClassLoader.getSystemResource(resource); } 大家可以看到,classLoader = Loader.class.getClassLoader(); 实际上log4J是调用当前类的ClassLoader来装载这个properties文件的。特别注意的是它使用的是getResource()方法,该方法返回一个URL类型的对象。 接下来看webMethods的ClassLoarder,webMethods IS有一个Server的ClassLoader,每一个Package有一个自己的ClassLoader,值得注意的是Package的ClassLoader与整个Server的ClassLoader没有继承关系,它们都是com.wm.app.b2b.server.ServerClassLoader的实例,这个类直接继承自JDK的ClassLoader,但是覆盖了父类的getResourceAsStream方法,代码如下: public InputStream getResourceAsStream(String name) { for(int i = 0; i < resdirs.size(); i++) { File rfile = new File((File)resdirs.elementAt(i), name); if(rfile.exists()) try { return new FileInputStream(rfile); } catch(IOException _ex) { JournalLogger.log(27, 28, name); } } for(int i = 0; i < jars.size(); i++) try { ZipFile zfile = new ZipFile((File)jars.elementAt(i)); ZipEntry ze = zfile.getEntry(name); if(ze != null) { InputStream is = null; is = zfile.getInputStream(ze); return is; } } catch(Exception _ex) { JournalLogger.log(26, 28, name); } for(int i = 0; i < cldirs.size(); i++) { File cfile = new File((File)cldirs.elementAt(i), name); if(cfile.exists()) try { return new FileInputStream(cfile); } catch(IOException _ex) { JournalLogger.log(27, 28, name); } } return null; } 其中变量“resdirs”,“jars”,“cldirs”都是Vertor,通过下面的方法最始初化: public static void addPackage(String pkgName) throws IOException, ZipException { Resources res = Server.getResources(); ServerClassLoader scl = new ServerClassLoader(pkgName); scl.addJar(new File(res.getPackageCodeDir(pkgName), "classes.zip")); scl.addJarDir(res.getPackageJarsDir(pkgName)); scl.addClassDir(res.getPackageClassDir(pkgName)); scl.addResourceDir(res.getPackageResourceDir(pkgName)); scl.addResourceDir(res.getDeprecatedPackageResourceDir(pkgName)); pkgs.put(pkgName, scl); } private void addResourceDir(File dir) { if(dir != null || dir.isDirectory()) resdirs.addElement(dir); } 查看Resource类的代码发现放在Package的code/classes下,code/jars下,config下和lib下的文件都可以通getResourceAsStream这个方法取到。不知道什么原因,webMethods实现的ServerClassLoader并没有覆盖getResource方法,调用这个方法实际调用的是其父类即JDK的ClassLoader的方法。 问题就出在这里,当我在Package里用log4J的时候,log4J的实现是用getResource方法的,因此放在Package的资源文件下的properties文件无法被找到,只能将这个文件放到整个Server级别的classpath下。 影响:整个webMethods IS如果有多个包用自己的log4J,但却只能有一个log4J的配置。即使设置log4j.configuration这个属性,也只能有一个。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-11-07
关于webmethods的应用,不知道能否举个实际的用java调用的例子
|
|
返回顶楼 | |
发表时间:2006-11-07
引用 接下来看webMethods的ClassLoarder,webMethods IS有一个Server的ClassLoader,每一个Package有一个自己的ClassLoader,值得注意的是Package的ClassLoader与整个Server的ClassLoader没有继承关系,它们都是com.wm.app.b2b.server.ServerClassLoader的实例,这个类直接继承自JDK的ClassLoader,但是覆盖了父类的getResourceAsStream方法,代码如下: ClassLoader的父子关系和Classloader的实现类的继承关系是两回事的,或许你需要再研究一下是否有其他的设置!没有用过webMethods IS 6.1,也不知道此为何物.只是在Websphere Application Sever中,可以设置不同Classloader的加载策略. For example: PARENT_FIRST or PARENT_LAST. 还有,或许你可以DEBUG以下,看看当前的加载log4j LogManager的Classloder是那个? 它的查找路径有那些? 当前加载的log4j LogManager在那个位置? |
|
返回顶楼 | |