在 EJB JAR 中焊接 "Enclosing method not found" 异常

Weld "Enclosing method not found" exception in an EJB JAR

将 EJB Jar 部署到启用了 CDI 的 WildFly 8.2.0(即使用最小 beans.xml 文件)会导致抛出 "Enclosing method not found" 异常。日志中没有什么特别有用的东西可以识别错误的来源。我该如何解决这个问题?

这是因为我的 EJB Jar 被 Gradle 创建为 "Fat" jar,即

task fatJar(type: Jar) {
    baseName = project.name + '-all'
    from {
        configurations.compile
            .collect {
                println it
                it.isDirectory() ? it : zipTree(it)
            }
    }
    with jar
}

为了访问我需要的 Java EE 库,我还引用了这些工件:

compile 'javax:javaee-api:7.0'
compile 'javax:javaee-web-api:7.0'
compile 'javax.jms:jms:1.1'

问题是这些 Javax 库被拉入 JAR,这是不必要的,因为 Wildfly 已经提供了它们。重复导致焊接异常。

解决方案是从 Fat JAR 中排除这些 Javax 库:

task fatJar(type: Jar) {
    baseName = project.name + '-all'
    from {
        configurations.compile
            /*
                Effectively the javax libraries are provided in scope,
                so don't add them to the jar. Failing to exclude these
                leads to Weld CDI exceptions like
             */
            .findAll {
                it.toString().indexOf('javax') == -1
            }
            .collect {
                println it
                it.isDirectory() ? it : zipTree(it)
            }
    }
    with jar
}

通过此更改,异常消失了。