Jdbi: سيقوم JDK9 بحظر setAccessible على الوحدات النمطية

تم إنشاؤها على ٢١ سبتمبر ٢٠١٦  ·  22تعليقات  ·  مصدر: jdbi/jdbi

نحن نستخدم setAccessible(true) للحصول على وصول عاكس لواجهة برمجة التطبيقات الخاصة في مكانين. لا يمكننا الاعتماد على هذا بعد إصدار JDK9.

على وجه الخصوص ، يستخدم DefaultMethodHandler في كائن SQL setAccessible للوصول إلى MethodHandle.Lookup للأعضاء الخاصين ، حتى نتمكن من استدعاء الطريقة الافتراضية ("super").

ارى:

bug

التعليق الأكثر فائدة

يجب أن يكون هذا مدعومًا في إصدار Jdbi التالي - ربما v3.2.0

ال 22 كومينتر

لقد اختبرت أحدث لقطة JDBI على JDK 9-ea + 136 ، وللأسف ، لا تعمل الطرق الافتراضية.

java.lang.RuntimeException: java.lang.IllegalAccessException: access to public member failed: org.jdbi.v3.sqlobject.TestSqlObject$Dao.doesTransactionAnnotationWork()boolean/invokeSpecial, from org.jdbi.v3.sqlobject.TestSqlObject$Dao/2 (unnamed module @34b7bfc0)

    at org.jdbi.v3.sqlobject.DefaultMethodHandler.invoke(DefaultMethodHandler.java:63)
    at org.jdbi.v3.sqlobject.TransactionDecorator.lambda$invoke$0(TransactionDecorator.java:54)
    at org.jdbi.v3.core.transaction.LocalTransactionHandler.inTransaction(LocalTransactionHandler.java:173)
    at org.jdbi.v3.core.Handle.inTransaction(Handle.java:478)
    at org.jdbi.v3.sqlobject.TransactionDecorator.invoke(TransactionDecorator.java:57)
    at org.jdbi.v3.sqlobject.SqlObjectFactory.lambda$createInvocationHandler$18(SqlObjectFactory.java:241)
    at com.sun.proxy.$Proxy16.doesTransactionAnnotationWork(Unknown Source)
    at org.jdbi.v3.sqlobject.TestSqlObject.testTransactionAnnotationWorksOnInterfaceDefaultMethod(TestSqlObject.java:115)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-ea/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-ea/NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-ea/DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(java.base@9-ea/Method.java:535)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-ea/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-ea/NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-ea/DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(java.base@9-ea/Method.java:535)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.IllegalAccessException: access to public member failed: org.jdbi.v3.sqlobject.TestSqlObject$Dao.doesTransactionAnnotationWork()boolean/invokeSpecial, from org.jdbi.v3.sqlobject.TestSqlObject$Dao/2 (unnamed module @34b7bfc0)
    at java.lang.invoke.MemberName.makeAccessException(java.base@9-ea/MemberName.java:915)
    at java.lang.invoke.MethodHandles$Lookup.checkAccess(java.base@9-ea/MethodHandles.java:1924)
    at java.lang.invoke.MethodHandles$Lookup.checkMethod(java.base@9-ea/MethodHandles.java:1864)
    at java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(java.base@9-ea/MethodHandles.java:2013)
    at java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(java.base@9-ea/MethodHandles.java:2007)
    at java.lang.invoke.MethodHandles$Lookup.unreflectSpecial(java.base@9-ea/MethodHandles.java:1539)
    at org.jdbi.v3.sqlobject.DefaultMethodHandler.invoke(DefaultMethodHandler.java:51)
    ... 38 more

للأسف ، أنا أيضًا لا أرى حلاً لهذا.

هذا نوع من الغريب كل الأشخاص في الإنترنت الذين يواجهون نفس المشكلة ، ينتهي بهم الأمر بهذا الاختراق باعتباره الحل الوحيد. يبدو أنه كان هناك القليل من الإشراف من فريق JDK لعدم الالتفات إلى حالة استخدام "الطرق الافتراضية في البروكسيات".

حسنًا ، لقد عملت مع:

Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
field.setAccessible(true);
MethodHandles.Lookup lookup = (MethodHandles.Lookup) field.get(null);
Class<?> declaringClass = method.getDeclaringClass();
return lookup.unreflectSpecial(method, declaringClass)
                    .bindTo(target)
                    .invokeWithArguments(args);

لا توجد فكرة لماذا هذا يعمل مع JDK9.

تنهد. ربما ينبغي أن نتابع مع مطوري openjdk حول هذا عاجلاً وليس آجلاً ...

لقد كنت أشاهد Jigsaw-dev خلال الأيام العديدة الماضية. كان هناك بعض النقاش حول حالة الاستخدام هذه بالضبط ، ولكن مما يمكنني قوله كان أكثر من مجرد حاشية سفلية تتعلق بمناقشة محتدمة حول قيمة تقييد setAccessible . يبدو أن الكثير من الناس ليسوا سعداء بهذه الخطوة.

أنا أقوم بإزالة هذا من حاصرات الإصدار. يبدو أنه من غير المحتمل ظهور إصلاح في المنبع قريبًا ، ولم يتم إصدار JDK9 بعد. يجب ألا يؤثر الإصلاح النهائي على واجهة برمجة التطبيقات العامة.

لقد اتصلت بالقائمة البريدية لـ Jigsaw-dev حول هذا الموضوع. http://jigsaw-dev.1059479.n5.nabble.com/Invoking-default-methods-from-a-Proxy-s-InvocationHandler-in-JDK9-td5714878.html.

سنرى ما يخرج منه.

صدمته على core-libs-dev مرة أخرى.

يجب حل هذا الأمر بالنسبة لنا في تصميمات JDK9 الأخيرة. على الأقل من الناحية النظرية.

في الأساس ، قاموا بتغيير الفحوصات الأمنية بحيث يمكن لأي شخص القيام بذلك
خاص بالطريقة الافتراضية.

عندما تهبط JDK9 ، سيتعين علينا تبديل النهج ديناميكيًا اعتمادًا على
إصدار Java الذي يعمل به JDBI.

في 1 آذار (مارس) 2017 الساعة 2:36 ظهرًا ، "ستيفن شلانسكر" [email protected]
كتب:

صدمته على core-libs-dev مرة أخرى.

-
أنت تتلقى هذا لأنك قمت بتأليف الموضوع.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/jdbi/jdbi/issues/497#issuecomment-283478025 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AACW5VBktrJYJatnsABFKay_-Ci5WD_Sks5rheTCgaJpZM4KCb6m
.

اه نعم. من core-libs-dev:

يمكنك استخدام MethodHandles.privateLookupIn (جديد في JDK 9) لاستبدال Constructor hack للحصول على كائن بحث مع وصول خاص للفئة المستهدفة.
ماندي

هذا منعش لسماعه! على الأقل يمكننا التخلص من هذه الفوضى في JDK9.

مرحبًا ، لقد قمت بحل مشكلة مماثلة في مشروعي OWNER الذي يستدعي الأساليب الافتراضية على الواجهات باستخدام JDK9 ، يرجى إلقاء نظرة على فئة المرافق الخاصة بي ، ربما يمكن أن تساعدك.

اي كلمة في هذا؟ متى سأتمكن من استخدام JDBI مع JDK 9؟

نحن مهتمون جدًا بدعم Java 9 ولكن بصراحة لم أبدأ في البحث فيه بعد. آخر مرة بحثت فيها عن النظام البيئي ما زلت بحاجة إلى وقت للاستقرار ، ولكن ربما حان الوقت للتغلب على أولوية هذا.

هل من جديد هنا؟ 10 دينار أردني خارج المنزل منذ أيام قليلة ...

لا يوجد تغيير واضح في jdk9 ، فمن الأفضل الانتقال مباشرة إلى 10

يبدو أننا قد نضطر إلى تفريع الكود واستخدام الانعكاس للاستفادة من الأساليب الجديدة المضافة في JDK9 دون كسر التوافق مع 8. أسرع طريقة للمضي قدمًا هنا هي إرسال تصحيح أو على الأقل بعض الإجراءات القانونية نحو اكتشاف الحد الأدنى من التغيير ضروري :) وإلا سأحاول إلقاء نظرة على هذا في وقت ما هذا الأسبوع.

ونأمل أن تكون غالبية الأعمال للوصول إلى الرقم 10 ستكون في الواقع في الوصول إلى 9 - لا أعتقد أن هناك أي تغييرات كبيرة في 10 نتوقع كسر الأشياء ، بينما نعلم بالتأكيد 9 أشياء معطلة ...

لدي فرع في هذا لا يحتاج إلى بناء مزدوج ، لكنه يحتاج إلى إصلاح أولاً

حسنًا ، لن أبدأ في اختراقها بعد ذلك.

يجب أن يكون هذا مدعومًا في إصدار Jdbi التالي - ربما v3.2.0

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات