Spring XD 处理器模块类加载器问题:ClassNotFoundException

Spring XD processor module classloader issue: ClassNotFoundException

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

背景信息

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

问题

只要下面的处理器模块代码在 Spring XD 容器中执行,classloader 就无法从模块的 jar 中找到任何 classes(我更改了此 post 的包名称。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.run(URLClassLoader.java:372)
at java.net.URLClassLoader.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 验证了该行为。可能值得注意的是,在使用反应器流时,处理器模块运行时没有任何 class 加载问题。

问题

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

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