рдЬрд╛рд╡рд╛ 8, 9, 10 рдореЗрдВ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рддрдХ рдЙрдЪрд┐рдд рдкрд╣реБрдВрдЪ

рдЕрдиреБрд╡рд╛рджрдХ рдХрд╛ рдзреНрдпрд╛рди: рд╕реАрдпреВрдмреАрдП рдврд╛рдВрдЪреЗ рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЖрд░рдПрдВрдбрдбреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЛ рдЬрдиреНрдо рджреЗрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рджреМрд░рд╛рди, рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рд╣рдореЗрдВ рдкреНрд░реЙрдХреНрд╕реА рдХрдХреНрд╖рд╛рдУрдВ рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рдПрдХ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд▓реЗрдЦ рдкрд░ рдареЛрдХрд░ рдЦрд╛рдИ, рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдЕрдиреБрднрд╡ рдХрдо рд╕реЗ рдХрдо рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛, рдФрд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдПрдХ рд╡рд┐рд╕реНрддреГрдд рд╕рд░реНрдХрд▓ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред

рдЬрдм рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рд╡рд╛ рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдмрд╛рдд рдЖрддреА рд╣реИ, рддреЛ Google рдмрд╣реБрдд рдорджрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, StackOverflow рдкрд░ рдПрдХ рд╕рдорд╛рдзрд╛рди рдХреЗрд╡рд▓ рдХреБрдЫ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЬрд╛рд╡рд╛ рдХреЗ рд╕рднреА рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдирд╣реАрдВред

рдпрд╣ рдЖрд▓реЗрдЦ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдЧрд╛, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░реЙрдХреНрд╕реА рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛рддреЗ рд╕рдордпред

TL, DR рдпрджрд┐ рдЖрдк рдкреНрд░рддреАрдХреНрд╖рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕ рдЖрд▓реЗрдЦ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд╕рднреА рддрд░реАрдХреЗ рдЗрд╕ рд▓рд┐рдВрдХ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рдФрд░ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣рдорд╛рд░реЗ jOOR рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдкрд╣рд▓реЗ рд╣реА рд╣рд▓ рд╣реЛ рдЪреБрдХреА рд╣реИред

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ рд╕рдореАрдкрддрд╛


рдЙрдкрдпреЛрдЧреА рдПрдкреАрдЖрдИ java.lang.reflect.Proxy рдПрдХ рд▓рдВрдмреЗ рд╕рдордп рдХреЗ рд▓рд┐рдП рдЕрд╕реНрддрд┐рддреНрд╡ рдореЗрдВ рд╣реИ, рдЗрд╕рдХреЗ рд╕рд╛рде рд╣рдо рд╢рд╛рдВрдд рдЪреАрдЬреЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

import java.lang.reflect.Proxy; public class ProxyDemo { interface Duck { void quack(); } public static void main(String[] a) { Duck duck = (Duck) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), new Class[] { Duck.class }, (proxy, method, args) -> { System.out.println("Quack"); return null; } ); duck.quack(); } } 

рдпрд╣ рдХреЛрдб рдмрд╕ рдЖрдЙрдЯрдкреБрдЯ:

 Quack 

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдордиреЗ рдПрдХ рдкреНрд░реЙрдХреНрд╕реА рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдпрд╛ рдЬреЛ рдбрдХ рдПрдкреАрдЖрдИ рдХреЛ рдЗрдирд╡реЛрдХреЗрд╢рдирд╣реИрдВрдбрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рд┐рд░реНрдл рдПрдХ рд▓реИрдореНрдмреНрдбрд╛ рд╣реИ рдЬреЛ рдбрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

рджрд┐рд▓рдЪрд╕реНрдк рд╣рд┐рд╕реНрд╕рд╛ рддрдм рд╢реБрд░реВ рд╣реЛрдЧрд╛ рдЬрдм рд╣рдо рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдкрджреНрдзрддрд┐ рдкрд░ рдПрдХ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:

 interface Duck { default void quack() { System.out.println("Quack"); } } 

рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рдЖрдк рдЗрд╕ рдХреЛрдб рдХреЛ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗ:

 import java.lang.reflect.Proxy; public class ProxyDemo { interface Duck { default void quack() { System.out.println("Quack"); } } public static void main(String[] a) { Duck duck = (Duck) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), new Class[] { Duck.class }, (proxy, method, args) -> { method.invoke(proxy); return null; } ); duck.quack(); } } 

рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рдиреЗрд╕реНрдЯреЗрдб рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдПрдХ рд▓рдВрдмрд╛ рдвреЗрд░ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ (рдФрд░ рдпрд╣ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рд╡рд┐рдзрд┐ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝рд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдмрд╕ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордирд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ):

 Exception in thread "main" java.lang.reflect.UndeclaredThrowableException at $Proxy0.quack(Unknown Source) at ProxyDemo.main(ProxyDemo.java:20) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at ProxyDemo.lambda$0(ProxyDemo.java:15) ... 2 more Caused by: java.lang.reflect.UndeclaredThrowableException at $Proxy0.quack(Unknown Source) ... 7 more Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at ProxyDemo.lambda$0(ProxyDemo.java:15) ... 8 more Caused by: java.lang.reflect.UndeclaredThrowableException at $Proxy0.quack(Unknown Source) ... 13 more Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at ProxyDemo.lambda$0(ProxyDemo.java:15) ... 14 more Caused by: java.lang.reflect.UndeclaredThrowableException at $Proxy0.quack(Unknown Source) ... 19 more ... ... ... goes on forever 

рдмрд╣реБрдд рдорджрджрдЧрд╛рд░ рдирд╣реАрдВред

рд╡рд┐рдзрд┐ рд╣реИрдВрдбрд▓ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рддреЛ, рдПрдХ Google рдЦреЛрдЬ рд╣рдореЗрдВ рдмрддрд╛рддреА рд╣реИ рдХрд┐ рд╣рдореЗрдВ MethodHandles API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред рдЕрдЪреНрдЫрд╛, рдЪрд▓реЛ рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ!

 import java.lang.invoke.MethodHandles; import java.lang.reflect.Proxy; public class ProxyDemo { interface Duck { default void quack() { System.out.println("Quack"); } } public static void main(String[] a) { Duck duck = (Duck) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), new Class[] { Duck.class }, (proxy, method, args) -> { MethodHandles .lookup() .in(Duck.class) .unreflectSpecial(method, Duck.class) .bindTo(proxy) .invokeWithArguments(); return null; } ); duck.quack(); } } 

рд╢рд╛рдВрдд, рдпрд╣ рдХрд╛рдо рдХрд░рдиреЗ рд▓рдЧрддрд╛ рд╣реИ!

 Quack 

... рд▓реЗрдХрд┐рди рдирд╣реАрдВред

рдЧреИрд░-рдирд┐рдЬреА рдкрд╣реБрдВрдЪ рдХреЗ рд╕рд╛рде рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐


рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕рд╛рд╡рдзрд╛рдиреА рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рддрд╛рдХрд┐ рдХреЙрд▓рд┐рдВрдЧ рдХреЛрдб рдХреА рдирд┐рдЬреА рдкрд╣реБрдВрдЪ рд╣реЛ, рдЕрд░реНрдерд╛рддред рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдХреЙрд▓рд┐рдВрдЧ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдиреЗрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЧреИрд░-рдиреЗрд╕реНрдЯреЗрдб рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ?

 import java.lang.invoke.MethodHandles; import java.lang.reflect.Proxy; interface Duck { default void quack() { System.out.println("Quack"); } } public class ProxyDemo { public static void main(String[] a) { Duck duck = (Duck) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), new Class[] { Duck.class }, (proxy, method, args) -> { MethodHandles .lookup() .in(Duck.class) .unreflectSpecial(method, Duck.class) .bindTo(proxy) .invokeWithArguments(); return null; } ); duck.quack(); } } 

рд▓рдЧрднрдЧ рд╕рдорд╛рди рдХреЛрдб рдЕрдм рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред IllegalAccessException рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:

 Exception in thread "main" java.lang.reflect.UndeclaredThrowableException at $Proxy0.quack(Unknown Source) at ProxyDemo.main(ProxyDemo.java:26) Caused by: java.lang.IllegalAccessException: no private access for invokespecial: interface Duck, from Duck/package at java.lang.invoke.MemberName.makeAccessException(MemberName.java:850) at java.lang.invoke.MethodHandles$Lookup.checkSpecialCaller(MethodHandles.java:1572) at java.lang.invoke.MethodHandles$Lookup.unreflectSpecial(MethodHandles.java:1231) at ProxyDemo.lambda$0(ProxyDemo.java:19) ... 2 more 

рдмреБрд▓рдмреБрд▓ рдмрд╛рд╣рд░ рдЖ рдЧрдИред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдЕрднреА рддрдХ Google рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдирд┐рдореНрди рд╕рдорд╛рдзрд╛рди рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ MethodHandles.Lookup рдХреЗ рдЖрдВрддрд░рд┐рдХ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░рддрд╛ рд╣реИред

 import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Constructor; import java.lang.reflect.Proxy; interface Duck { default void quack() { System.out.println("Quack"); } } public class ProxyDemo { public static void main(String[] a) { Duck duck = (Duck) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), new Class[] { Duck.class }, (proxy, method, args) -> { Constructor<Lookup> constructor = Lookup.class .getDeclaredConstructor(Class.class); constructor.setAccessible(true); constructor.newInstance(Duck.class) .in(Duck.class) .unreflectSpecial(method, Duck.class) .bindTo(proxy) .invokeWithArguments(); return null; } ); duck.quack(); } } 

рдФрд░, рдЬрдпрдХрд╛рд░, рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:

 Quack 

рд╣рдо рдЗрд╕реЗ JDK 8 рдкрд░ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗред JDK 9 рдпрд╛ 10 рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ?

 WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by ProxyDemo (file:/C:/Users/lukas/workspace/playground/target/classes/) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class) WARNING: Please consider reporting this to the maintainers of ProxyDemo 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 Quack 

Opachkiред рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╣реЛрддрд╛ рд╣реИ ред рдпрджрд┐ рд╣рдо рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрдХреНрд░рдо рдЪрд▓рд╛рддреЗ рд╣реИрдВ --illegal-access=deny :

 java --illegal-access=deny ProxyDemo 

рдареАрдХ рд╣реИ, рддреЛ рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ (рдФрд░ рдареАрдХ рд╣реА рддреЛ!):

 Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make java.lang.invoke.MethodHandles$Lookup(java.lang.Class) accessible: module java.base does not "opens java.lang.invoke" to unnamed module @357246de at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281) at java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:192) at java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:185) at ProxyDemo.lambda$0(ProxyDemo.java:18) at $Proxy0.quack(Unknown Source) at ProxyDemo.main(ProxyDemo.java:28) 

рдРрд╕реЗ рд╣реИрдХ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд░рд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдПрдХ рд▓рдХреНрд╖реНрдп рдареАрдХ рдерд╛ред рддреЛ, рдХреМрди рд╕рд╛ рд╕рдорд╛рдзрд╛рди рдмреЗрд╣рддрд░ рд╣реИ? рдХреНрдпрд╛ рдпрд╣ рд╣реИ?

 import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Proxy; interface Duck { default void quack() { System.out.println("Quack"); } } public class ProxyDemo { public static void main(String[] a) { Duck duck = (Duck) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), new Class[] { Duck.class }, (proxy, method, args) -> { MethodHandles.lookup() .findSpecial( Duck.class, "quack", MethodType.methodType( void.class, new Class[0]), Duck.class) .bindTo(proxy) .invokeWithArguments(); return null; } ); duck.quack(); } } 

 Quack 

рдорд╣рд╛рди, рдпрд╣ рдЬрд╛рд╡рд╛ 9 рдФрд░ 10 рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрд╛рд╡рд╛ 8 рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?

 Exception in thread "main" java.lang.reflect.UndeclaredThrowableException at $Proxy0.quack(Unknown Source) at ProxyDemo.main(ProxyDemo.java:25) Caused by: java.lang.IllegalAccessException: no private access for invokespecial: interface Duck, from ProxyDemo at java.lang.invoke.MemberName.makeAccessException(MemberName.java:850) at java.lang.invoke.MethodHandles$Lookup.checkSpecialCaller(MethodHandles.java:1572) at java.lang.invoke.MethodHandles$Lookup.findSpecial(MethodHandles.java:1002) at ProxyDemo.lambda$0(ProxyDemo.java:18) ... 2 more 

рдХреНрдпрд╛ рддреБрдо рдореБрдЭрд╕реЗ рдордЬрд╛рдХ рдХрд░ рд░рд╣реЗ рд╣реЛ?

рддреЛ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рдорд╛рдзрд╛рди (рд╣реИрдХ) рд╣реИ рдЬреЛ рдЬрд╛рд╡рд╛ 8 рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди 9 рдФрд░ 10 рдореЗрдВ рдирд╣реАрдВ, рдФрд░ рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ 9 рдФрд░ 10 рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди 8 рдореЗрдВ рдирд╣реАрдВ

рдЧрд╣рд░рд╛ рд╢реЛрдз


рдЦреИрд░, рдореИрдВрдиреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ JDK рдкрд░ рдЕрд▓рдЧ рдХреЛрдб рдЪрд▓рд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред рдЕрдЧрд▓реА рдХрдХреНрд╖рд╛ рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреА рд╣реИред рдпрд╣ рдпрд╣рд╛рдВ GIST рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдЙрдкрд▓рдмреНрдз рд╣реИ ред

JDK 9 рдпрд╛ 10 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ (рдХреНрдпреЛрдВрдХрд┐ JDK 9+ API рдЖрд╡рд╢реНрдпрдХ рд╣реИ: MethodHandles.pStreetLookupIn () ), рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЗрд╕реЗ JDK 8 рдкрд░ рдХреНрд▓рд╛рд╕ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 javac -source 1.8 -target 1.8 CallDefaultMethodThroughReflection.java 

 import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface PrivateInaccessible { default void quack() { System.out.println(" -> PrivateInaccessible.quack()"); } } public class CallDefaultMethodThroughReflection { interface PrivateAccessible { default void quack() { System.out.println(" -> PrivateAccessible.quack()"); } } public static void main(String[] args) { System.out.println("PrivateAccessible"); System.out.println("-----------------"); System.out.println(); proxy(PrivateAccessible.class).quack(); System.out.println(); System.out.println("PrivateInaccessible"); System.out.println("-------------------"); System.out.println(); proxy(PrivateInaccessible.class).quack(); } private static void quack(Lookup lookup, Class<?> type, Object proxy) { System.out.println("Lookup.in(type).unreflectSpecial(...)"); try { lookup.in(type) .unreflectSpecial(type.getMethod("quack"), type) .bindTo(proxy) .invokeWithArguments(); } catch (Throwable e) { System.out.println(" -> " + e.getClass() + ": " + e.getMessage()); } System.out.println("Lookup.findSpecial(...)"); try { lookup.findSpecial(type, "quack", MethodType.methodType(void.class, new Class[0]), type) .bindTo(proxy) .invokeWithArguments(); } catch (Throwable e) { System.out.println(" -> " + e.getClass() + ": " + e.getMessage()); } } @SuppressWarnings("unchecked") private static <T> T proxy(Class<T> type) { return (T) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), new Class[] { type }, (Object proxy, Method method, Object[] arguments) -> { System.out.println("MethodHandles.lookup()"); quack(MethodHandles.lookup(), type, proxy); try { System.out.println(); System.out.println("Lookup(Class)"); Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class); constructor.setAccessible(true); constructor.newInstance(type); quack(constructor.newInstance(type), type, proxy); } catch (Exception e) { System.out.println(" -> " + e.getClass() + ": " + e.getMessage()); } try { System.out.println(); System.out.println("MethodHandles.privateLookupIn()"); quack(MethodHandles.privateLookupIn(type, MethodHandles.lookup()), type, proxy); } catch (Error e) { System.out.println(" -> " + e.getClass() + ": " + e.getMessage()); } return null; } ); } } 

рдЙрдкрд░реЛрдХреНрдд рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ:

рдЬрд╛рд╡рд╛ 8
 $ java -version java version "1.8.0_141" Java(TM) SE Runtime Environment (build 1.8.0_141-b15) Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode) $ java CallDefaultMethodThroughReflection PrivateAccessible ----------------- MethodHandles.lookup() Lookup.in(type).unreflectSpecial(...) -> PrivateAccessible.quack() Lookup.findSpecial(...) -> class java.lang.IllegalAccessException: no private access for invokespecial: interface CallDefaultMethodThroughReflection$PrivateAccessible, from CallDefaultMethodThroughReflection Lookup(Class) Lookup.in(type).unreflectSpecial(...) -> PrivateAccessible.quack() Lookup.findSpecial(...) -> PrivateAccessible.quack() MethodHandles.privateLookupIn() -> class java.lang.NoSuchMethodError: java.lang.invoke.MethodHandles.privateLookupIn(Ljava/lang/Class;Ljava/lang/invoke/MethodHandles$Lookup;)Ljava/lang/invoke/MethodHandles$Lookup; PrivateInaccessible ------------------- MethodHandles.lookup() Lookup.in(type).unreflectSpecial(...) -> class java.lang.IllegalAccessException: no private access for invokespecial: interface PrivateInaccessible, from PrivateInaccessible/package Lookup.findSpecial(...) -> class java.lang.IllegalAccessException: no private access for invokespecial: interface PrivateInaccessible, from CallDefaultMethodThroughReflection Lookup(Class) Lookup.in(type).unreflectSpecial(...) -> PrivateInaccessible.quack() Lookup.findSpecial(...) -> PrivateInaccessible.quack() MethodHandles.privateLookupIn() -> class java.lang.NoSuchMethodError: java.lang.invoke.MethodHandles.privateLookupIn(Ljava/lang/Class;Ljava/lang/invoke/MethodHandles$Lookup;)Ljava/lang/invoke/MethodHandles$Lookup; 

рдЬрд╛рд╡рд╛ реп
 $ java -version java version "9.0.4" Java(TM) SE Runtime Environment (build 9.0.4+11) Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode) $ java --illegal-access=deny CallDefaultMethodThroughReflection PrivateAccessible ----------------- MethodHandles.lookup() Lookup.in(type).unreflectSpecial(...) -> PrivateAccessible.quack() Lookup.findSpecial(...) -> PrivateAccessible.quack() Lookup(Class) -> class java.lang.reflect.InaccessibleObjectException: Unable to make java.lang.invoke.MethodHandles$Lookup(java.lang.Class) accessible: module java.base does not "opens java.lang.invoke" to unnamed module @30c7da1e MethodHandles.privateLookupIn() Lookup.in(type).unreflectSpecial(...) -> PrivateAccessible.quack() Lookup.findSpecial(...) -> PrivateAccessible.quack() PrivateInaccessible ------------------- MethodHandles.lookup() Lookup.in(type).unreflectSpecial(...) -> class java.lang.IllegalAccessException: no private access for invokespecial: interface PrivateInaccessible, from PrivateInaccessible/package (unnamed module @30c7da1e) Lookup.findSpecial(...) -> PrivateInaccessible.quack() Lookup(Class) -> class java.lang.reflect.InaccessibleObjectException: Unable to make java.lang.invoke.MethodHandles$Lookup(java.lang.Class) accessible: module java.base does not "opens java.lang.invoke" to unnamed module @30c7da1e MethodHandles.privateLookupIn() Lookup.in(type).unreflectSpecial(...) -> PrivateInaccessible.quack() Lookup.findSpecial(...) -> PrivateInaccessible.quack() 

рдЬрд╛рд╡рд╛ 10
 $ java -version java version "10" 2018-03-20 Java(TM) SE Runtime Environment 18.3 (build 10+46) Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode) $ java --illegal-access=deny CallDefaultMethodThroughReflection ...   ,   Java 9 

рдирд┐рд╖реНрдХрд░реНрд╖


рдпрд╣ рд╕рдм рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рдЬрдЯрд┐рд▓ рд╣реИред

  • рдЬрд╛рд╡рд╛ 8 рдореЗрдВ, рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рддрд░реАрдХрд╛ рдПрдХ рд╣реИрдХ рд╣реИ рдЬреЛ Lookup рдХреНрд▓рд╛рд╕ рдХреЗ рдкреИрдХреЗрдЬ-рдкреНрд░рд╛рдЗрд╡реЗрдЯ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рддрдХ рдкрд╣реБрдВрдЪ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬреЗрдбреАрдХреЗ рдЗрдВрдЯрд░реНрдирд▓ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рд╡рд░реНрдЧ рд╕реЗ рдирд┐рдЬреА рдкрд╣реБрдВрдЪ рдФрд░ рдЧреИрд░-рдирд┐рдЬреА рдкрд╣реБрдВрдЪ рджреЛрдиреЛрдВ рдХреЗ рд╕рд╛рде рд╕реБрд╕рдВрдЧрдд рддрд░реАрдХреЗ рд╕реЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдпрд╣ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╣реИред
  • Java 9 рдФрд░ 10 рдореЗрдВ, рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ Lookup.findSpecial() (Java 8 рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рдирд╛) рдпрд╛ MethodHandles.privateLookupIn() (рдЬрд╛рд╡рд╛ 8 рдореЗрдВ рд╡рд┐рдзрд┐ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рдпрджрд┐ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд┐рд╕реА рдЕрдиреНрдп рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣реИ рддреЛ рдмрд╛рдж рд╡рд╛рд▓реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдмрд╛рд╣рд░реА рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ, рдпрд╣ рдереЛрдбрд╝рд╛ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдореЗрдо:



рд░рд╛рдлреЗрд▓ рд╡рд┐рдВрдЯрд░рд╣реЗрд▓реНрдЯрд░ (рдмрд╛рдЗрдЯрдмреБрдбреА рдХреЗ рд▓реЗрдЦрдХ) рдиреЗ рдХрд╣рд╛ рдХрд┐ "рд╡рд╛рд╕реНрддрд╡рд┐рдХ" рдлрд┐рдХреНрд╕ рдкреНрд░реЙрдХреНрд╕реА рдПрдкреАрдЖрдИ рдХреЗ рд╕рдВрд╢реЛрдзрд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╣реЛрдЧрд╛:


рдЕрдиреБрд╡рд╛рдж
рд▓реБрдХрд╛рд╕ рдПрдбрд░ : "рдЖрдк рдЗрд╕ рдХрд╛рд░рдг рдХреЛ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдиреЗ рдЗрд╕реЗ рдЕрдм рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛? рдпрд╛ рдмрд╕ рдЗрд╕реЗ рдпрд╛рдж рдХрд┐рдпрд╛ (рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ)? "
рд░рд╛рдлреЗрд▓ рд╡рд┐рдВрдЯрд░рд╣реЗрд▓реНрдЯрд░ : тАЬрдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИред рдпрд╣ рдореЗрдердб рдХреНрд▓рд╛рд╕ рд╕реЗ рд▓реБрдХрдЕрдк рдХреНрд▓рд╛рд╕ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛ рд╕реБрд░рдХреНрд╖рд╛ рдореЙрдбрд▓ рдХрд╛ рдПрдХ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рд╣реИред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдкреНрд░реЙрдХреНрд╕реА рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рд▓реБрдХрдЕрдк рдХреЛ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП ( рдирд┐рд░реНрдорд╛рддрд╛ - рд▓рдЧрднрдЧред рдкреНрд░рддрд┐ред ), рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЛрдВрдиреЗ рдЗрд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдореИрдВрдиреЗ рдЕрд╕рдлрд▓ рд░реВрдк рд╕реЗ рдХреНрд▓рд╛рд╕ рдлрд╝рд╛рдЗрд▓ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдореЗрд╢рди рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рди рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдкреЗрд╢рдХрд╢ рдХреАред "

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╕рднреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдбреЗрд╡рд▓рдкрд░ рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдХреНрдпрд╛ рдпреЗ рддрд░реАрдХреЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ рдпрджрд┐ рдмрддрдЦ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдЖрдпрд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:


рдЕрдиреБрд╡рд╛рдж
JOOQ : рд╢реАрд░реНрд╖рдХ рдФрд░ рд▓реЗрдЦ рд▓рд┐рдВрдХ
рд░рд╛рдлреЗрд▓ рд╡рд┐рдВрдЯрд░рд╣реЗрд▓реНрдЯрд░ : тАЬрдХреНрдпрд╛ рдЖрдкрдиреЗ рдПрдХ рдРрд╕реЗ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдбрдХ рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ рдЬреЛ рдирд┐рд░реНрдпрд╛рдд рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреИрдХреЗрдЬ рдирд╣реАрдВ рдЦреЛрд▓рддрд╛ рд╣реИ? рдпрджрд┐ рдЖрдк рдореЙрдбреНрдпреВрд▓ рдкрде рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдореИрдВ рдЬрд╛рд╡рд╛ 9+ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЗ рд╕рдорд╛рдзрд╛рди рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реВрдВред тАЭ

... рдФрд░ рд╡рд╣ рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдХрд╛ рд╡рд┐рд╖рдп рд╣реЛрдЧрд╛ред

Jor рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдпрджрд┐ рдЖрдк jOR (рдкреНрд░рддрд┐рдмрд┐рдВрдм рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА, рдпрд╣ рдпрд╣рд╛рдБ рд╣реИ ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдВрд╕реНрдХрд░рдг 0.9.8 рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд┐рдХреНрд╕ рд╢рд╛рдорд┐рд▓ рд╣реЛрдЧрд╛: github.com/jOOQ/jOOR/issues/49
рдмрд╕ рдЬрд╛рд╡рд╛ 8 рдпрд╛ MethodHandles.pStreetLookupIn () рдЬрд╛рд╡рд╛ 9+ рдХреЗ рд▓рд┐рдП рд░рд┐рдлреНрд▓реЗрдХреНрд╢рди рдПрдкреАрдЖрдИ рд╣реИрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЖрдк рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

 Reflect.on(new Object()).as(PrivateAccessible.class).quack(); Reflect.on(new Object()).as(PrivateInaccessible.class).quack(); 

Source: https://habr.com/ru/post/hi421413/


All Articles