【问题标题】:Spring XD processor module classloader issue: ClassNotFoundExceptionSpring XD 处理器模块类加载器问题:ClassNotFoundException
【发布时间】:2015-12-08 02:56:27
【问题描述】:

我在加载 Spring XD 处理器模块类时遇到问题,想知道如何解决:

背景资料

我有一个 Spring XD 处理器模块,它在 Spring XD 容器中运行时找不到某些类。我遇到了 jaxb xml 转换和 xstream xml 转换的类加载问题,因为类加载器找不到用于转换 xml 的类。 jaxb 类在另一个 jar 文件中。 xstream 类在同一个(模块的)jar 文件中。无需任何 jaxb/xstream 代码即可轻松重现该问题(见下文)。

问题

只要下面的处理器模块代码在 Spring XD 容器中执行,类加载器就无法从模块的 jar 中找到任何类(我更改了这篇文章的包名。Foo 在同一个 jar 中的同一个包中文件。没有外部依赖项。):

// This is a spring xd processor
public class TestTransformer {

  private final Logger logger = LoggerFactory.getLogger(getClass());

  public String process(String input) {

    try {
      Class clazz = Class.forName("some.package.Foo", false, Thread.currentThread().getContextClassLoader());
      logger.info("Class: {}", clazz.toString()); // works in test
    } catch (ClassNotFoundException e) {
      // happens when deployed to spring-xd container
      logger.error(e.toString(), e);
      throw new RuntimeException(e.toString(), e);
    }
    return input;

  }
}

此代码在测试(单元测试和 Spring XD 集成测试)中有效,但在作为模块部署到 Spring XD(单节点)时失败。堆栈跟踪:

Caused by: java.lang.ClassNotFoundException: some.package.Foo
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:344)
at some.package.TestTransformer.process(TestTransformer.java:13)
... 88 more

我使用 Spring XD 1.2.0 和 1.2.1 验证了该行为。值得注意的是,处理器模块在使用反应器流时运行时没有任何类加载问题。

问题

我做错了什么,我该如何解决这个问题?

【问题讨论】:

  • 您是说 some.package.Foo 在单独的 jar 文件中,例如 foo.jar 和 foo.jar 在您模块的类路径中?即,声明为依赖项并且 lib/foo.jar 包含在您的模块 uberjar 中?如果您的问题实际上与 jaxb 或 xstream 类有关,那就另当别论了。
  • 不,这个例子中的所有类都在同一个包的同一个jar文件中。它与 jaxb 或 xstream 无关,因为我通过创建上面的示例来重现问题,删除了所有这些依赖项。

标签: spring classloader spring-xd


【解决方案1】:

听起来 Transformer 类被一个 spring-integration-core 类引用,该类由主 XD 类加载器(模块类加载器的父级)加载。所以它在模块 jar 中看不到任何类。我创建了https://jira.spring.io/browse/XD-3472。同时,解决方法是将这些类放在一个单独的 jar 中并将 jar 安装在 xd/lib 中。

【讨论】:

  • 我没有验证您的解决方案,但感谢您调查它,我认为您是对的。我通过使用带有反应器流的处理器解决了这个问题。类加载按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-29
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多