ravenix

鱼如何控制自己的呼吸
posts - 7, comments - 3, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2005年8月30日

Eclipse 应用可以使用Java Web Start部署,实现Rich Client。

这要求把所有的插件打包成独立的jar,并且要签署它。

如果要用到别人开发的java库,就要利用eclipse提供的Create a plug-in project from existing JAR archives 把它做成 eclipse plugin。

Apache Jakarta有许多项目使用了commons-logging来写log。如果用到了这样的项目,你也需要把commons-logging做成一个 plugin。但是commons-logging在使用eclispe plugin包装并使用Java Web Start部署时,它会抛出异常

LogConfigurationException : Invalid class loader hierarchy. You have more than one version of org.apache.commons.logging.Log visible, which is not allowed.

究其原因,是JCL(Jakarta Commons Logging)中一直存在的classloader问题。

简单来说,JCL使用调用者的classloader加载Log接口,这是最常见的类载入方法;但是加载具体的实现类是,用的是thread context classloader。

通常情况下,这两个classloader是同一个。但是Eclipse有一套插件类加载机制,每个插件使用不同的 classloader。在这个例子中,加载Log接口是EclipseClassLoader,加载Log实现类的thread context classloader是JNLPClassLoader,它们并不相同。问题就来了,用不同classloader加载的类被认为是无关的,所以JCL 的实现类不能赋给Log接口类,就会抛出那个异常。

关于JCL classloader问题更详细解释,请看log4j的创始人之一,Ceki Gülcü写的文章
"Taxonomy of class loader problems encountered when using Jakarta Commons Logging"

为了解决这个问题,我启动了一个项目,jcleclipse -- 重写了JCL,固定实现为把所有的log写到eclipse自己的ILog里。这样就不用要求用户在某个指定的地方建目录来存储log。

jcleclipse项目主页 http://jcleclipse.sourceforge.net/
jcleclipse项目概要 http://sourceforge.net/projects/jcleclipse

posted @ 2005-09-09 14:30 ravenix 阅读(1249) | 评论 (1)编辑 收藏

如果用digister处理的xml里包含了外部dtd指定,即在!DOCTYPE中用PUBLIC指定外部dtd,即使使用了

digester.setValidating(false);

底层的sax解析器xerces仍然会去指定的地址去加载DTD,特别地,如果指定的地址无法获得DTD,就会抛出异常:
SAXException: The markup declarations contained or pointed to by the document type declaration must be well-formed

为了避免这个问题,可以使用这样的语句:
digester.setValidating(false);
digester.setFeature(
"http://apache.org/xml/features/nonvalidating/load-external-dtd",false);

当然这个设置只有在底层的sax解析器是xerces才有效。如果你使用的是其它的sax解析器,请参考解析器的文档。

posted @ 2005-08-30 15:57 ravenix 阅读(1049) | 评论 (0)编辑 收藏