我无比艰难的Java技术更新之旅

最近这一个月成为我这几年来最忙最累最绝望的日子,身为一个不太熟悉Java的人需要完成以下的应用软件升级工作:

1. Java 从 8 到 Java 17

2. Spring 从 3 到 5

3. Hibernate 从 3 到 5

4. Genesys Voice Platform Call Flow 从 8.1.2 到 8.1.5

5. 其他用到的模块比如log4j, common-cli, sqljdbc, 等等

6. IBM MQ Client 7 到 9

人就是这样,越不熟悉的,就越不想做,前两年做了一次技术更新,就想着以后再也不要做了。所以这次任务来了,第一反应是推掉,之前有个修改请求就成功地推给外包了。这次技术更新任务估算推给了外包,想着万一要真正做也是可以找他来做。可是到了任务真正下来的时候,跟老板一商量,不打算给外包,手头上也没有Java程序员,真是怕什么来什么,还得自己这个菜鸟上,于是乎艰难而绝望的日子就开始了。

任务当然从升级Java开始,一上了Java17,jaxb和jaxws就出现了编译错误。虽然不知道这两个是啥玩意,就按照名字下载,加入了编译没问题了。

想着hibernate和Spring是大头,先升级其他的,下载了其他模块的更新版本,一切都还算顺利,想着到hibernate和Spring的时候不也这样嘛,下载新的类库,一编译成功,那不就得了。

到了hibernate和Spring的时候,情况完全不是这么回事,各种编译错误,看不懂就按照名字找类库加上,排除了所有的编译错误之后,上JBoss遇到大问题了,总说不行,就是上下文载入不了,死活载入不了,不知道啥原因,这样试,那样试,啥办法都想了,啥库都往里面加,跟个无头苍蝇似的,还是不行啊,就是不行啊。

在网上找了找,人家也说升级的时候最好一步一步来,从3到4再到5。既然自己的猜想的方法不管用,就应该用最基本的方法来。首先把一切还原到最初的Spring3和hibernate3,JBoss里面跑起来没问题。考虑到Spring应该是主导,并且向下兼容,就先升级到4,升级的方法也改变了,不能按照原有版本的文件名找相应的升级文件,应该下载全套的,比如Spring4全套有哪些文件,先全部下载全部加上,没问题。所以就采用了下面的升级路径:

Spring4和Hibernate3 - 没问题

Spring4和Hibernate4 - 没问题

Spring4和Hibernate5 - 没问题

Spring5和Hibernate5 - 没问题

这两个组件都采用全套的文件,所以打包完了之后只是有个别的一些数据库的操作做一点小的改动,编译成功,并且也能运行在JBoss里面,当时信心大增,很受鼓舞,以为最难的事情搞定了。

那天突然想起来,我们还有在Tomcat上面用Java写的Call Flow也需要升级啊,这就傻眼了,我哪会Call Flow啊,导入相应的项目文件,根本不能打包,不识别,需要加载GVP本身的外接件,也试了好半天,怎么也加不进去,后来摸索到了Eclipse加入外接件的方法,成功地安装上了,Call Flow能看见了,但是不能打包啊,源文件版本太低,需要升级。我尝试升级了,根本不行,Genesys的人跟我说不能直接升级必须按照下面的方法来升级:

8.1.2 到 8.1.3 - 这个版本只有Windows 8上面做

8.1.3 到 8.1.4

8.1.4 到 8.1.5

最后完成了升级,看到log4j 成功地被转换到log4j2我还是挺开心的,毕竟自己手动做会有很多麻烦。

上面的升级过程,只有JBoss是有真正跑了Runtime的测试,其他的只在打包阶段而已。到了真正的目标环境上面问题就很大了,Call Flow倒还好,两个打入的,一个打出的,都还调试得顺顺利利的,acknowledge和电话录音都好着呢,电话通知的也可以激活。

JBoss的Runtime测试是做过了,我忘记还有命令行的一个程序,这个一跑起来完全不是这么回事,到了Java17完全跑不了,各种错误,显示一些自己都不认识的类名,程序里面也没看到用的,就是没有。那天我使用各种方法,就是不行,周四晚上做到12点,灰溜溜地回家了,跟项目经理说,明天你等我的消息,搞得定我就让你来测试,不能你就别来。

一开始跑的时候出各种类库找不到的问题,手动加入了下面两个类库:

- jboss-logging-3.3.0.Final.jar

- jta-1.1.jar

好像还有jaxb-api和jaxb-impl之类的,加上了以后才没有出现类库不存在的错误。

这些个库在JBoss里面都不需要加载的,就是上下文初始化在JBoss和命令行是不一样的。

周五我找了一个做Java的朋友来帮我,人家也很给力,跟我进行了三次Zoom,主要的错误就是下面这个:

module java.base does not "opens java.lang" to unnamed module @746c215d

导致Error creating bean with name 'sessionFactory' defined in class path resource

网上说了,要加下面这个参数在JVM初始化的时候:

--add-opens java.base/java.lang=ALL-UNNAMED

我在Eclipse里面也加了,还是不行。后来我灵光一闪,想着Java8能不能跑,结果一切换发现可以。当时内心就有了想说服用户不进行Java版本的升级工作的想法了。因为Java8的延长支持期甚至比Java17的延长支持期更长,只是主要的支持的时间比17少两年。

关键我初始化Spring的跟Hibernate有关的Bean都是用xml的方式,我和我朋友都非常担心是因为用的方法过于传统,导致新版本不支持,可问题是我们都不知道该怎样该配置文件。我们用的是Spring orm, 我朋友用的是Spring Bot。

可问题是JBoss上面跑一点问题没有,那是怎么回事。我顺便也问我朋友jaxb是干嘛的,她说就是从xml到bean的转换。既然是Bean初始化的问题,那必定就是跟Jaxb有关,我朋友建议我使用更新一点的版本,我就找了jaxb-api和jaxb-impl更新的版本来试,还是不行。后来发现是新版旧版都有才能行,就是下面这四个文件:

- jaxb-api-2.4.0-b180830.0359.jar

- jaxb-core-4.0.0-M4.jar

- jaxb-impl-2.4.0-b180830.0438.jar

- jaxb-impl-4.0.0-M4.jar

正当我很开心地准备收工的时候,突然发现我的Hibernate的数据库操作根本是无效的,没有报错,但是数据没有插入。

一开始的时候是出现这个错误:

Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

于是我就在写数据的代码之前加了一行,以上错误就消失了:

            getHibernateTemplate().setCheckWriteOperations(false);
            getHibernateTemplate().saveOrUpdate(logEntry);

没有错误不代表没问题,我发现数据根本没有插入。于是开始在网上疯狂地找,尝试各种方法,昨天晚上做到很晚,还是没结果,后来我强迫自己4点必须睡觉,但是各种不甘心。

今天早上一起来就开始继续调试,突然JBoss跟我投诉了下面的问题,我的包无法部署:

Could not initialize class org.apache.logging.log4j.core.LoggerContext

这个问题在于log4j-api和log4j-core的不兼容性:

JBoss log4j-api 版本:log4j-api-2.14.0.redhat-00002

应用程序log4j-api版本:log4j-api-2.17.2

解决这个问题的方法是替换JBoss log4j-api的版本:

1. 把log4j-api-2.17.2.jar 拷贝到如下JBoss的路径\modules\system\layers\base\org\apache\logging\log4j\api\main

2. 修改该路径的module.xml文件中版本的内容

那个数据库的问题是这样解决的:

就是要加入下面的Spring类库:

spring-aop-5.3.18.jar

并且在Hibernate配置文件做以下修改:

文件开头要用新的名字空间:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
后面要加上

    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>    
    <tx:annotation-driven transaction-manager="transactionManager" />     
另外数据操作代码的方法前面要加:

    @Transactional
 

下周二上班,希望真正的集成测试一切顺利吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值