REST 服务中的 Java 8 Lambda 表达式不起作用

2022-09-01 17:08:50

如果我将 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 的东西很好(例如,“谓词”输入参数)。

我收到的错误消息是: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>

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

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

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


答案 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>

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

感谢大家的帮助!


答案 2

泽西岛 1.19 与 JDK 1.8.0 兼容。请参阅泽西岛 1.19 版本摘要泽西岛 1.19 中的 JDK8 支持 泽西岛1.19 中的重新打包 ASM lib

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


推荐