在 Arquillian 测试中难以将包添加到 Shrinkwrap 存档

Difficulty adding package to Shrinkwrap archive in Arquillian test

我正在尝试使用 shrinkwrap 将包 org.jibble.pircbot 添加到我的测试存档中。我已经尝试了所有我能想到的变体,但在所有情况下都找不到包。但是,由于某些原因,类 可以单独添加,但不会添加任何匿名内部 类。

  @Deployment
  public static WebArchive createDeployment() {
    return ShrinkWrap.create(WebArchive.class, "RcCustomerTest.war")
//      .addPackages(true, PircBot.class.getPackage())
//      .addPackages(true, "org.jibble.pircbot")
      .addClasses(PircBot.class,
        ReplyConstants.class,
        IrcException.class,
        NickAlreadyInUseException.class,
        InputThread.class,
        OutputThread.class,
        Queue.class)
      .addClass(DccManager.class) // Inner classes not added!
      .addPackages(true, "com.recursiveloop.webcommon")
      .addPackages(true, "com.recursiveloop.jloop.core.irc")
      .addAsResource("config.properties")
      .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
      .addAsWebInfResource("jboss-web.xml", "jboss-web.xml")
      .addAsWebInfResource("jboss-deployment-structure.xml", "jboss-deployment-structure.xml")
      .addAsResource("persistence.xml", "META-INF/persistence.xml")
      .setWebXML("web.xml");
  }

这导致异常

...
Caused by: java.lang.NoClassDefFoundError: org/jibble/pircbot/DccManager
        at org.jibble.pircbot.PircBot.<init>(PircBot.java:3081)
        ...

这很奇怪,因为在浏览 shrinkwrap 源代码时我发现了一个函数可以进行以下断言

Assert.assertTrue("Adding a class should also add the anonymous inner classes",
    getArchive().contains(expectedPathAnonymousInnerClass));

但遗憾的是,似乎没有测试用例真正调用这个函数。

然而,问题仍然存在——为什么当我调用 addPackages(true, "org.jibble.pircbot") 时 shrinkwrap 没有找到包?我查看生成的存档,没有 org.jibble.pircbot 的迹象,显然存在不可避免的 ClassDefNotFound 异常:

...
Caused by: java.lang.NoClassDefFoundError: Failed to link com/recursiveloop/jloop/core/irc/VisitorConnection (Module "deployment.RcCustomerTest.war:main" from Service Module Loader): org/jibble/pircbot/PircBot
...

我正在使用 gradle,但如果我使用的是 maven,则 maven 解析器可能会完成这项工作。有一个 gradle 解析器,但它做的事情并不完全相同。我使用它的最佳尝试如下

return ShrinkWrap.create(EmbeddedGradleImporter.class)
      .forProjectDirectory()
      .forTasks("integTestWar")
      .importBuildOutput("build/libs/integTest.war").as(WebArchive.class);

这将启动 gradle 任务并将测试 类 插入生成的存档中。挑战在于让 gradle 构建正确的 war 文件。我希望它包含属于集成测试源集而不是主源集的资源文件(部署描述符等),但我无法让它工作。

仅供参考,我使用的是 shrinkwrap 版本 1.2.3,这是最新的。

如有任何帮助,我们将不胜感激。

我使用 maven 解析器解决了它,如下所示:

return ShrinkWrap.create(WebArchive.class, "RcCustomerTest.war")
  .addAsLibraries(Maven.resolver()
    .loadPomFromFile("build/pom.xml")
    .resolve("pircbot:pircbot")
    .withTransitivity().asFile())

    ...

POM文件是使用gradle的eclipse插件生成的,像这样

task writeNewPom << {
  pom {
    writeTo("$buildDir/pom.xml")
  }
}

集成测试前设置为运行。

事实证明,maven 解析器可以在没有 POM 的情况下使用,但您必须在测试中指定工件并确保它与您的项目使用的内容保持同步。集成测试已经很难维护,所以最好从 POM 中解决依赖关系,这样你就知道它是正确的版本(少了一件需要担心的事情)。