JEP 181ネストされたクラスのアクセス制埡







私たちはあたり知られおいないJEPに粟通し続けおいたす。 今床は、Valhallaからnestmatesず呌ばれる別のサブプロゞェクトがありたす。 この機胜により、ネストされたクラスは盞互に無制限にアクセスできたす。 正確に-以䞋で説明したす。 実際、この蚘事は初心者にずっお問題の本質を非垞に明確に説明しおいるため、 JEP 181の正匏な翻蚳です。







初心者の芋た目ではなく、ある皮の専門家の意芋が必芁な堎合は、ニキヌタリプスキヌ、タギルバレ゚フ、りラゞミヌルむワノフなどの専門家に盞談したほうがいいでしょう。ずころで。







JEPはJDK Enchancement Proposalであり、正匏なJSRがリリヌスされるたで、コミッショナヌがより非公匏に䜜業できるようにするOpenJDKの提案ず改善を収集するプロセスです。 JEPはOpenJDKの戊略蚈画ず考えるこずができたす。







アプリケヌションプログラマヌOpenJDKのコミッタヌではないにずっお、そのような知識はコヌドを盎接蚘述するのに圹立぀可胜性は䜎いです。代わりに、Javaプラットフォヌムの䞀般的なアヌキテクチャの理解を提䟛し、戊略的に考え、近い将来を予枬できるようにしたす。







最小倀タむプに関する最近の蚘事を読んだ人たちぞのいく぀かの蚀葉。  MVTの実甚的な偎面に関する蚘事は珟圚曞かれおいたす vwithfield vwithfield



に぀いお話したした。これにより、遞択した倀の型を取埗し、その䞭のフィヌルドを眮き換えるこずができたす。 そのようなメ゜ッドは、明らかに「意味」ではなく、オブゞェクトラッパヌにあるべきです。 論理的には、蚀語オブゞェクトぞのプラむベヌトアクセスを持぀クラスのみがそのフィヌルドを倉曎できたす。 したがっお、型ず倀のコンポヌネントVCCずDVTの間には、特別な信頌関係が生じるはずです。その実装は、JVMで盎接実珟したいものです。







したがっお、JVMの䞀郚の将来のバヌゞョンでは、VMレベルで明瀺的なネストメむトを実装でき、互いのプラむベヌトフィヌルドおよびメ゜ッドにアクセスできるず想定されおいたす。 これは、ラッパヌを生成するためのコンパむラハックではなく、完党にネむティブな機胜です。 これらのバヌゞョンのJVMでは、 vwithfield



は、特定の各倀タむプのすべおのネストメむトが利甚できたす。 蚀い換えるず、 vwithfield



は、すべおのプラむベヌトメ゜ッドが利甚可胜な䞀皮の「カプセル」内で利甚可胜になりたす。







さお、チャットをやめお、JEPに進みたしょう







JEP 181ネストされたクラスのアクセス制埡



簡単な説明







JVMのアクセスチェックを、ネストされたクラスのメ゜ッド、コンストラクタヌ、およびフィヌルドに定矩されたJava蚀語ルヌルに関連付け、クラスをネストクラスに分割する必芁がありたす。぀たり、共通のアクセス制埡コンテキストを共有するそしお通垞は゜ヌスを含む1぀のファむル。 特に、クラスファむルがすべお同じトップレベル型のコンテキストでコンパむルされおいる堎合、別のクラスファむルのプラむベヌト名にアクセスできるようにしたす。 これは、コンパむラがアクセスのレベルを䞊げるアダプタヌメ゜ッドをセットアップする必芁がないようにするために必芁です。







目暙







仮想マシンの機胜を拡匵しお、コンパむラがクラスをグルヌプ化しお、共通のアクセス制埡コンテキストを共有する゜ケット ネストにできるようにしたす。 これにより、クラスを個々のクラスファむルにコンパむルし、論理的に1぀の共通゚ンティティJavaの内郚クラスなどの䞀郚ずしお継続し、特別なアダプタヌメ゜ッドを䜜成せずに互いのメンバヌにアクセスできたす。







クラスのネストずクラスファむル内の関心を正確に蚘述する機胜を远加したす。







Unsafe.defineAnonymousClass()



およびシヌルドクラスの安党で十分にサポヌトされおいる代替手段など、関連する機胜の基盀を圢成する仮想マシンで準備䜜業をUnsafe.defineAnonymousClass()



たす。







制限事項







このJEPは、モゞュヌルなどの他の倧芏暡なアクセス制埡プロゞェクトの改善には関係しおいたせん。







やる気







倚くのJVM蚀語では、1぀のファむルで耇数のクラスを宣蚀したりJavaにネストされたクラスがあるなど、他の゜ヌスクラスではなくをクラスファむルに倉換したりできたす。 䞀方、ナヌザヌの芳点からは、これらはすべお「同じクラス」の䞀郚であるように芋えるため、ナヌザヌは盎感的に同じセキュリティモヌドが適甚されおいるず想定したす。 コンパむラは、期埅に応えようずしお、倚くの堎合、アダプタメ゜ッドを䜿甚しおpackage



するクラスのprivate



メンバヌをチェックする厳密さを軜枛する必芁がありたす。 残念ながら、そのようなアダプタヌはすべおのカプセル化を砎壊し、さたざたなツヌルで゚ラヌを匕き起こしたり、単にナヌザヌの誀解を招く可胜性がありたす。 隣接 nestmate が共通のアクセス制埡メカニズムによっお結合されおいるネストを圢成するクラスファむルのグルヌプに正匏な定矩を導入するず、誰にずっおも同じ結果がより迅速、安党か぀透過的に実珟されたす。







説明







Java蚀語仕様では、クラスずむンタヌフェヌスをネストできたす。 JLS 7.6では、トップレベルの型宣蚀の抂念が導入されおいたす。 ネストされた型をいく぀でもネストできたす。 䞊䜍レベルの型ずその䞭のすべおの型に぀いお、「 ネストを圢成する 」ず蚀うこずができたす。 ネストの2぀のメンバヌは、このネストの隣接ず呌ばれたす  ネストメむト 。 ネむバヌは、プラむベヌトフィヌルド、メ゜ッド、コンストラクタヌを含め、盞互に無制限にアクセスできたす JLS 6.6.1 。 このようなアクセスは、他のすべおの型を含む最䞊䜍の型宣蚀内のすべおに完党に拡匵されたす。 この最䞊䜍タむプは「ミニパッケヌゞ」ず考えるこずができたす。その䞭には、すべおのナヌザヌが実際のJavaパッケヌゞのメンバヌに提䟛されるものよりも幅広いアクセスが蚱可されたす。







Javaコンパむラは、ネストされたタむプのグルヌプを察応するクラスファむルグルヌプにコンパむルしたす。 このネスト JVMS 4.7.6 、 JVMS 4.7.7 を具䜓化するために、 InnerClasses



EnclosingMethod



ずEnclosingMethod EnclosingMethod



䜿甚しEnclosingMethod



。 これらの属性は、JVMが近傍を識別するのに十分であるため、単にネストされたタむプであるず思った堎合よりも、より広くより䞀般的な定矩を近傍に䞎えるこずができたす。 効率を向䞊させるために、ネむバヌず最䞊䜍クラス nest topず呌ばれるの䞡方で䜿甚されるいく぀かの新しい属性を远加しお、クラスファむルの圢匏を倉曎するこずを提案したす。 各ネむバヌには頂点を指す属性があり、各頂点には既知のネむバヌを指す属性がありたす。







JVMのアクセスルヌルを少し倉曎し、 JVMS 5.4.4に次のようなものを远加したす。







フィヌルドたたはメ゜ッドR



は、次の条件のいずれかに該圓する堎合にのみ、クラスたたはむンタヌフェむスD



からアクセスできたす。









C



ずD



が隣接するためには、同じ頂点を持っおいる必芁がありたす。 タむプC



、 MemberOfNest



属性にD



を远加するこずにより、自分自身をスロットD



メンバヌずしお宣蚀したす。 D



がNestMembers



属性を远加したずきに、この近傍がチェックされたす。 このチェックは、ネむバヌのプラむベヌトメンバヌにアクセスしようずしたずきにのみ起動されたす。 このため、他の堎合に発生する前に、䞀郚のタむプをロヌドする必芁がありたす。







これらの新しいルヌルの導入ずバむトコヌドの察応する倉曎の埌、javacはその近隣のプラむベヌトメンバヌの盎接呌び出し呜什を生成できるため、javacにラッパヌはもう必芁ありたせん。 察応する呌び出しバむトコヌド









VMコヌドでネむバヌの抂念ず察応するルヌルを実装した埌、javacにこの圹割を削陀させ、既存のアクセスチェックを改善するだけでなく、他のプロゞェクトも支揎したす。









より゜フトなアクセスルヌルは、次の点でチェックに圱響したす。









バむトコヌドの呌び出しに適甚される他の制限ずの盞互䜜甚を怜蚎する必芁がある堎合がありたす。䟋









およびMethodHandle



呌び出しのセマンティクスバむトコヌドの制限を反映したす。 JVMS 3.7など、䞀般的な説明で䜕かを倉曎する必芁がありたす。







仮想マシンレベルでのネむバヌぞのアクセスの制埡を開始し、javacによっお生成される他のすべおのアダプタヌメ゜ッドを、珟圚のようにpackage-privateではなくprivateアクセスレベルに制限できたす。 それらがたったく必芁ずされない倚くの堎所。







実際の問題







  1. ここでの提案は、VMレベルで、アクセス境界を隣人たで拡匵したす。 すでにこれを行っおいる堎合、 protected



    およびprivate



    ずしお宣蚀さprotected



    クラスぞのアクセスを制限しお、Java蚀語の芏則をより正確にprotected



    べきではないでしょうか これには、JVMがClass.getModifiers



    の倀に基づいお远加のチェックを実行する必芁がありたす。 ほずんどの堎合、プラむベヌトアクセスがpackage-privateに拡匵されたこずを前提ずする反射を䜿甚しおこのようなコヌドを壊す可胜性があるため、そうすべきではありたせん。さらに、保護クラスの新しいチェックは、パブリック。
  2. 「近隣」関係は反射で芋られるべきですか もちろん、リフレクションの基本的な方法は、隣人ぞのアクセスの芏則を考慮に入れるように調敎する必芁がありたす。 しかし、近所のチェックをパブリックAPIに枡すこずは䟡倀がありたす-これに察凊する必芁がありたす。 考えられる最も単玔なク゚リは次のずおりです。 Class#getNestTop



    は、クラスが゜ケットの䞀郚でない堎合、たたは゜ケットの䞊郚でない堎合にnull



    を返したす。 クラス自䜓が最䞊䜍の堎合、ク゚リはそれ自䜓を返したす。


代替案







Javaコンパむラでラッパヌを生成し続けるこずができたす。 䜕かを予枬するのは難しいです。 たずえば、Project Lambdaでは、内郚クラスがこの拡匵に関䞎しおいる堎合、メ゜ッド参照を公開するこずは困難でした。これにより、新しいアダプタヌメ゜ッドが䜜成されたした。 コンパむラヌによっお生成されたラッパヌは扱いにくく予枬䞍胜であるため、倚くのバグがあり、逆コンパむラヌやデバッガヌなどのツヌルを䜿甚しお分析するこずは非垞に困難です。







最初に、既存のInnerClasses



およびEnclosingMethod



属性のみを䜿甚しお近傍を決定するこずを提案したした。 しかし、特別な近隣属性の䜜成により、Java蚀語レベルでネストされた型を単玔に反映するよりも䞀般的なレベルに疑問が生じ、より効率的な実装が可胜になりたした。







テスト䞭







JVMの倧芏暡なテストセットを開発する必芁がありたす。このテストでは、近隣の実装甚に特別に導入されたバむトコヌドのセマンティクスのアクセス芏則ず倉曎をチェックしたす。







同様に、リフレクション、メ゜ッド参照、var-handles、およびJDWP、JVM TI、JNIなどの暙準APIぞの倖郚アクセスに関する远加のテストを䜜成する必芁がありたす。







蚀語でのチェックを提䟛しおいないため、蚀語コンプラむアンスのテストを䜜成する必芁もありたせん。







Javaコンパむラが䞊蚘の機胜の䜿甚を開始するずすぐに、適切な機胜テスト自䜓が蚀語テストから出珟する堎合がありたす。







リスクず仮定







Javaコンパむラが機胜するルヌルは倉化しおいるため、これらの革新はすべお、クラスファむルの新しいバヌゞョン番号に関連付ける必芁がありたす。







JVMの叀いバヌゞョンずの埌方互換性を維持するには、Javaコンパむラヌがレガシヌラッパヌ生成ロゞックをサポヌトする必芁がありたす。







より゜フトなアクセス暩は䜕も壊さないはずです。 䟋倖ずしお、理論䞊、負のコンプラむアンステストは砎綻する可胜性がありたす。







互換性を倱うリスクは非垞に小さいか、たたはたったくありたせん。アクセスルヌルを厳しくせず、むしろ゜フトにするこずを提案しおいるためです。 ナヌザヌがマゞックラッパヌメ゜ッドの存圚を「発芋」し、その存圚を䜿甚する方法を芋぀けた堎合、倉曎を導入した埌、ナヌザヌはこれを行うこずができなくなりたす。 たず、このようなラッパヌには安定した名前がないため、このリスクは非垞に小さくなりたす。







提案されたルヌルは特定のランタむムパッケヌゞ内でのみ新しいアクセス暩を割り圓おるため、プラットフォヌムの敎合性を損なうリスクは非垞に小さいか、ありたせん。 アダプタメ゜ッドの必芁性を排陀するこずにより、個々のトップレベルクラス間のアクセスの機䌚を䜓系的に枛らしたす。







近傍怜蚌には、それが単独で䜿甚されない堎合でも、ネストされたメンバヌのコンテナを陀き、トップレベルのクラスが必芁です。 これは、ディストリビュヌションから未䜿甚のクラスをスロヌするテストたたはアプリケヌションに圱響を䞎える可胜性がありたす。







他のシステムぞの圱響







JVM仕様の新しい説明ず、JVM実装の倉曎が必芁になりたす。 さらに、反射、メ゜ッド参照、var-handle、および堎合によっおはJVM TI、JDWP、およびJNIの仕様ず実装の倉曎が必芁になりたすただし、ネむティブむンタヌフェむスは通垞、アクセス暩を無芖したす-ほずんど䜕もする必芁がないこずが刀明する堎合がありたす。







远加のアクセスチェックでパフォヌマンスがどのように倉化するかを調べる必芁がありたす。







珟圚のJavaコンパむラは、゜ケット間のアクセス甚のアダプタヌメ゜ッドを生成したす。 このドキュメントでは、それらの生成を停止する必芁はありたせんが、それでも、圹に立たなくなったらすぐに捚おるこずをお勧めしたす。







Java゜ヌスずクラスファむルずの間の察応芏則は簡玠化されたす。 Project Lambdaは同じルヌルを耇雑にしおいるため、これは非垞にタむムリヌです。 ただし、補品の亀差点 JDK-8005122など でもいく぀かの圱響が発生するため、最近の耇雑さの増加は通垞の成長ずは芋なされたせん。







アダプタヌをスロヌするず、䞀郚のアプリケヌションのサむズがわずかに小さくなる堎合がありたす。







Pack200の仕様を修正する必芁がある堎合がありたす。







著者



John Roseは、OracleのJVM゚ンゞニアおよびアヌキテクトです。 リヌド゚ンゞニアDa Vinci Machine ProjectOpenJDKの䞀郚。 リヌド゚ンゞニアJSR 292Javaプラットフォヌムでの動的型付け蚀語のサポヌトは、動的呌び出しず、型プロファむリングや高床なコンパむラ最適化などの関連トピックを専門ずしおいたす。 以前は、内郚クラスに取り組んでおり、SPARCの元のHotSpotポヌト、Unsafe APIを䜜成し、Common Lisp、Scheme「esh」、C ++の動的バむンダヌを含む倚くの動的、䞊列、およびハむブリッド蚀語を開発したした。







翻蚳者



Oleg Chirukhin-このテキストの執筆時点では、Sberbank-Technologyのアヌキテクトずしお働いおおり、自動化されたビゞネスプロセス管理システムのアヌキテクチャの開発に埓事しおいたす。 Sberbank Technologiesに入瀟する前は、政府サヌビスや電子医療蚘録を含むいく぀かの政府情報システムの開発、およびオンラむンゲヌムの開発に参加しおいたした。 JUG.ruカンファレンス JPoint、JBreakのスピヌカヌ。 珟圚の研究察象には、仮想マシン、コンパむラ、プログラミング蚀語が含たれたす。








All Articles