我想使用 LambdaMetaFactory 来有效地访问私有方法。
public class Foo {
private void bar() { // here's what I want to invoke
System.out.println("bar!");
}
}
我知道这不是安全违规,因为以下代码有效:
Foo foo = new Foo();
Method m = Foo.class.getDeclaredMethod("bar");
m.setAccessible(true);
m.invoke(foo); // output: bar!
但是,我尝试使用 LambdaMetaFactory 失败了:
MethodHandles.Lookup lookup = MethodHandles.lookup();
Method m = Foo.class.getDeclaredMethod("bar");
m.setAccessible(true);
CallSite site = LambdaMetafactory.metafactory(lookup, "accept",
MethodType.methodType(Consumer.class),
MethodType.methodType(void.class, Object.class),
lookup.unreflect(m),
MethodType.methodType(void.class, Foo.class));
Consumer<Foo> func = (Consumer<Foo>) site.getTarget().invoke();
func.accept(foo); // IllegalAccessException: member is private
显然m.setAccessible(true)
这里还不够。我尝试更改lookup
为MethodHandles.privateLookupIn(Foo.class, MethodHandles.lookup())
,这在我的玩具示例中确实解决了它......但在我的实际应用程序中没有,它会生成一个IllegalAccessException
说法,我的班级“没有完全特权访问”。我一直无法发现为什么我的应用程序“没有完全权限访问”,或者如何修复它。
我发现几乎可以工作的唯一一件事是:
MethodHandles.Lookup original = MethodHandles.lookup();
Field internal = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
internal.setAccessible(true);
TRUSTED = (MethodHandles.Lookup) internal.get(original);
只要我在VM选项中有我可以做到TRUSTED
的,它就允许我使用它。这会产生一个代替(说它找不到),这似乎很有希望......但我仍然无法弄清楚如何让它完全工作,只是产生这个错误而不是其他错误。lookup
--illegal-access=permit
NoClassDefFoundError
Foo
这里发生了什么,我该如何bar
访问LambdaMetaFactory
?