Java Agent中使用fastjson导致宿主应用出现找不到类的异常问题

图片来自pixabay.com的designerpoint会员

fastjson是一个目前应用广泛、高性能的Java JSON开发类库,本文记录一个在Java Agent中由于引用了fastjson,进而导致宿主应用(sprint boot)在启动过程中出现找不到类的问题。

1. 问题现象

最近在进行Java Agent的相关开发工作,某天发现在其中一个spring boot应用中报如下异常(在对宿主应用加载了Java Agent情况下),

[main] ERROR org.springframework.boot.SpringApplication 858 | Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testHttpController': Unsatisfied dependency expressed through field 'xxxHttpClientManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxHttpClientManager' defined in URL [jar:file:/xxx/xxxHttpClientManager.class]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/http/converter/GenericHttpMessageConverter

Caused by: java.lang.NoClassDefFoundError: org/springframework/http/converter/GenericHttpMessageConverter
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at com.xxx.http.client.xxxHttpClientManager.<>(xxxHttpClientManager.java:63)

若不加载Java Agent,单独启动Spring Boot应用则能够正常运行,只要加载Java Agent就会报如上错误,除此之外,日志中并无其它的特别错误报告。

通过上述日志,分析相关代码,获悉到如下的执行顺序,

  1. Spring Boot应用启动。
  2. Spring Boot应用通过BeanInitializer (spring web 5.1.x)尝试初始化Bean。
  3. Spring Boot应用注入 @Autowired testHttpController。
  4. Spring Boot应用注入 @Autowired xxxHttpClientManager。
  5. 在xxxHttpClientManager中有执行new FastJsonHttpMessageConverter,这个类来自fastjson版本1.2.x。