`
dechong
  • 浏览: 16755 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate的Antlr.jar与weblogic.jar冲突:ClassNotFoundException: org.hibernate.hql.ast

阅读更多
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
分享到:
评论
1 楼 xcc313 2011-10-12  
解决我的问题了,

相关推荐

    weblogic12 下 org.hibernate.hql.ast.HqlToken

    在WebLogic 12环境中部署应用程序时,如果应用依赖于特定版本的Hibernate框架,并且该版本与WebLogic服务器默认提供的Hibernate版本存在差异,则可能会导致`org.hibernate.hql.ast.HqlToken`类冲突。此类冲突主要...

    判断编码格式.rar antlr.jar chardet.jar cpdetector_1.0.5.jar

    它包含的三个文件“antlr.jar”,“chardet.jar”,以及“cpdetector_1.0.5.jar”都是与字符编码检测相关的Java库。 1. **ANTLR.jar**: ANTLR (ANother Tool for Language Recognition) 是一个强大的解析器生成器,...

    antlr.rar_DWA_antlr.BLK_antlr.jar

    在给定的压缩包“antlr.rar”中,包含三个关键文件:“DWA_antlr.BLK”,“antlr.BLK”,以及“antlr.jar”。让我们逐一了解这些文件的作用: 1. **DWA_antlr.BLK**:这个名字可能是某种特定格式的文件,但具体用途...

    hibernate3用的 antlr.jar

    hibernate3用到的antlr.jar,语法分析生成器.

    ant-antlr.jar

    ant-antlr.jar

    ant-antlr.jar.zip

    在"ant-antlr.jar.zip"中,"ant-antlr.jar"这个库包含了ANTLR的相关类和方法,使得Ant能够方便地与ANTLR集成,进行复杂的语法分析任务。 "ant.license.txt"文件通常包含了Ant的许可协议信息,这对于开源软件的使用...

    antlr.jar

    antlr.jar antlr.jar

    antlr-2.7.7.jar.zip

    这个"antlr-2.7.7.jar.zip"文件是ANTLR的一个特定版本——2.7.7的Java版本,包含ANTLR库的jar文件。 ANTLR的工作原理基于上下文无关语法(Context-Free Grammar,CFG),它可以解析符合给定语法的输入,并生成抽象...

    antlr.jar.zip

    描述"antlr.jar"直接指出了这个压缩包解压后的主要内容——ANTLR的Java实现,即一个名为"antlr.jar"的文件。这个JAR文件包含了ANTLR解析器生成器的全部Java代码,开发者可以将其引入到Java项目中,利用ANTLR的能力来...

    antlr-2.7.7.jar和antlr-2.7.6.jar

    总之,ANTLR是构建解析器的强大工具,而antlr-2.7.7.jar和antlr-2.7.6.jar是ANTLR的不同版本,它们以JAR文件的形式提供,用于Java项目中解析和处理结构化文本。选择使用哪个版本应根据项目的需求、兼容性和稳定性来...

    dao-hibernate.jar

    dao-hibernate.jardao-hibernate.jardao-hibernate.jardao-hibernate.jardao-hibernate.jar

    antlr-2.7.6.jar,cpdetector_1.0.10.jar,chardet.jar下载,IO流相关Jar包

    ANTLR 2.7.6.jar是ANTLR的一个版本,它包含了ANTLR工具运行所需的类库,可以用来生成Java源代码,用于解析特定的语法。 CPDetector(Class Path Detector)是1.0.10版本的jar包,这是一个用于检测Java类路径中的...

    antlr.jar包

    antlr包,希望能够给大伙提供帮助,哈哈哈哈哈哈!!!!

    antlr.jar和json.jar

    2. **语法分析**:然后ANTLR使用语法分析器对词法单元进行解析,生成抽象语法树(AST)。这一步骤允许我们以结构化的方式理解输入文本。 3. **访问控制**:ANTLR生成的解析器可以实现复杂的访问控制策略,如权限...

    antlr.jar-2.7.6

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

    antlr chardet cpdetector jar包

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于各种编程语言的编译器和解释器的构建,它能生成Java、C#、Python...

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

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

    antlr-2.7.2.jar.zip

    在Java项目中,通常通过`java -cp antlr-2.7.2.jar org.antlr.Tool`命令行来运行ANTLR工具。 “antlr.LICENSE.txt”文件则包含了ANTLR的许可协议,这通常是软件开源许可证,如BSD、MIT、Apache等,它规定了用户如何...

    antlr.jar 包EJB

    EJB+JPA开发必须的包,有需要的就拿去,一般在Jboss的Client目录下能找的到

    hibernate3所需完整jar包

    压缩包内包含antlr-2.7.6.jar、commons-collections-3.1.jar、commons-logging-1.1.3.jar、dom4j-1.6.1.jar、ejb3-persistence.jar、hibernate3.jar、hibernate-jpa-2.0-api-1.0.1.Final.jar、javassist-3.12.0.GA....

Global site tag (gtag.js) - Google Analytics