Guice: guiceに対するJava9(JDK-9)のサポート

作成日 2017年03月14日  ·  51コメント  ·  ソース: google/guice

プレリリースのJava9SDKを使用してプロジェクトを評価しています。 依存関係の注入に失敗した最近の推測を使用しています。 Guiceは、 setAccessible(...) Reflection呼び出しを介して、 java.baseモジュールの一部のクラスを変更しようとしています。 他の多くのDIフレームワークにも同じ問題があります。

現在、GuiceのJava 9サポートに取り組んでいますか?

Java(TM) SE Runtime Environment (build 9-ea+159)とguice 1.4.1 。 ビルドターゲットはJava 1.8です。

DI-ing時に発生したスタックトレースは次のとおりです。

Exception in thread "Thread-0" java.lang.ExceptionInInitializerError
      at com.google.inject.internal.cglib.reflect.$FastClass$Generator.getProtectionDomain(FastClass.java:73)
      at com.google.inject.internal.cglib.core.$AbstractClassGenerator.create(AbstractClassGenerator.java:206)
      at com.google.inject.internal.cglib.reflect.$FastClass$Generator.create(FastClass.java:65)
      at com.google.inject.internal.BytecodeGen.newFastClassForMember(BytecodeGen.java:252)
      at com.google.inject.internal.BytecodeGen.newFastClassForMember(BytecodeGen.java:203)
      at com.google.inject.internal.ProviderMethod.create(ProviderMethod.java:69)
      at com.google.inject.internal.ProviderMethodsModule.createProviderMethod(ProviderMethodsModule.java:275)
      at com.google.inject.internal.ProviderMethodsModule.getProviderMethods(ProviderMethodsModule.java:144)
      at com.google.inject.internal.ProviderMethodsModule.configure(ProviderMethodsModule.java:123)
      at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340)
      at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:349)
      at com.google.inject.spi.Elements.getElements(Elements.java:110)
      at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:138)
      at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:104)
      at com.google.inject.Guice.createInjector(Guice.java:99)
      at de.client.main.Factory.createInjector(Factory.java:248)
      at de.client.main.Main$1$1.run(Main.java:76)
      at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module <strong i="15">@a42cff</strong>
      at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:335)
      at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:278)
      at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:196)
      at java.base/java.lang.reflect.Method.setAccessible(Method.java:190)
      at com.google.inject.internal.cglib.core.$ReflectUtils$1.run(ReflectUtils.java:52)
      at java.base/java.security.AccessController.doPrivileged(Native Method)
      at com.google.inject.internal.cglib.core.$ReflectUtils.<clinit>(ReflectUtils.java:42)
      ... 21 more

VM引数--add-opens java.base/java.lang=ALL-UNNAMEDを使用して、この問題を克服できます。

最も参考になるコメント

Java 9は数週間前にリリースされたので、Guiceを更新する時が来ました。

全てのコメント51件

@felixblaschkeこれは特に

@brettwooldridgeこの問題について言及し

私は実際には特定のページを参照していませんでした。 しかし、あなたが1つにリンクしている限り、私はこの要約版の戦争と平和をミックスに投入します。

cglib3.2.5はこの問題を修正しているようです。 しかし、Guiceはcglibを再パッケージ化しているようです。 したがって、cglib 3.2.5だけを含めることはできないようです。

しかし、cglib 3.2.5を使用して独自のバージョンのguiceを構築し、Java 9-ea +162でアプリケーションを起動できるようになりました。 cglib3.2.5を使用してGuiceの新しいバージョンを作成することを検討する必要があります。

はい。 guiceの新しいバージョンをリリースしてください

私もこの問題に苦しんでいます。 新しいバージョンをリリースするか、cglibをバンドル解除するとよいでしょう。

Java9用の最初のRCが公開されました。

http://mail.openjdk.java.net/pipermail/jdk9-dev/2017-August/005940.html

したがって、これを修正するのに良い時期のようです(cglibバージョンをバンプすることも簡単な修正のようです)。

java.langパッケージは、デフォルトでいわゆるディープリフレクション用に開かれているため、既存のハックがもう少し長く機能し続けることができます。 将来的には、これにより、Guiceやcglibが新しいLookup.defineClassを確認する必要があります。これは、ライブラリがクラスを挿入するためのサポート方法です。

Java 9は数週間前にリリースされたので、Guiceを更新する時が来ました。

この問題の状況はどうなっていますか? 寄稿者の誰かがこれを知っていますか?

@DigitalSmileプロジェクト全体が放棄されたようです。 ほとんどの人がSpringを使用していますが、以前は少なくとも純粋なDIフレームワークがあることを知っていました。 そして今、私は春に代わるものがないことを知っています:(

参考:依存関係をバンドル解除してアップグレードすることで、すべてをJDK9で機能させるブランチがあります。 これをJDK9の本番環境で1か月以上問題なく使用しています。 ブランチでは、ローカルのArtefactoryで機能するように展開設定が変更されているため、これを使用する場合は、設定を調整する必要があります。

Guiceは絶対に放棄されていません! しかし、それは現在ボランティアによって維持されており、新しいオープンソースリリースのためにすべてをまとめることは優先されていません。 これは修正されますが、現時点ではいかなる種類のETAも提供できません:(

@ dimo414洞察に感謝し、頭を上げます。 私は理解できます、それはオープンソースコードであり、コミュニティによってサポートされています、それでもグーグルはこのプロジェクトに対して「後援」を持っていると非常に明確に述べられています...何ヶ月も何ヶ月も活動はありません(または少なくとも他のすべてコミュニティはこれを見ることができません)。
計画やマイルストーン、および/またはいくつかのニュースを明らかにすることはできますか? @stIncMaleに同意できるので、放棄されたプロジェクトのように見えます...

頑張ってくれてありがとう! libは素晴らしいです。

参考までに、OSビルドを再び動かそうとしています。 投稿を続けてください!

@ dimo414 Jigsawを完全にサポートする予定ですか、それともJDK9で実行するための単なる修正ですか?

@DigitalSmile私は何かをサポートすることを約束する立場にはありません:)しかし、私たちは確かにGuiceが可能な限り機能することを望んでおり、OSビルドが修正されると、これらの問題に対処するのが簡単になります。

Java9でGuice4.1.0を実行すると、別の例外が発生します:

このIllegalArgumentExceptionは、Guiceが使用している古いASMバージョンが原因です。 現在、ここでは5.0.3です

問題の原因となるASMソース内の行があり、ここで、1つの明示的に失敗8よりもJavaのバージョンが大きくなることができます。 ASMバージョン6.0では、その行はJava9と確実に互換性があります。

ASM 6.0は、Java9クラスファイルを完全にサポートします。 ここでリリースの発表を読んで

ASM 6.0バージョンがリリースされ、Java9クラスファイルが完全にサポートされています。

@ dimo414 (jarを置き換えることにより)

@rototor上記のブランチでASM6.0にアップグレードすることをお勧めします。

@ dimo414 guiceがjdk9でコンパイルおよび実行されるポイントに修正する、少なくとも3つのフォークがあります。
これは数行のコードの問題であるため、これは良いスタートです。

https://jitpack.io/のように、基本的にこれらのフォークをビルドしてMavenの依存関係として使用できるツールはあり
したがって、コンパイルして機能するように修正し、マイナーバージョンを増やしてMavenリポジトリに公開するだけで、少なくともプロジェクトが生きていることを人々に納得させることができます(gitリポジトリのクローンを作成し、過去数か月間にマスターでのアクティビティがほとんどないことを確認しない限り) )。
ETAをもらえますか?

@sameb @lukesandberg参照されているPRを見てください:cat
それ以外の場合は、パッチを適用して独自のバージョンをフォークしてビルドする必要があると思います。そうすれば、再び便利になります。 :残念だった:

私はこれがお尻の王室の迷惑であることに同意する必要があります。 Guice + JDK9はこの問題のために実際には使用できず、JDK9はGAに約4か月間使用されています。 このプロジェクトは孤立しているように見えます。

私は同意する必要があります-Guiceのパブリックバージョンが腐敗したままになっているように見えます。 :crying_cat_face:

e7bef34ef6379735e2a58df1b23f351bb7e30e44がマージされてから、現在変更を取得するために取り組んでいます。これらの変更の一部により、Java 9のサポートに近づき、PRの問題の一部が修正されます。 その後、私たちがやらなければならないことを見てみましょう。

aopalliance:aopalliancejavax.inject:javax.injectもかなり死んでいるようです。 :slightly_frowning_face:

d95c8c0cdd029a8cfda781bf48976255e059d45aはJava9のcglibを更新し、次のコミットもJava9の問題に対処しました。 それらを試してみませんか?

マスターに何かが起こっているのがわかります。 すぐにリリースされると思いますか?

@ronshapiroIDE内でJava9を使用して実行できますが、実行時には実行できません-guiceにはまだAutomatic-Module-Nameまたはmodule-info.javaクラスがありません。

@ronshapiro現在のスナップショットは、テストしたものに対して

@kashikeそれらのリマインダーに感謝します-#1155に追加されました。

正確には何が残っていますか? 私は、リリースに十分なほどしっかりしていると思います。java9に関連するマイナーな追加の変更は、修正ポイントリリースに入る可能性があります。 java9を使用したGuiceは実際には使用できず、悪化し、時間が経つにつれて摩耗します。
残っているものが何であれ、今すぐリリースし、後で修正するのに十分なようです。

@anthraxxに同意する必要があります。

@ronshapiro / @netdpb :何が欠けていますか? 何かお手伝いできることはありますか? 追加のテスト?

このアップデートで、guiceはjdk10とも互換性がありますか? 角を曲がったところで待っています。

Java 10をサポートするには、リリース時にASM6.1にアップグレードする必要があります。 現在、beta2です: https

今週は、4.2リリースに取り組んでいます。

guice4.2はjava9サポート付きでリリースされています。

関係する仕事とこれの世話をしてくれてありがとう。
Guiceは本当に素晴らしいDIフレームワークであり、この最終的に実現したことを嬉しく思います。 愛のほんの一部を与え続けてください、それは本当にそれに値します:tada:

新しいリリースをどうもありがとう。 欠落しているバインディングがログに美しく報告されるようになりました。

ただし、記録として、違法アクセスの警告がまだ表示されています。

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:/Users/bartek/.m2/repository/com/google/inject/guice/4.2.0/guice-4.2.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

これは、 --illegal-access=denyを使用してGuiceをテストし、JDKモジュール内のクラスまたはクラスのメンバーへの不正アクセスへのアクセスが拒否されたときに発生する可能性のある問題を検出するのに役立ちます。 インジェクションの場合、Guiceは、cglibのコピーに依存してjava.lang.ClassLoaderの保護されたメンバーにハッキングするのではなく、Lookup.defineClass自体を使用することを検討する可能性があります。

Ubuntu 18.04のguiceパッケージでこの問題を参照しました: https

Java10をサポートするASM6.1がリリースされました。
https://mail.ow2.org/wws/arc/asm/2018-03/msg00000.html
https://gitlab.ow2.org/asm/asm/tags

ASM 6.1.1がリリースされ、Java10のサポートに必要です。
@samebここでの計画は何ですか? asmをアップグレードしてリリース4.2.1をリリースしますか?

ASM 6.2は、JDK 10のサポートが向上し、JDK11のサポートもすでにリリースされています。
http://asm.ow2.io/versions.html
https://gitlab.ow2.org/asm/asm/tags
https://gitlab.ow2.org/asm/asm/issues/317830

asm6.2.1がリリースされました。

これは、JRE 11で復活したように見えますか?

原因:java.lang.reflect.InaccessibleObjectException:保護された最終的なjava.lang.Classを作成できませんjava.lang.ClassLoader.defineClass(java.lang.String、byte []、int、int、java.security.ProtectionDomain)throws java.lang.ClassFormatErrorアクセス​​可能:モジュールjava.baseはモジュールcom.google.guiceに対して「java.langを開きません」
java.base / java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)で
java.base / java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)で
java.base / java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)で
java.base / java.lang.reflect.Method.setAccessible(Method.java:192)で
com.googleで。 [email protected]/com.google.inject.internal.cglib.core。 $ ReflectUtils $ 1.run(ReflectUtils.java:61)
java.base / java.security.AccessController.doPrivileged(ネイティブメソッド)で
com.googleで。 [email protected]/com.google.inject.internal.cglib.core。 $ ReflectUtils。(ReflectUtils.java:52)
com.googleで。 [email protected]/com.google.inject.internal.cglib.reflect。 $ FastClassEmitter。(FastClassEmitter.java:67)
com.googleで。 [email protected]/com.google.inject.internal.cglib.reflect。 $ FastClass $ Generator.generateClass(FastClass.java:77)
com.googleで。 [email protected]/com.google.inject.internal.cglib.core。 $ DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
com.googleで。 [email protected]/com.google.inject.internal.cglib.core。 $ AbstractClassGenerator.generate(AbstractClassGenerator.java:329)
com.googleで。 [email protected]/com.google.inject.internal.cglib.core。 $ AbstractClassGenerator $ ClassLoaderData $ 3.apply(AbstractClassGenerator.java:93)
com.googleで。 [email protected]/com.google.inject.internal.cglib.core。 $ AbstractClassGenerator $ ClassLoaderData $ 3.apply(AbstractClassGenerator.java:91)
com.googleで。 [email protected]/com.google.inject.internal.cglib.core.internal。 $ LoadingCache $ 2.call(LoadingCache.java:54)
java.base / java.util.concurrent.FutureTask.run $$$ capture(FutureTask.java:264)で
java.base / java.util.concurrent.FutureTask.run(FutureTask.java)で
com.googleで。 [email protected]/com.google.inject.internal.cglib.core.internal。 $ LoadingCache.createEntry(LoadingCache.java:61)
com.googleで。 [email protected]/com.google.inject.internal.cglib.core.internal。 $ LoadingCache.get(LoadingCache.java:34)
com.googleで。 [email protected]/com.google.inject.internal.cglib.core。 $ AbstractClassGenerator $ ClassLoaderData.get(AbstractClassGenerator.java:116)
com.googleで。 [email protected]/com.google.inject.internal.cglib.core。 $ AbstractClassGenerator.create(AbstractClassGenerator.java:291)
com.googleで。 [email protected]/com.google.inject.internal.cglib.reflect。 $ FastClass $ Generator.create(FastClass.java:65)
com.googleで。 [email protected]/com.google.inject.internal.BytecodeGen.newFastClassForMember (BytecodeGen.java:258)
com.googleで。 [email protected]/com.google.inject.internal.BytecodeGen.newFastClassForMember (BytecodeGen.java:207)
com.googleで。 [email protected]/com.google.inject.internal.ProviderMethod.create (ProviderMethod.java:69)
com.googleで。 [email protected]/com.google.inject.internal.ProviderMethodsModule.createProviderMethod (ProviderMethodsModule.java:272)
com.googleで。 [email protected]/com.google.inject.internal.ProviderMethodsModule.getProviderMethods (ProviderMethodsModule.java:116)
com.googleで。 [email protected]/com.google.inject.internal.ProviderMethodsModule.configure (ProviderMethodsModule.java:100)
com.googleで。 [email protected]/com.google.inject.spi.Elements $ RecordingBinder.install(Elements.java:344)
com.googleで。 [email protected]/com.google.inject.spi.Elements $ RecordingBinder.install(Elements.java:353)
com.googleで。 [email protected]/com.google.inject.PrivateModule.install (PrivateModule.java:171)
com.jwebmp.guicedpersistence / com.jwebmp.guicedpersistence.injectors.JpaPersistPrivateModule.configure(JpaPersistPrivateModule.java:50)で
com.googleで。 [email protected]/com.google.inject.PrivateModule.configure (PrivateModule.java:101)
com.googleで。 [email protected]/com.google.inject.spi.Elements $ RecordingBinder.install(Elements.java:344)
com.googleで。 [email protected]/com.google.inject.AbstractModule.install (AbstractModule.java:103)
com.jwebmp.guicedpersistence / com.jwebmp.guicedpersistence.db.AbstractDatabaseProviderModule.configure(AbstractDatabaseProviderModule.java:109)で
com.googleで。 [email protected]/com.google.inject.AbstractModule.configure (AbstractModule.java:61)
com.googleで。 [email protected]/com.google.inject.spi.Elements $ RecordingBinder.install(Elements.java:344)
com.googleで。 [email protected]/com.google.inject.spi.Elements.getElements (Elements.java:103)
com.googleで。 [email protected]/com.google.inject.internal.InjectorShell $ Builder.build(InjectorShell.java:137)
com.googleで。 [email protected]/com.google.inject.internal.InternalInjectorCreator.build (InternalInjectorCreator.java:103)
...さらに6

  • [ひどい]

@GedMarchttps //github.com/google/guice/issues/1205を参照

GerMarcのコメントのInaccessibleObjectExceptionは、Guiceが名前付きモジュール内にあり、保護されたClassLoader.defineClassメソッドをハッキングして、間違ったコンテキストから呼び出そうとしているためです。 もちろん、一時的に--add-opens java.base/java.lang=com.google.guiceで回避できますが、適切な解決策は、GuiceをLookup.defineClassを使用するように修正することです。 Guiceがクラスパスにデプロイされたときに動作が異なる理由は、JDK(JDK 9、10、および11)がJDK 8に存在するすべてのパッケージを開いて、クラスパス(すべてのモジュールではない)でコーディングするためです。違法アクセスと呼ばれます。 これにより、ほとんどの既存のハックがいくつかのリリースで機能し続け、ライブラリのメンテナがそれらを置き換える時間を与えることができます。

これはJRE10からの腕立て伏せによるものだったので、JPMSでは正常に機能していました。

あなたがグーグルのguiceパッケージに直接公開することを指摘したようにそれを回避するのでALL-MODULESが削除されたと思いますが、ALL-MODULESを使用するとこれはまだ起こります...モジュールパスの除外を行うと後でさらに多くのエラーが発生します
また、JRE11のすべてのAOP Guiceが完全に機能しないことに気づきましたが、JRE 10では完璧でした;)

露出に関して注入ライブラリを壊している10と11の間に重要な変化があると思います...

JDK 11では、この領域に変更はありません。クラスパス上のコードへの不正アクセスのために開かれるパッケージのセットは、JDK9およびJDK10と同じです。これは、デプロイされているため、例のGuiceには役立ちません。クラスパス(名前のないモジュール)ではなく、名前の付いたモジュールとして。 正しいことは、Lookup.defineClassを使用するようにGuiceを修正することです。

うーん、それでは意味がありません。
名前付きモジュールを使用してJRE10でまったく同じアプリを実行すると、コマンドラインパラメーターや除外がなくても100%実行され、10からJRE11に切り替えるだけで問題が発生します。 上記のALL-MODULESを追加してもまったく機能しません。実際、実行に違いはありません。

--add-opens java.base / java.lang = com.google.guiceに設定すると、javassistは明示的に指定された状態で機能します(したがって、ALL-MODULESは理論を削除しました)。 しかし、あなたが言っていることは、何が起こっているのか意味がありませんか?

プログラムパラメータ-Dcom.google.inject.internal.cglib。$ experimental_asm7 = trueを追加すると、ある程度は役に立ちますが、AOPは利用できません。

InaccessibleObjectExceptionは、Guiceが名前付きモジュールにあるため、JDK 9、10、11とまったく同じ例外が表示されます。Guiceがクラスパスにある場合、ハッキングは機能しますが、「不正なリフレクティブアクセス」の警告が表示されます。 java.baseモジュールが完全にカプセル化されると壊れることを指摘します。

アランに感謝します、確かにそれはguiceの原因でcglibでした、

オープンを公開し、パラメーターを構成して実行できます。

このページは役に立ちましたか?
0 / 5 - 0 評価