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

本文探讨了Hibernate和WebLogic因使用相同版本的Antlr而导致的Jar冲突问题,并提出了解决方案,包括调整WebLogic的配置及ClassPath设置。

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。
讲述了这么多东西,其实,最终想揭示的问题是,无论是Hibernate和WebLogic,在一开始的时候都没有意识到开源代码重构的重要性。早期的 WebLogic确实已经XML Parser付出版本冲突的代价,所以后期,很多XML包都被WebLogic重新Rename Package(重构代码的一种方式)。 如果一开始,WebLogic就使用com.bea.opensource.antlr来让自己的容器使用Antlr,ANTLR冲突的这些问题肯定不会出现。
解决方法:
修改% mydomain% \ startWebLogic.cmd :
在set CLASSPATH之前加上下面一句:
set PRE_CLASSPATH=%WL_HOME%\server\lib\antlr-2.7.5H3.jar;
在set CLASSPATH之后加上下面一句:
set CLASSPATH=%PRE_CLASSPATH%;%CLASSPATH%
一切OK!
1 2/3维图像分割工具箱2 PSORT粒子群优化工具箱3 matlab计量工具箱Lesage4 MatCont7p15 matlab模糊逻辑工具箱函数6 医学图像处理工具箱7 人工蜂群工具箱8 MPT3安装包9 drEEM toolbox10 DOMFluor Toolbox v1.711 Matlab数学建模工具箱12 马尔可夫决策过程(MDP)工具箱MDPtoolbox13 国立SVM工具箱14 模式识别与机器学习工具箱15 ttsbox1.1语音合成工具箱16 分数阶傅里叶变换的程序FRFT17 魔方模拟器与规划求解18 隐马尔可夫模型工具箱 HMM19 图理论工具箱GrTheory20 自由曲线拟合工具箱ezyfit21 分形维数计算工具箱FracLab 2.222 For-Each23 PlotPub24 Sheffield大学最新遗传算法工具箱25 Camera Calibration 像机标定工具箱26 Qhull(二维三维三角分解、泰森图)凸包工具箱 2019版27 jplv728 MatlabFns29 张量工具箱Tensor Toolbox30 海洋要素计算工具箱seawater31 地图工具箱m_map32 othercolor配色工具包33 Matlab数学建模工具箱34 元胞自动机35 量子波函数演示工具箱36 图像局域特征匹配工具箱37 图像分割graphcut工具箱38 NSGA-II工具箱39 chinamap中国地图数据工具箱(大陆地区)40 2D GaussFit高斯拟合工具箱41 dijkstra最小成本路径算法42 多维数据快速矩阵乘法43 约束粒子群优化算法44 脑MRI肿瘤的检测与分类45 Matlab数值分析算法程序46 matlab车牌识别完整程序47 机器人工具箱robot-10.3.148 cvx凸优化处理工具箱49 hctsa时间序列分析工具箱50 神经科学工具箱Psychtoolbox-3-PTB51 地震数据处理工具CREWES1990版52 经济最优化工具箱CompEcon53 基于约束的重构分析工具箱Cobratoolbox54 Schwarz-Christoffel Toolbox55 Gibbs-SeaWater (GSW)海洋学工具箱56 光声仿真工具箱K-Wave-toolbox-1.2.157 语音处理工具箱Sap-Voicebox58 贝叶斯网工具箱Bayes Net Toolbox(BNT)59 计算机视觉工具箱VFfeat-0.9.2160 全向相机校准工具箱OCamCalib_v3.061 心理物理学数据分析工具箱Palamedes1_10_362 生理学研究工具箱EEGLAB63 磁共振成像处理工具箱CONN 18b64 matlab 复杂网络工具箱65 聚类分析工具箱FuzzyClusteringToolbox66 遗传规划matlab工具箱67 粒子群优化工具箱68 数字图像处理工具箱DIPUM Toolbax V1.1.369 遗传算法工具箱70 鱼群算法工具箱OptimizedAFSAr71 蚁群算法工具箱72 matlab优化工具箱73 数据包络分析工具箱74 图像分割质量评估工具包75 相关向量机工具箱76 音频处理工具箱77 nurbs工具箱78 Nurbs-surface工具箱79 grabit数据提取工具箱80 量子信息工具箱QLib81 DYNAMO工具箱82 NEDC循环的整车油耗量83 PlotHub工具箱84 MvCAT_Ver02.0185 Regularization Tools Version 4.186 MatrixVB 4.5(含注册)87 空间几何工具箱 matGeom-1.2.288 大数计算工具箱 VariablePrecisionIntegers89 晶体织构分析工具包 mtex-5.7.090 Minimal Paths 2工具箱91 Matlab数学建模工具箱
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值