`

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

阅读更多

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。

分享到:
评论
2 楼 一别梦心 2012-11-05  
你好,我也遇到此问题了。就你贴的那段代码,你说了两种解决方式,
1)向BEA索取此Case的补丁
2)前置System ClassPath,让新版本的Antlr永远放在前面。
能说的再清楚点吗,有点不太明白,非常感谢!

1 楼 sh_xuzhiqiang 2010-10-25  
你说的不无道理,但我看了你的贴子,我有个新想法,就是吧Antlr(2.7.6).jar 的包里面的antlr文件夹中的文件复制到weblogic.jar的 antlr中去,问题就解决了。
只针对weblogic8.x hibernate3.0 解决方法。

相关推荐

    Hibernate的Antlr在Weblogic中产生Jar冲突的解决办法

    ### Hibernate的Antlr在Weblogic中产生Jar冲突的解决办法 #### 背景与问题描述 在使用Hibernate框架进行Java应用开发时,特别是在Weblogic服务器环境下部署应用程序时,可能会遇到一个常见问题:由于不同版本的...

    weblogic10 与hibernate冲突解决方案 linux windows环境全解

    weblogic10 与hibernate冲突解决方案 错误如下:org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken linux windows 环境解决方案全解 Linux 启动脚本添加如下: export USER_...

    struts2 sping hibernate 部署到weblogic8.1.6上所需要jar包

    在部署Struts2、Spring与Hibernate到WebLogic 8.1.6服务器的过程中,经常会遇到兼容性问题。本文将详细阐述所需JAR包的具体情况及其配置步骤,帮助开发者顺利完成部署。 ### Struts2、Spring与Hibernate部署至...

    antlr.jar-2.7.6

    总结来说,ANTLR.jar-2.7.6是ANTLR库的一个版本,它在Java开发中,特别是在Hibernate3这样的ORM框架中,作为解析和生成SQL查询的关键组件。通过使用ANTLR,开发者可以更高效地处理语言和配置文件解析,提升项目开发...

    weblogic12 下 org.hibernate.hql.ast.HqlToken

    2. **调整类路径**:将冲突的库文件(例如ANTLR-2.7.6.jar)放置到一个专门的目录中,例如在示例中提到的`/opt/Oracle/Middleware/test/`目录下,并确保其路径被正确地添加到WebLogic的启动参数中。 3. **修改启动...

    sunone8.1到weblogic10.3转移配置

    从Sun ONE 8.1迁移到WebLogic 10.3的过程中,需要注意解决Hibernate配置问题以及ANTLR版本冲突等问题。通过上述步骤,可以有效地解决这些挑战,确保应用程序能够在新的WebLogic环境下顺利运行。在实际操作中还需要...

    SSH项目部署在window和linux下的Weblogic上出现 ClassNotFound异常解决办法

    经过初步排查发现,这一问题可能与Hibernate框架中所依赖的`antlr.jar`文件与WebLogic自带的jar包存在冲突有关。虽然在网上搜索了许多资料,但并未找到可行的解决方案。最终通过一份由前同事提供的资料,明确了问题...

    weblogic与hibernate

    使用的Hibernate是3.0之后的版本,而从3.0开始就采用了新的基于ANTLR的查询翻译器,在WebLogic中使用的是antlr2.6.1.jar,无法满足该要求,需要从新版本的Hibernate中提取该jar并添加到WebLogic的Classpath中。

    Linux 下整合 weblogic12c jsf1.2 Hibernate3

    - 修改 `${DOMAIN_HOME}/bin/startWeblogic.sh` 文件,在 `CLASSPATH` 变量中加入新版本的 `antlr-2.7.6.jar`。 2. **启动 WebLogic 服务**: - 修改后的 `startWeblogic.sh` 文件应包含如下内容: ```bash WEB...

    在 Weblogic 8.1上配置 Hibernate 3.0

    - **放置位置**:将所有必需的库文件(如`hibernate.jar`以及任何第三方库)放置在应用程序的`APP-INF/lib`文件夹中。 - **目的**:这样放置库文件是为了确保在应用程序部署时,所有必需的库都能被正确加载和使用。 ...

    Extjs3.2+struts2.0+spring2.5+hibernate3.5+weblogic10+oracle10g含全包5

    proxool_cofig.xml为连接池配置 此项目可做基础项目开发原型方便,启动此项目在weblogic10中会有antlr-2.7.6rc1.jar此包的异常请配置其先加载并将次包考入 bea\wlserver_10.0\server\lib目录下,再将bea\user_projects...

    Tomcate移植到webLogic问题及解决方法

    通过以上步骤,可以有效地解决Hibernate3和jomi与WebLogic之间的类加载冲突问题,确保应用程序在WebLogic环境下稳定运行。需要注意的是,除了上述提到的具体问题外,还可能存在其他兼容性问题,如JSP引擎差异、JNDI...

    antlr-2.7.6rc1.jar

    解决weblogic抛出的ClassNotFoundException: org.hibernate.hql.ast.HqlToken异常

    Windows 下整合 weblogic10 jsf1.2 hibernate3

    - **关于 Hibernate 3 的依赖管理**:在 WebLogic 10.3 的环境中,需要特别注意 Antlr 的版本及其与其他库的兼容性问题。 总结来说,在 Windows 环境下整合 WebLogic 10、JSF 1.2 和 Hibernate 3 需要注意的技术...

    weblogic10.3 使用

    ### WebLogic 10.3 使用详解 #### 一、WebLogic 10.3 安装步骤 在正式开始WebLogic 10.3 的使用...通过以上步骤,可以有效解决Spring + Hibernate3在WebLogic 10.3环境中出现的异常问题,确保开发工作的顺利进行。

    WebLogic的安装与使用

    #### 六、在Hibernate中使用WebLogic的数据源 1. **更新Hibernate配置**: - 移除原有的数据库连接配置。 - 添加对数据源的引用配置:`&lt;property name="hibernate.connection.datasource"&gt;MySqlDs&lt;/property&gt;`。 ...

    weblogic安装配置及项目部署

    特别是对于描述中提到的问题,如Hibernate查询错误,可能需要检查命名查询的定义,并确保所有依赖项(如antlr-2.7.6.jar)已正确添加到类路径中。如果遇到`HibernateException`,检查配置文件,确保JNDI查找设置正确...

    Weblogic项目部署文档

    - **解决方案**: 将`antlr-2.7.6.jar`文件添加到`bea\wlserver_10.3\server\lib`目录,并调整`startWebLogic.cmd`文件中的`CLASSPATH`环境变量顺序。 - **步骤四**: 配置Weblogic运行模式。 - **操作**: 安装...

Global site tag (gtag.js) - Google Analytics