Glassfish4でlambda式を使ってみよう、としたが・・・
先日Java SE8がついにリリースされました。
早速ラムダ式試してみました。
慣れるまでは大変そうですが、記述が簡単になるのがいいですね。
さて、今回は昨年リリースされたGlassfish4でJava8のラムダ式が使えるかどうかを試してみました。
準備
まず、Java SE8とNetBeans8をダウンロード。今回は別々にダウンロードしました。
http://www.oracle.com/technetwork/java/javase/downloads/index.html
https://netbeans.org/downloads/
Glassfishは4.0.1 build4をダウンロード
ここから4.0.1_b4のzipをダウンロードして解凍
今回はweb-profileにしました
参考
で、それぞれインストール
プロジェクト作成
NetBeans上でプロジェクトを
Maven->Webアプリケーションからプロジェクト名等は適当に入力して
サーバは上でインストールしたGlassfish4、Java EEバージョンにJava EE 7 Webを指定して新規作成。
pom.xmlのmaven-compiler-pluginの設定で1.7->1.8に変更
<groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> 以下略
プロジェクトのプロパティのビルド->コンパイルもJDK1.8になっていることを確認
JAX-RSの動作確認
今回はjersey(JAX-RS)を使って試したので
pom.xmlに依存性追加
<dependency> <groupId>org.glassfish.jersey.ext</groupId> <artifactId>jersey-mvc</artifactId> <version>2.5.1</version> <scope>provided</scope> </dependency>
リソースクラス
@javax.ws.rs.Path("demo") public class DemoAction { @javax.ws.rs.GET @javax.ws.rs.Produces("text/plain") public String demo() { return "this is demo!"; } }
コンフィグクラス
@javax.ws.rs.ApplicationPath("d") public class DemoConfig extends org.glassfish.jersey.server.ResourceConfig { public DemoConfig() { register(DemoAction.class); } }
これで
http://localhost:8080/[プロジェクト名]/d/demo
を開くと「this is demo!」と表示されるはず
ここまででJAX-RSの動作確認はひとまずOK
Java8 Stream APIの確認
ラムダ式の確認の前にJava8自体の動作確認
DemoActionを次のように書き換えます
public String demo() { java.util.List<Integer> list = java.util.Arrays.asList(1, 2, 3, 4, 5); long count = list.stream().collect(java.util.stream.Collectors.counting()); return "this is demo! count=" + count; }
http://localhost:8080/[プロジェクト名]/d/demo
を開くと「this is demo! count=5」と表示されるはず
ラムダ式の動作確認
本題です
DemoActionを次のように書き換えます
public String demo() { java.util.List<Integer> list = java.util.Arrays.asList(1, 2, 3, 4, 5); long count = list.stream().filter(i -> i < 2).collect(java.util.stream.Collectors.counting()); return "this is demo! count=" + count; }
起動時に次のようなエラーが出ました
重大: Exception while visiting WEB-INF/classes/demo/DemoAction.class of size 2189 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:359) at com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter.handleEntry(ReadableArchiveScannerAdapter.java:165) at com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter.onSelectedEntries(ReadableArchiveScannerAdapter.java:127) at org.glassfish.hk2.classmodel.reflect.Parser.doJob(Parser.java:344) at org.glassfish.hk2.classmodel.reflect.Parser.access$300(Parser.java:67) at org.glassfish.hk2.classmodel.reflect.Parser$3.call(Parser.java:303) at org.glassfish.hk2.classmodel.reflect.Parser$3.call(Parser.java:292) 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)
ただし、
http://localhost:8080/[プロジェクト名]/d/demo
を開くと「this is demo! count=1」と表示されるのでなんとか動いているようです