GlassFish4.0でJAX-RSのリソースにCDIでインジェクト出来ない問題

コードは次のとおり

import文等は省略してます。

TestBean.java
@ApplicationScoped
@Getter // lombok
public class TestBean implements Serializable {
    private Integer count = 0;

    public void increment() {
        count++;
    }
}
TestResource.java
@Path("test")
@RequestScoped
public class TestResource {
    @Inject private TestBean testBean;

    @GET
    @Produces(MediaType.TEXT_HTML)
    public String test() {
        testBean.increment();
        return testBean.getCount().toString();
    }

    @GET
    @Path("hoge")
    @Produces(MediaType.TEXT_HTML)
    public String hoge(@NotNull @QueryParam("id") int id) {
        return String.valueOf(id);
    }
}

これ、なんで2つ目のメソッドを書いたかは後でわかります。

ここで"/設定されたパス/test"にアクセスすると次のようなエラーになります

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee以下略
     at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
     at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:771)

対処法

GlassFish4.0でJAX-RSのクラスにCDIでインジェクションしようとしたらUnsatisfiedDependencyExceptionが発生するバグ?

そもそも、もし4.0.1の正式版が出た後で、それを使っているならこの問題は出ないはずですが、まだ正式版が出ていないので一時回避的に対応します。

対処法1

上のリンク先に対処法が書いてあります。

バグのチケットはこれ
https://java.net/jira/browse/GLASSFISH-20597

ここで書かれている対処法はglassfish4のフォルダ内のjarファイルを置き換える
jersey-gf-cdi.jar -> jersey-gf-cdi-2.0.jar
というものですが、なんかうまくいかなかったので次のようにしました。

対処法2

まずは次のリンク先でglassfishのzipファイルを取得します。
http://dlc.sun.com.edgesuite.net/glassfish/4.0.1/nightly/
※ これは正式版ではないのでその点は注意してください
こちらで動作確認したのは「07-Nov-2013 06:55」に作成されたzipファイルです(約100M)
これでもって動かせば少なくとも今回エラーになったところは動くようになりました。

ただし、4.0.1になると例えばJerseyのバージョンが2.4になったりするので、それによる不整合が起こる可能性もあります。

補足

この現象は毎回出るわけではないようです。
試しに上のTestResource.javaの2つ目のメソッドを削除してGF4.0で試してみるとうまくいきます。

で、どこが原因なのかなといろいろ試してみたところ@NotNullアノテーションを外せばうまくいきました。

と、ここまできて再度上のJIRAのページ(再掲)を見てみるとちゃんと書いてありました。

It is problem that a JAX-RS application (exactly a resource class) throws org.glassfish.hk2.api.UnsatisfiedDependencyException when I send GET request to it. The application uses both Bean Validation (@NotNull and @Min) and CDI (@Inject) into same resource class and it is neither Managed Bean nor EJB (Session Bean). If it uses either of them (for example, it uses without Bean Validation), it runs well and send response as status 200.

下記の記事にもあるようにGF4.0はまだ不完全なままリリースされたようです。
http://yoshio3.com/2013/06/11/glassfish-v4-0-released-0611/
http://www.publickey1.jp/blog/13/java_ee_7glassfish_4.html
そのあたりは理解した上で今のところは「試す」というスタンスのほうが良さそうです。