web-dev-qa-db-ja.com

Java 8内のラムダ式RESTサービスが機能していません

Java 8ラムダ式をRESTサービスに挿入すると、クラッシュします。ラムダ式を削除すると機能します。ラムダ式を使用するかどうか。ラムダが存在するだけでクラッシュする可能性があります。その他すべて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);
    }

}

上記のコードからわかるように、ラムダ式が存在するだけでエラーが発生します。ラムダを削除するとすぐに正常に動作します。他のJava 8は問題ありません(たとえば、 "Predicate"入力パラメーター)。

私が取得しているエラーメッセージは次のとおりです。Java.lang.ArrayIndexOutOfBoundsException:2598

私はJava 8を使用してTomcat 7および8でこれを試しました。JavaEE6の標準の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 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 )com.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。糸PoolExecutor $ Worker.run(ThreadPoolExecutor.Java:617)at Java.lang.Thread.run(Thread.Java:744)

25
David Jensen

私は解決策を見つけました!私はジャージー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クラスから削除して非RESTクラスに配置したのに、ラムダ式が依然として失敗するのはなぜですか? Jersey 1.xはラムダ式を使用するとクラッシュするのに十分でした(実際のRESTサービスが関係していたかどうかに関係なく)。しかし、いずれにしても、プロジェクトが再び機能していることを嬉しく思います。とにかく最新バージョンのjax-rs&Jerseyにアップグレードしたいと思っていたため、これを行う必要がありました(数時間の作業がかかり、「SCRUMマスター」に、見積もりがオフになっている理由を説明する必要があります(取得しないでください) JSONを返すように言ったときにJersey 2がなぜXMLを返すのかを理解することができれば、私は軌道に戻るでしょう。

皆さんの助けに感謝します!

26
David Jensen

Jersey 1.19はJDK 1.8.0と互換性があります。 Jersey 1.19リリースの概要を参照してくださいJersey 1.19でのJDK8サポートASM libをジャージー1.19に再パッケージします

Jersey-server-1.19.jarにはasm 5.0が再パックされているため、asm-3.1.jarを削除してください。

12
Tom Shen

スタックトレースは、クラスorg.objectweb.asm.ClassReader.readClassは例外を示します。これはGlassfishが内部で使用するパーサーだと思います。

クラッシュする理由の1つは、指定された入力を適切に処理するように構成されていないためです。この場合、与えられた入力はラムダ式であり、それを処理する方法がわかりません。

GlassfishおよびTomcatのJava 8バイトコード(lambda)サポートを探す必要があります。それが問題でない場合は、内部で使用されているパーサーのバグである可能性があります。

3
skiwi

ラムダを導入した後、Java 1.8でjunitテストを実行しようとしたときに、この特定のエラーを取り除く前に、springを4.3.6.RELEASEおよびjunitに4.12にアップグレードする必要がありました。

1
David B

他のすべての答えに加えて、

私のシステムでは、この問題はGlassfish 4.0(build 89)で発生します

解決;

Glassfish to 4.1(build 13)をアップグレードし、その問題を解決しました。

0
Yusuf K.