StringConcatFactory 异常 - Java 9
Exception in StringConcatFactory - Java 9
在学习 java9 StringConcatFactory
class 时,我无法理解为什么使用 MethodHandles.publicLookup()
的代码会抛出 StringConcatException
异常,而如果 MethodHandles.lookup()
使用一切正常。
根据 java 查找文档:
"lookup - Represents a lookup context with the accessibility
privileges of the caller"
StringConcatFactory.makeConcat(MethodHandles.publicLookup(),
"abc",MethodType.methodType(String.class));//Exception Here
StringConcatFactory.makeConcat(MethodHandles.lookup(),
"abc", MethodType.methodType(String.class)); //Working fine
不知道我哪里弄错了?请帮助我理解这种行为。
publicLookup()
的 Javadoc 说:
Returns a lookup object which is trusted minimally.
对比lookup():
Returns a lookup object with full capabilities to emulate all supported bytecode behaviors of the caller. These capabilities include private access to the caller. Factory methods on the lookup object can create direct method handles for any member that the caller has access to via bytecodes, including protected and private fields and methods. This lookup object is a capability which may be delegated to trusted agents.
makeConcat()
的 Javadoc 最后说:
throws StringConcatException - If any of the linkage invariants described here are violated.
鉴于问题 不 包含任何更多细节,最有可能的答案是:您在这里遇到了某种 "permission" 问题。也许您尝试 "concat" 一些在使用 "minimal trust".
时根本不可用的东西
makeConcat
的 javadoc 说第一个参数:
lookup Represents a lookup context with the accessibility privileges of the caller
publicLookup
返回的查找上下文没有这些权限。
即使你不连接任何东西,仍然会抛出异常:
MethodType concatType = MethodType.methodType(String.class); // No arguments, returns String
StringConcatFactory.makeConcat(MethodHandles.publicLookup(), "abc", concatType); // Exception
因为上下文的访问权限是在StringConcatFactory#doStringConcat
中检查的:
if ((lookup.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) {
throw new StringConcatException("Invalid caller: " +
lookup.lookupClass().getName());
}
上下文需要私有查找模式,publicLookup
没有:
System.out.println((MethodHandles.publicLookup().lookupModes()
& MethodHandles.Lookup.PRIVATE) != 0); // false
System.out.println((MethodHandles.lookup().lookupModes()
& MethodHandles.Lookup.PRIVATE) != 0); // true
你的情况下 publicLookup
的主要原因:
StringConcatFactory.makeConcat(MethodHandles.publicLookup(), "abc", MethodType.methodType(String.class));
可以抛出 StringConcatException
而另一方面, lookup
StringConcatFactory.makeConcat(MethodHandles.lookup(), "abc", MethodType.methodType(String.class));
当创建的方法句柄用于访问包的私有 class 的 class 的私有成员时可以正常工作。
如@GhostCat 链接的 Javadoc of publicLookup 中所述
publicLookup => PUBLIC_LOOKUP => (PUBLIC|UNCONDITIONAL) modes
Returns a lookup object which is trusted minimally. The lookup has the
PUBLIC
and UNCONDITIONAL modes
. It can only be used to create method
handles to public members of public classes in packages that are
exported unconditionally.
而 lookup
lookup => (lookupClass => Reflection.getCallerClass, FULL_POWER_MODES => (ALL_MODES & ~UNCONDITIONAL))
Returns a lookup object with full capabilities to emulate all
supported bytecode behaviors of the caller. These capabilities include
private access to the caller. Factory methods on the lookup object can
create direct method handles for any member that the caller has access
to via bytecodes, including protected and private fields and methods.
This lookup object is a capability which may be delegated to trusted
agents.
Do not store it in place where untrusted code can access it.
This method is caller sensitive, which means that it may return
different values to different callers.
For any given caller class C, the lookup object returned by this call
has equivalent capabilities to any lookup object supplied by the JVM
to the bootstrap method of an invokedynamic instruction executing in
the same caller class C.
在学习 java9 StringConcatFactory
class 时,我无法理解为什么使用 MethodHandles.publicLookup()
的代码会抛出 StringConcatException
异常,而如果 MethodHandles.lookup()
使用一切正常。
根据 java 查找文档:
"lookup - Represents a lookup context with the accessibility privileges of the caller"
StringConcatFactory.makeConcat(MethodHandles.publicLookup(),
"abc",MethodType.methodType(String.class));//Exception Here
StringConcatFactory.makeConcat(MethodHandles.lookup(),
"abc", MethodType.methodType(String.class)); //Working fine
不知道我哪里弄错了?请帮助我理解这种行为。
publicLookup()
的 Javadoc 说:
Returns a lookup object which is trusted minimally.
对比lookup():
Returns a lookup object with full capabilities to emulate all supported bytecode behaviors of the caller. These capabilities include private access to the caller. Factory methods on the lookup object can create direct method handles for any member that the caller has access to via bytecodes, including protected and private fields and methods. This lookup object is a capability which may be delegated to trusted agents.
makeConcat()
的 Javadoc 最后说:
throws StringConcatException - If any of the linkage invariants described here are violated.
鉴于问题 不 包含任何更多细节,最有可能的答案是:您在这里遇到了某种 "permission" 问题。也许您尝试 "concat" 一些在使用 "minimal trust".
时根本不可用的东西makeConcat
的 javadoc 说第一个参数:
lookup Represents a lookup context with the accessibility privileges of the caller
publicLookup
返回的查找上下文没有这些权限。
即使你不连接任何东西,仍然会抛出异常:
MethodType concatType = MethodType.methodType(String.class); // No arguments, returns String
StringConcatFactory.makeConcat(MethodHandles.publicLookup(), "abc", concatType); // Exception
因为上下文的访问权限是在StringConcatFactory#doStringConcat
中检查的:
if ((lookup.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) {
throw new StringConcatException("Invalid caller: " +
lookup.lookupClass().getName());
}
上下文需要私有查找模式,publicLookup
没有:
System.out.println((MethodHandles.publicLookup().lookupModes()
& MethodHandles.Lookup.PRIVATE) != 0); // false
System.out.println((MethodHandles.lookup().lookupModes()
& MethodHandles.Lookup.PRIVATE) != 0); // true
你的情况下 publicLookup
的主要原因:
StringConcatFactory.makeConcat(MethodHandles.publicLookup(), "abc", MethodType.methodType(String.class));
可以抛出 StringConcatException
而另一方面, lookup
StringConcatFactory.makeConcat(MethodHandles.lookup(), "abc", MethodType.methodType(String.class));
当创建的方法句柄用于访问包的私有 class 的 class 的私有成员时可以正常工作。
如@GhostCat 链接的 Javadoc of publicLookup 中所述
publicLookup => PUBLIC_LOOKUP => (PUBLIC|UNCONDITIONAL) modes
Returns a lookup object which is trusted minimally. The lookup has the
PUBLIC
andUNCONDITIONAL modes
. It can only be used to create method handles to public members of public classes in packages that are exported unconditionally.
而 lookup
lookup => (lookupClass => Reflection.getCallerClass, FULL_POWER_MODES => (ALL_MODES & ~UNCONDITIONAL))
Returns a lookup object with full capabilities to emulate all supported bytecode behaviors of the caller. These capabilities include private access to the caller. Factory methods on the lookup object can create direct method handles for any member that the caller has access to via bytecodes, including protected and private fields and methods. This lookup object is a capability which may be delegated to trusted agents.
Do not store it in place where untrusted code can access it. This method is caller sensitive, which means that it may return different values to different callers.
For any given caller class C, the lookup object returned by this call has equivalent capabilities to any lookup object supplied by the JVM to the bootstrap method of an invokedynamic instruction executing in the same caller class C.