文档章节

Hibernate的Antlr在Weblogic中产生Jar冲突的历史缘故以及解决办法

山海经
 山海经
发布于 2014/11/27 23:57
字数 1065
阅读 240
收藏 4

Hibernate使用的文法分析器是antlr,WebLogic同样也是。

不少用户碰到ClassNotFoundException: org.hibernate.hql.ast.HqlToken的典型问题,这个典型问题已经通过配置weblogic.xml,要求Web应用优先加载WEB-INF的Jar(即应用Classloader)而非WebLogic的System Classloader得以勉强解决:

<weblogic-web-app>
  <container-descriptor>
    <prefer-web-inf-classes>true</prefer-web-inf-classes>
  </container-descriptor>
</weblogic-web-app>

Hibernate 3.0的用户发现上述的方法依然不能解决问题,因为Hibernate使用了Class.forName去Load一个类,而JVM加载类的方式是先 System Classloader(WebLogic),后Application Classloader(Web应用),于是,应用即使采用prefer-web-inf-classes策略,但Class.forName还是 Load了WebLogic的Antlr!!

 

Hibernate 3.1迅速解决了这个问题,Hibernate会使用context classloader,Class.forName这种罪恶的代码已经被消除掉。

 

无独有偶,2005年,澳大利亚的Suncorp-Metway公司使用Hibernate3.0.3 + WebLogic8.1SP4开发他们的应用 , 当时的WebLogic 8.1SP4内置了antlr 2.7.1,跟Hibernate  3.0.3捆绑的antlr-2.7.5H3.jar冲突,Suncorp-Metway公司希望改变WebLogic的SystemClassPath(加入antlr-2.7.5H3.jar), 效果等于替换了WebLogic的Antlr,这当然能够解决Hibernate的问题,但天知道会带来什么问题,因为WebLogic自身会使用 Antlr去分析EJBQL(如果不适用CMP,用户完全可以不管3721,置换WebLogic的Antlr版本了之),Suncorp-Metway公司担心这种替换对系统带来其他影响,希望BEA仍然能够提供技术支持。

当时,作为BEA在澳大利亚昆士兰州最大的BEA客户,他们的建议当然受到足够的尊重。 为此,BEA 8.1 SP4/SP5都提供了一个补丁,等同于升级了WebLogic 8.1自带的Antlr的版本,WebLogic 8.1SP6以及WebLogic 9.1开始都沿用这个变更。

 

很明显,这种办法不可能再次沿用到以后的SP,因为Antlr以及Hibernate的版本的更新速度远远高于WebLogic Service pack的更新速度,BEA不可能不断地重构Antlr来适应开源日新月异的API变化。

 

WebLogic 8.1 SP6之后,当使用Hibernate 3(策略是<prefer-web-inf-classes>true</prefer-web-inf-classes>)的 Antlr 2.7.6时候,轮到WebLogic自身的Servlet容器出问题(Hibernate好了,WebLogic出事了)抛出如下的Antlr异常:

java.lang.ClassCastException: antlr.CommonToken
at antlr.CharScanner.makeToken(CharScanner.java:175)
at weblogic.servlet.jsp.JspLexer.mWORD(JspLexer.java:4723)
at weblogic.servlet.jsp.JspLexer.mXML_ATTRIBUTES(JspLexer.java:4309)
at weblogic.servlet.jsp.JspLexer.mTAGLIB_DIRECTIVE_BODY(JspLexer.java:5034)
at weblogic.servlet.jsp.JspLexer.mTAGLIB_DIRECTIVE(JspLexer.java:4905)
at weblogic.servlet.jsp.JspLexer.mDIRECTIVE(JspLexer.java:4751)
at weblogic.servlet.jsp.JspLexer.mSTANDARD_THING(JspLexer.java:2161)
at weblogic.servlet.jsp.JspLexer.mTOKEN(JspLexer.java:1947)
at weblogic.servlet.jsp.JspLexer.nextToken(JspLexer.java:1820)
at weblogic.servlet.jsp.JspLexer.nextToken(JspLexer.java:1820)
at weblogic.servlet.jsp.JspLexer.parse(JspLexer.java:963)
at weblogic.servlet.jsp.JspParser.doit(JspParser.java:106)
at weblogic.servlet.jsp.JspParser.parse(JspParser.java:234)
at weblogic.servlet.jsp.Jsp2Java.outputs(Jsp2Java.java:125)

这个问题是WebLogic Servlet容器没有意识到Hibernate用户对ANTLR的版本需求:

1) 在老的Antlr 2.7.1中,WebLogic的Servlet容器使用antlr.CharScanner通过下面的方法  Class.forName(String className) 加 载token,因为jsp编译的classes本身是基于WebLogic系统Classloader,于是,Classloader当然使用 WebLogic的Antlr版本(2.7.1),WebLogic没有被Hibernate的Antlr(2.7.6)所影 响,Class.forName转型成System CL所规约的 antlr.CommonToken不会有问题。

2) 而 当WebLogic Antlr 2.7.1+Hibernate Antlr2.7.6一起使用的时候,Servlet容器在CharScanner使用 Class.forName(String, boolean, ClassLoader)去加载token,而第三个参数是注入了当前的应用的Classloader,即WebLogic被迫使用了Hibernate 的Antlr 2.7.6,而最终会导致容器在将Antlr 2.7.6的 CommonToken转型成Antlr 2.7.1的CommonToken出现java.lang.ClassCastException。

 

这种情况,只能做两件事情:

1)向BEA索取此Case的补丁

2)前置System ClassPath,让新版本的Antlr永远放在前面。

 

讲述了这么多东西,其实,最终想揭示的问题是,无论是Hibernate和 WebLogic,在一开始的时候都没有意识到开源代码重构的重要性。早期的WebLogic确实已经XML Parser付出版本冲突的代价,所以后期,很多XML包都被WebLogic重新Rename Package(重构代码的一种方式)。 如果一开始,WebLogic就使用com.bea.opensource.antlr来让自己的容器使用Antlr,ANTLR冲突的这些问题肯定不会出现。

 

WebLogic 10确实开始大规模重构Jar包,不幸的是,这个世界上有一种潜规则叫做向后兼容,所以,<prefer-web-inf-classes>true</prefer-web-inf-classes>是我们J2EE初级阶段仍然需要接受的现实,当然,你可以期待另外一种技术解决此问题——OSGI,事实上,这个版本可能比我们想象的要快,或者就在WebLogic 12g。

本文转载自:http://www.blogjava.net/security/archive/2008/07/04/weblogic_hibernate_antlr_conflict.html

共有 人打赏支持
山海经
粉丝 32
博文 159
码字总数 40723
作品 0
广州
程序员
Hibernate连接Weblogic的数据源

因为前两天,发了关于hibernate配置多数据库连接和选择什么服务器方案的缘故,有的朋友就动了心眼儿。。呵呵,想把程序跑在weblogic上,结果接着一连串的问题都出来了, 应几个朋友的需求,要...

寒冰蓝血
2012/07/06
0
0
Suse 系统下 Weblogic12C 安装整合部署 Hibernate + Spring ...

Suse 系统下 Weblogic12C 安装整合部署 关于Weblogic12的安装以及部署,请参照WebLogic安装手册.pdf 由于公司客户需要,现在需要移植现成的银行系统到weblogic上部署,发现原来在tomcat上好好...

Deng小尧
2012/06/06
0
0
解决Weblogic与Hibernate的jar冲突

项目运行的时候,提示找不到org.hibernate.hql.ast.HqlToken这个类,可我jar包明明有啊,上网一搜,原来是Weblogic11已经带了antlr,所以没有用到了hibernate3相关的antlr-2.7.5H3.jar包,所...

山海经
2014/09/03
0
0
weblogic 服务启动报错|weblogic 包加载与冲突等问题

问题1(org.apache.commons.lang.ClassUtils.getClass) ? 解决办法 在WEB-INF文件夹下,加上weblogic.xml,让WebLogic 10先引用WEB-INF下面的jar,内容如下: ? 问题原因说明 http://hi.baid...

lqlm
07/10
0
0
Weblogic10.3项目部署出错的一些常见问题分析

1、在安装完成weblogic之后,我们需要把hibernate框架使用的一个jar包(antlr-2.7.6rc1.jar)放到weblogic的安装目录里。具体路径为D:beawlserver_10.3commonlib。 如果我们还不能够解决冲突...

java梦想家01
2015/04/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

no such module 'pop'问题

在github上 clone 了一个 swift 项目,编译时提示"no such module 'POP'"错误,查了一下居然是因为podfile中指定的最低版本是iOS 11.0,大于我测试手机的iOS版本10.3.3,将Podfile中的最低版...

yoyoso
38分钟前
1
0
redis 系列一 -- 简介及安装

1.简介 redis -- remote dictionary server 远程字典服务 使用 C 语言编写; 高性能的 key-value数据库; 内存数据库,支持数据持久化。 Redis 是一个开源(BSD许可)的,内存中的数据结构存...

imbiao
今天
3
0
nginx log记录请求响应时间

有时为了方便分析接口性能等,需要记录请求的时长,通过修改nginx的日志格式可以做到,如 添加一个新的log_format log_format timed_combined '$remote_addr - $remote_user [$time_local] "...

swingcoder
今天
4
0
Spring MVC之RequestMappingHandlerMapping匹配

对于RequestMappingHandlerMapping,使用Spring的同学基本都不会陌生,该类的作用有两个: 通过request查找对应的HandlerMethod,即当前request具体是由Controller中的哪个方法进行处理; 查...

爱宝贝丶
今天
3
0
Java Web--增删改查之二界面后台java代码(转载参考)

/** *  *//** * @author Administrator * */package dao; import java.sql.*;public class DBConn {/** * 链接数据库 * @return */  ...

小橙子的曼曼
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部