Spoon Inria在Docker与本地Spring Boot环境下CtExecutableReference类型解析异常
问题根因
- 你的Spoon配置默认开启了
noclasspath=true模式,该模式下Spoon仅基于输入的源代码做类型推断,无法读取外部依赖的类定义 - 出现null的
findAll是Spring Data JPA父接口JpaRepository自带的方法,没有显式定义在你自己编写的Repository接口中:如果Spoon无法获取到父接口的类定义,就无法推断该方法的返回类型,导致getType()、getDeclaredType()返回null - 本地运行正常的原因是IDE环境下,Spoon运行上下文的类加载器可以直接读取到项目依赖的Spring Data相关类;而Docker中运行的是Spring Boot可执行JAR,默认使用
LaunchedURLClassLoader加载BOOT-INF/lib下的依赖类,Spoon默认的类加载器无法识别该结构,找不到依赖类导致类型推断失败 - 自定义的
findByCustomerId方法是你显式声明在自己的Repository接口中的,Spoon从输入的源代码中就能直接读取方法定义,所以不受外部依赖缺失的影响
解决步骤
方案一:关闭noclasspath模式,显式配置类加载路径
- 初始化Spoon Launcher后,先关闭noclasspath模式,配置使用当前线程的上下文类加载器(Spring Boot启动后上下文类加载器可正确加载内部依赖):
Launcher spoonAPI = new Launcher(); // 新增配置 spoonAPI.getEnvironment().setNoClasspath(false); Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); // 原有逻辑 spoonAPI.addInputResource(...)
- 如上述配置无效,可以显式把当前应用的classpath传给Spoon:
String classpath = System.getProperty("java.class.path"); spoonAPI.getEnvironment().setSourceClasspath(classpath.split(File.pathSeparator));
方案二:保留noclasspath模式,补充输入资源
如果必须使用noclasspath模式,将Spring Data Common、Spring Data JPA等包含Repository父接口定义的源码,和目标项目源码一起作为输入资源传给Spoon,让Spoon可以直接从源码中读取findAll等继承方法的定义。
验证方法
你可以将Spoon的日志级别调整为DEBUG,在Docker环境中运行时查看是否存在找不到类定义相关的警告,确认是依赖类缺失导致的问题。
内容的提问来源于stack exchange,提问作者Kadnikov Sergey
相关产品推荐
相关产品推荐

