jfinal-undertow部署时class文件加载问题

请教一下,jfinal undertow部署的时候,能不能设置一个classes文件夹,类似tomcat的WEB-INF/classes文件夹,放进去的class文件能优先加载。

或者能调整jar的加载优先级也行。

问题来源是这样的,现在做的一个小系统,里面有几个对第三方jar包内class的自定义修改,本地开发运行时能被优先加载没有问题,但是打包部署时,自己项目的class都打包进了一个jar并且和第三方jar一起在lib文件下,加载顺序无法控制,导致都加载的原来jar里面的class程序出错。

评论区

JFinal

2019-10-15 12:39

大致按照如下步骤解决:
1:下载首页的 jfinal_demo_for_maven.zip 这个 demo

2:拿到里头的 package.xml

3:在 package.xml 中的 fileSets 标签下面添加 fileSet 子标签,配置将 target/classes 下的文件复制到被部署的 classes 目录下面,大至如下:
《fileSet》
《directory》${basedir}/target/classes《/directory》
《outputDirectory》classes《/outputDirectory》
《/fileSet》

4:修改 package.xml 中的 dependencySets 标签,添加 excluded 标签过滤掉对项目自身 jar 包的复制,大致如下:
《excludes》
《!-- **/* 前缀用法,可以匹配所有路径,例如:**/*.txt --》
《exclude》my-project.jar《/exclude》
《/excludes》

5:修改 jfinal.sh 启动文件,在 -cp 参数中添加 classes 目录,指向你自己新建的目录,大致如下:
CP=${APP_BASE_PATH}/classes:${APP_BASE_PATH}/config:${APP_BASE_PATH}/lib/*

JFinal

2019-10-15 12:44

最后,分别解释一下上面的各个步骤:
1:第一步拿到 demo 可获取 package.xml、pom.xml、jfinal.sh 这三个用于开发、部署的配置

2:第二步,不用解释

3:第三步本质就是在原有项目部署的结构之上,再多复制一个 target/classes 到部署项目的根下面的 classes 下面。当然这个目录的名称你可以随便改,不一定是 classes

4:第四步本质就是避免将项目本身 .class 文件打成的 jar 包复制到 lib 目录下面,因为你希望是使用 classes 目录下面的 .class 文件,而不是使用 jar 内的 .class 文件。

为了避免可能造成的冲突,所以第四步中添加了 excludes 来地滤那一个 jar 包, 具体的 jar 包名你要写正确,以免过滤不到,jar 包可能带有版本号,所以可能需要使用通配符来匹配,例如:
《exclude》my-project*.jar《/exclude》

5:第五步是改变启动脚本,将部署时创建的那个 classes 目录包含进 CP 参数,好让项目在启动的时候能够去该目录下面寻找资源,CP 是 CLASSPATH 的缩写

vigo

2019-10-15 14:20

@JFinal 老大回复真迅速,谢谢,我马上试试

vigo

2019-10-15 14:39

@JFinal 感觉大佬指点,我这边的需要搞定了。
现在采用的是直接只使用第5步,只改启动文件的CP配置,把自定义的classes目录放在前面。其他都按照jfinal_demo_for_maven的不变,项目jar包依然打,只把自己与第三方jar包冲突的class放入配置的classes目录里面(添加完整包路径)即可优先加载自定义classes目录的class文件。
谢谢

JFinal

2019-10-15 16:08

@vigo 如果你的 .class 文件是额外放置的,的确只需要修改主启动的 CP 配置

这里要注意一个问题,classes 目录下与 jar 包内存在同名的类的时候,jar 包内的会被加载,而 classes 目录下面的同名类将会被忽略

chcode

2019-10-15 16:41

@JFinal cp的多个路径 配置顺序 会影响加载类的优先级吗?

JFinal

2019-10-15 17:07

@chcode 应该不会影响

vigo

2019-10-16 09:28

@JFinal 我这边刚刚测试的结果好像可以通过CP配置指定类加载优先级。
测试过程:我重写的shiro中的一个类,shiro的jar中的class没有删除,我自己项目打包出来的jar里面的同名类也打进去了,然后添加了一个编译好的class到CP配置的classes目录下。
测试出来的结果:
win10开发电脑运行bat:CP不指定classes目录或者CP配置的时候将${APP_BASE_PATH}/classes:放在lib后面,加载的是项目打包出来的my-project.jar中的class;CP指定classes并放在CP的最前面时,加载的是放置在classes文件夹中的class。
CentOS7运行sh:CP不指定classes目录或者CP配置的时候将${APP_BASE_PATH}/classes:放在lib后面,加载的是shiro-core.jar中的class;CP指定classes并放在CP的最前面时,加载的是放置在classes文件夹中的class。

chcode

2019-10-16 09:40

@vigo 我之前的测试好像也和你一样

天晴

2024-04-01 20:59

测试了一下:
使用
set CP=%APP_BASE_PATH%config;%APP_BASE_PATH%lib\*;%APP_BASE_PATH%classes
会报错:
java.lang.ClassCastException: com.xir.xverse.core.XVerseConfig cannot be cast to com.jfinal.config.JFinalConfig

改为:
set CP=%APP_BASE_PATH%config;%APP_BASE_PATH%lib\*;%APP_BASE_PATH%classbean
则可以正常运行

是因为classes比较特殊么?

热门反馈

扫码入社