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

本文探讨了Hibernate与WebLogic在使用ANTLR时遇到的版本冲突问题,详细介绍了冲突产生的原因及解决方案,包括配置weblogic.xml文件和使用不同版本的ANTLR。
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
标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则和常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化改进根据测试结果对系统进行优化和改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策和风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理和建模功能。它简化了数据清洗、特征提取、模型构建、验证优化等流程,是数据科学项目中的常用工具。 三、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建验证 借助Sklearn,可以将数据集划分为训练集和测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差方差,增强整体预测的稳定性准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值