有个spring-boot项目需要用到spoon对java项目代码进行解析,从而获取一些信息。实际开发过程中,发现使用mvn spring-boot:run能够正常运行,但打成包之后,使用java -jar能够启动项目,但部分文件无法解析。

出错代码

使用的是官方示例,修改的代码。

public static void parse(String code){
	CtClass classContent = Launcher.parseClass(code);
	classContent.getAnnotations().stream().forEach(a ->{
		//do somthing;
	});
}

项目中需要解析代码中的注解。发现使用java -jar运行时,某些通过.*导入的注解会出现解析失败。该项通过,在源代码中二次显式导入需要解析的注解解决。但之后又发现注解参数中使用的导入的枚举类型也会报错。

解决方案

mvn spring-boot:runjava -jar最大的区别是classpath。出现这种错误是因为,Launcher.parseClass(code)没有正确导入依赖。修改源代码parseClass方法,手动注入需要解析的注解所在的包。

    public static CtClass<?> customParseClass(String code) {
		Launcher launcher = new Launcher();
		launcher.addInputResource(new VirtualFile(code));
		//
		launcher.getEnvironment().setSourceClasspath(new String[]{"target/example-project/WEB-INF/lib/需要解析注解所在的包.RELEASE.jar"});
		launcher.getEnvironment().setAutoImports(true);
		Collection<CtType<?>> allTypes = launcher.buildModel().getAllTypes();
		if (allTypes.size() != 1) {
			throw new SpoonException("parseClass only considers one class. Please consider using a Launcher object for more advanced usage.");
		}
		try {
			return (CtClass<?>) allTypes.stream().findFirst().get();
		} catch (ClassCastException e) {
			throw new SpoonException("parseClass only considers classes (and not interfaces and enums). Please consider using a Launcher object for more advanced usage.");
		}
	}

打包成docker 镜像时,将依赖包也放到相对路径下。

03-31 01:17