springboot+enjoy解决ClassNotFound问题

项目架构:springboot+enjoy

问题描述:springboot项目打成jar包部署运行后,enjoy模板中涉及到静态属性访问的页面会报错:ClassNotFoundException。但是在IDE中开发调试时完全没问题。

问题分析:其实不光enjoy模板中出现这个问题,我们发现springboot打成jar包后,所有用到Class.forName的地方都会报这个错,所以当时就考虑到enjoy模板这个报错应该也是这个问题导致的,因为后台肯定会根据类名称去寻找这个类,势必会用到Class.forName方法。然后去gitee下载了enjoy的最新源代码,通过全局搜索,确实查到了有两处使用到了Class.forName。

001.png

在此之前我们已经找到了应对方案来处理这个问题,就是使用hutool的类加载工具:ClassLoaderUtil.loadClass(className)。使用这个工具去获取类,在springboot打包后也能正常运行。在早期hutool版本中其实也是不支持的,我们还查到了有用户给hutool作者提了这个问题,当时作者的回复是在springboot中暂时无解。但是后续的hutool版本似乎完美解决了这个问题。帖子链接:https://gitee.com/loolly/hutool/issues/IKDJW

image.png

然后两个月后:

image.png

问题解决:修改上面搜到的两处使用Class.forName的代码段,换成hutool的方法,然后重新打包。

public StaticField(String className, String fieldName, Location location) {
	try {
		//this.clazz = Class.forName(className);
		//使用hutool工具加载类,解决springboot打包后找不到类的问题
		this.clazz = ClassLoaderUtil.loadClass(className);
		this.fieldName = fieldName;
		this.field = clazz.getField(fieldName);
		this.location = location;
	} catch (Exception e) {
		throw new ParseException(e.getMessage(), location, e);
	}
}

写在最后:springboot刚没用多久,如果有更好的方案,请广大码友不吝赐教。

评论区

JFinal

2019-05-21 20:58

ClassLoaderUtil.loadClass(...) 内部是怎么操作的? 这个才是解决问题的关键

感谢分享

JFinal

2019-05-21 20:59

springboot 之下可能是要用到特定的 class loader,或许 springboot 提供了工具类来获取这个 class loader

Sohnny

2019-05-21 22:23

SoJpt Boot 完全没这个问题, 还可像JFInal Undertow一样快速打包部署

happyboy

2019-05-21 23:16

@Sohnny 现在各种boot真的是眼花缭乱,话说官网是不是该改版了,O(∩_∩)O哈哈~

Sohnny

2019-05-22 07:56

@happyboy 也就是起了名字,官网在club的基础上改了改配色