【问题标题】:Java 8 Lambda Expression Within REST Service not workingREST服务中的Java 8 Lambda表达式不起作用
【发布时间】:2014-04-07 16:02:59
【问题描述】:

如果我将 Java 8 Lambda 表达式放在 REST 服务中,它会崩溃。如果我删除 lambda 表达式,它会起作用。我是否使用 lambda 表达式并不重要。仅存在 lambda 就足以崩溃。其他所有与 Java 8 相关的东西似乎都可以工作。

以下是我的代码(简化):

@Path("finance")
public class FinanceRest {

    @GET
    @Produces("text/plain")
    public String speak() {
        return "Hello world.";
    }

    private void lambdaFunction(Predicate<Account> predicate) {
        // Any lambda will cause problems, no matter how simple
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Stream<Integer> onlyOdds = numbers.stream().filter(n -> n%2 != 0);
    }

}

从上面的代码可以看出,仅仅存在 lambda 表达式就会导致失败。一旦我删除了 lambda,它就可以正常工作。其他 Java 8 的东西很好(例如,“Predicate”输入参数)。

我收到的错误消息是: java.lang.ArrayIndexOutOfBoundsException: 25980

我已经在使用 Java 8 的 Tomcat 7 和 8 上进行了尝试。 我正在使用 JavaEE 6 中的标准 jax-rs 东西......换句话说,我的 POM 文件有这个:

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
    </dependency>

任何帮助将不胜感激。 谢谢。

确切的错误消息(在 Glassfish 4.0 上...我已经尝试过 Tomcat 和 Glassfish)是:

java.lang.ArrayIndexOutOfBoundsException: 52264 在 org.objectweb.asm.ClassReader.readClass(ClassReader.java:2015) 在 org.objectweb.asm.ClassReader.accept(ClassReader.java:469) 在 org.objectweb.asm.ClassReader.accept(ClassReader.java:425) 在 org.glassfish.hk2.classmodel.reflect.Parser$5.on(Parser.java:362) 在 com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter.handleEntry(ReadableArchiveScannerAdapter.java:165) 在 com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter.onSelectedEntries(ReadableArchiveScannerAdapter.java:127) 在 org.glassfish.hk2.classmodel.reflect.Parser.doJob(Parser.java:347) 在 org.glassfish.hk2.classmodel.reflect.Parser.access$300(Parser.java:67) 在 org.glassfish.hk2.classmodel.reflect.Parser$3.call(Parser.java:306) 在 org.glassfish.hk2.classmodel.reflect.Parser$3.call(Parser.java:295) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:744)

【问题讨论】:

  • 我不想说这听起来像一个错误,但确实如此。仅添加 lambda 表达式不应破坏 JAX-RS 实现。
  • 您将需要使用 Tomcat 8,而不是 7。确保 JAVA_HOME 指向 Java8 JRE,以便 tomcat 会选择它。除此之外,我不确定问题可能是什么。
  • @jacobhyphenated Java 8 也将在 Tomcat 7 上运行。我有一个运行 Java 8 的实例,没有任何问题。只要确保版本是 7.52+(我相信)
  • @Bart 您是否在使用任何新的 Java 8 字节码结构? (Lambda等)
  • 你能发布错误的完整堆栈跟踪吗?

标签: java lambda glassfish java-8 glassfish-4


【解决方案1】:

我找到了解决方案! 我使用的是泽西岛 1.17.1。当我升级到 2.7 时,它起作用了。我的 pom 文件有以下内容:

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-bundle</artifactId>
    <version>1.17.1</version>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-servlet</artifactId>
    <version>1.17.1</version>
    <scope>compile</scope>
</dependency>

我删除了这些并添加了:

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.7</version>
</dependency>

当然,我必须修改 web.xml 文件:

<servlet>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>

<servlet-mapping>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <url-pattern>/rs/*</url-pattern>
</servlet-mapping>

现在一切正常。 问题是:当我将 lambda 表达式从 REST 类中删除并将它们放入非 REST 类时,为什么它们仍然失败?仅当我包含 Jersey 1.x 的事实就足以在使用 lambda 表达式时崩溃(无论是否涉及实际的 REST 服务)。但无论如何,我很高兴该项目再次运行。无论如何,我一直想升级到最新版本的 jax-rs 和 Jersey,所以这迫使我这样做(花费了我几个小时的工作,并且需要向“SCRUM 大师”解释为什么我的估计是错误的(不要让我开始讨论那个话题)。现在,如果我能弄清楚为什么 Jersey 2 在我告诉它返回 JSON 时返回 XML,我就会回到正轨。

感谢大家的帮助!

【讨论】:

    【解决方案2】:

    Jersey 1.19 与 JDK 1.8.0 兼容。参考 Jersey 1.19 Release summaryJDK8 support in Jersey 1.19Repackage ASM lib in Jersey 1.19

    请删除 asm-3.1.jar,因为 jersey-server-1.19.jar 中重新打包了 asm 5.0。

    【讨论】:

      【解决方案3】:

      堆栈跟踪显示类 org.objectweb.asm.ClassReader.readClass 给出了异常。我想这是 Glassfish 内部使用的解析器。

      它崩溃的原因之一是它没有被配置为正确处理给定的输入。在这种情况下,给定的输入是一个 lambda 表达式,它不知道如何处理它。

      您需要寻找对 Glassfish 和 Tomcat 的 Java 8 字节码 (lambda) 支持。如果不是问题,则可能是内部使用的解析器中的错误。

      【讨论】:

        【解决方案4】:

        在我引入 lamdas 后尝试使用 java 1.8 运行 junit 测试时,我必须将 spring 升级到 4.3.6.RELEASE 和 junit 到 4.12,然后才能摆脱这个特殊错误。

        【讨论】:

          【解决方案5】:

          除了所有其他答案,

          在我的系统上Glassfish 4.0(build 89)出现了这个问题

          解决方案;

          我升级了Glassfish to 4.1(build 13),它解决了这个问题。

          【讨论】:

            猜你喜欢
            • 2012-06-25
            • 2015-06-21
            • 2019-01-16
            • 1970-01-01
            • 2017-11-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多