μ°λ¦¬λ setAccessible(true)
λ₯Ό μ¬μ©νμ¬ λͺ κ³³μμ λΉκ³΅κ° APIμ λν λ°μ¬ μ‘μΈμ€λ₯Ό μ»κ³ μμ΅λλ€. JDK9κ° μΆμλ νμλ μ΄λ₯Ό κΈ°λν μ μμ΅λλ€.
νΉν SQL Objectμ DefaultMethodHandler
λ setAccessible
λ₯Ό μ¬μ©νμ¬ private λ©€λ²μ MethodHandle.Lookup
μ μ‘μΈμ€νλ―λ‘ κΈ°λ³Έ("μνΌ") λ©μλλ₯Ό νΈμΆν μ μμ΅λλ€.
보λ€:
JDK 9-ea+136μμ μ΅μ JDBI μ€λ μ·μ ν μ€νΈνλλ° λΆννλ κΈ°λ³Έ λ°©λ²μ΄ μλνμ§ μμ΅λλ€.
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λ μμ§ λ¦΄λ¦¬μ€λμ§ μμμ΅λλ€. μ΅μ’ μμ μ¬νμ κ³΅κ° APIμ μν₯μ λ―ΈμΉμ§ μμμΌ ν©λλ€.
μ΄μ λν΄ jigsaw-dev λ©μΌλ§ 리μ€νΈμ μ°λ½νμ΅λλ€. http://jigsaw-dev.1059479.n5.nabble.com/Invoking-default-methods-from-a-Proxy-s-InvocationHandler-in-JDK9-td5714878.html.
μ°λ¦¬λ κ·Έκ²μμ 무μμ΄ λμ€λμ§ λ³Ό κ²μ λλ€.
core-lib-devμ λ€μ λΆλͺμ³€μ΅λλ€.
μ΄κ²μ μ΅κ·Ό JDK9 λΉλμμ ν΄κ²°λμ΄μΌ ν©λλ€. μ μ΄λ μ΄λ‘ μμΌλ‘λ.
κΈ°λ³Έμ μΌλ‘ 보μ κ²μ¬λ₯Ό λ³κ²½νμ¬ λꡬλ
κΈ°λ³Έ λ©μλμ λν unreflectSpecial.
JDK9κ° μΆμλλ©΄ λ€μμ λ°λΌ μ κ·Ό λ°©μμ λμ μΌλ‘ μ νν΄μΌ ν©λλ€.
Java λ²μ JDBIκ° μ€ν μ€μ
λλ€.
2017λ
3μ 1μΌ μ€ν 2μ 36λΆ, "Steven Schlansker" [email protected]
μΌλ€:
core-lib-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μ μλ‘μ΄ κΈ°λ₯)μ μ¬μ©νμ¬ μμ±μ ν΄νΉμ λ체νμ¬ λμ ν΄λμ€μ λν λΉκ³΅κ° μ‘μΈμ€λ‘ μ‘°ν κ°μ²΄λ₯Ό κ°μ Έμ¬ μ μμ΅λλ€.
맨λ
λ£κΈ°λ§ ν΄λ μμΎν©λλ€! μ΅μν JDK9μμλ μ΄ νΌλμ μμ¨ μ μμ΅λλ€.
μλ νμΈμ JDK9λ₯Ό μ¬μ©νμ¬ μΈν°νμ΄μ€μμ κΈ°λ³Έ λ©μλλ₯Ό νΈμΆνλ νλ‘μ νΈ μμ μ μμ μ μ¬ν λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€. μ μ νΈλ¦¬ν° ν΄λμ€λ₯Ό μ΄ν΄λ³΄μμμ€. λμμ΄ λ μ μμ΅λλ€.
μ΄κ²μ λν μ΄λ€ λ§? μΈμ JDBIλ₯Ό JDK 9μ ν¨κ» μ¬μ©ν μ μμ΅λκΉ?
μ°λ¦¬λ Java 9 μ§μμ λ§€μ° κ΄μ¬μ΄ μμ§λ§ μμ§ν μμ§ μ‘°μ¬λ₯Ό μμνμ§ μμμ΅λλ€. λ§μ§λ§μΌλ‘ μνκ³κ° μμ§ μ μ°©ν μκ°μ΄ νμνλ€λ κ²μ λΆλͺ ν 보μμ§λ§, μλ§λ μ΄κ²μ μ°μ μμλ₯Ό λΆλͺν λμΌ κ²μ λλ€.
μ¬κΈ°μ μλ‘μ΄ κ²μ΄ μμ΅λκΉ? JDK 10μ΄ λ©°μΉ λ§μ μμ΄μ‘μ΅λλ€ ...
jdk9μλ λμ λλ λ³νκ° μμ΅λλ€. 10μΌλ‘ λ°λ‘ μ΄λνλ κ²μ΄ μ’μ΅λλ€.
μ½λλ₯Ό λΆκΈ°νκ³ λ¦¬νλ μ μ μ¬μ©νμ¬ 8κ³Όμ νΈνμ±μ μμμν€μ§ μκ³ JDK9μ μΆκ°λ μλ‘μ΄ λ°©λ²μ νμ©ν΄μΌ ν μλ μμ΅λλ€. μ¬κΈ°μ μμΌλ‘ λμκ°λ κ°μ₯ λΉ λ₯Έ λ°©λ²μ ν¨μΉλ₯Ό μ μΆνκ±°λ μ΅μνμ λ³κ²½ μ¬νμ νμ νκΈ° μν μ½κ°μ λ Έλ ₯μ κΈ°μΈμ΄λ κ²μ λλ€. νμν©λλ€ :) κ·Έλ μ§ μμΌλ©΄ μ΄λ² μ£Όμ μ΄κ²μ μ΄ν΄λ³΄λ €κ³ ν©λλ€.
κ·Έλ¦¬κ³ λ°λΌκ±΄λ 10μ λλ¬νλ μμ μ λλΆλΆμ μ€μ λ‘ 9μ λλ¬νλ κ²μ λλ€. 10μ ν° λ³νκ° μλ€κ³ μκ°ν©λλ€. μ°λ¦¬κ° κΉ¨λ¨λ¦΄ κ²μΌλ‘ μμνλ λ°λ©΄μ 9λ νμ€ν κΉ¨μ‘μ΅λλ€...
μ΄μ€ λΉλκ° νμνμ§ μμ λΆκΈ°κ° μμ§λ§ λ¨Όμ μμ ν΄μΌ ν©λλ€.
μκ² μ΅λλ€. κ·Έλ¬λ©΄ ν΄νΉμ μμνμ§ μκ² μ΅λλ€.
μ΄κ²μ λ€μ Jdbi 릴리μ€(μλ§λ v3.2.0)μμ μ§μλμ΄μΌ ν©λλ€.
κ°μ₯ μ μ©ν λκΈ
μ΄κ²μ λ€μ Jdbi 릴리μ€(μλ§λ v3.2.0)μμ μ§μλμ΄μΌ ν©λλ€.