-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #4691 - use static methods with javadoc to get MethodHandle lookups #4694
Merged
lachlan-roberts
merged 2 commits into
jetty-10.0.x
from
jetty-10.0.x-4691-consistent_methodhandles_lookup
Mar 24, 2020
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -373,8 +373,7 @@ public <T> void addMessageHandler(JavaxWebSocketSession session, Class<T> clazz, | |
{ | ||
try | ||
{ | ||
// TODO: move methodhandle lookup to container? | ||
MethodHandles.Lookup lookup = MethodHandles.publicLookup(); | ||
MethodHandles.Lookup lookup = JavaxWebSocketFrameHandlerFactory.getServerMethodHandleLookup(); | ||
MethodHandle partialMessageHandler = lookup | ||
.findVirtual(MessageHandler.Partial.class, "onMessage", MethodType.methodType(void.class, Object.class, boolean.class)); | ||
partialMessageHandler = partialMessageHandler.bindTo(handler); | ||
|
@@ -431,8 +430,7 @@ public <T> void addMessageHandler(JavaxWebSocketSession session, Class<T> clazz, | |
{ | ||
try | ||
{ | ||
// TODO: move MethodHandle lookup to container? | ||
MethodHandles.Lookup lookup = MethodHandles.publicLookup(); | ||
MethodHandles.Lookup lookup = JavaxWebSocketFrameHandlerFactory.getServerMethodHandleLookup(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. |
||
MethodHandle wholeMsgMethodHandle = lookup.findVirtual(MessageHandler.Whole.class, "onMessage", MethodType.methodType(void.class, Object.class)); | ||
wholeMsgMethodHandle = wholeMsgMethodHandle.bindTo(handler); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -157,7 +157,8 @@ public static MessageSink createMessageSink(MethodHandle msgHandle, Class<? exte | |
|
||
try | ||
{ | ||
MethodHandle ctorHandle = MethodHandles.lookup().findConstructor(sinkClass, | ||
MethodHandles.Lookup lookup = JettyWebSocketFrameHandlerFactory.getServerMethodHandleLookup(); | ||
MethodHandle ctorHandle = lookup.findConstructor(sinkClass, | ||
MethodType.methodType(void.class, CoreSession.class, MethodHandle.class)); | ||
return (MessageSink)ctorHandle.invoke(session.getCoreSession(), msgHandle); | ||
} | ||
|
@@ -194,7 +195,7 @@ private MethodHandle toMethodHandle(MethodHandles.Lookup lookup, Method method) | |
private JettyWebSocketFrameHandlerMetadata createListenerMetadata(Class<?> endpointClass) | ||
{ | ||
JettyWebSocketFrameHandlerMetadata metadata = new JettyWebSocketFrameHandlerMetadata(); | ||
MethodHandles.Lookup lookup = getMethodHandleLookup(endpointClass); | ||
MethodHandles.Lookup lookup = JettyWebSocketFrameHandlerFactory.getApplicationMethodHandleLookup(endpointClass); | ||
|
||
Method openMethod = ReflectUtils.findMethod(endpointClass, "onWebSocketConnect", Session.class); | ||
MethodHandle open = toMethodHandle(lookup, openMethod); | ||
|
@@ -273,7 +274,7 @@ private JettyWebSocketFrameHandlerMetadata createAnnotatedMetadata(WebSocket ann | |
metadata.setIdleTimeout(Duration.ofMillis(max)); | ||
metadata.setBatchMode(anno.batchMode()); | ||
|
||
MethodHandles.Lookup lookup = getMethodHandleLookup(endpointClass); | ||
MethodHandles.Lookup lookup = getApplicationMethodHandleLookup(endpointClass); | ||
Method onmethod; | ||
|
||
// OnWebSocketConnect [0..1] | ||
|
@@ -456,9 +457,53 @@ private void assertSignatureValid(Class<?> endpointClass, Method method, Class<? | |
throw new InvalidSignatureException(err.toString()); | ||
} | ||
|
||
private MethodHandles.Lookup getMethodHandleLookup(Class<?> endpointClass) | ||
/** | ||
* <p> | ||
* Gives a {@link MethodHandles.Lookup} instance to be used to find methods in server classes. | ||
* For lookups on application classes use {@link #getApplicationMethodHandleLookup(Class)} instead. | ||
* </p> | ||
* <p> | ||
* This uses the caller sensitive {@link MethodHandles#lookup()}, this will allow MethodHandle access | ||
* to server classes we need to use and will give access permissions to private methods as well. | ||
* </p> | ||
* | ||
* @return a lookup object to be used to find methods on server classes. | ||
*/ | ||
public static MethodHandles.Lookup getServerMethodHandleLookup() | ||
{ | ||
return MethodHandles.publicLookup().in(endpointClass); | ||
return MethodHandles.lookup(); | ||
} | ||
|
||
/** | ||
* <p> | ||
* Gives a {@link MethodHandles.Lookup} instance to be used to find public methods in application classes. | ||
* For lookups on server classes use {@link #getServerMethodHandleLookup()} instead. | ||
* </p> | ||
* <p> | ||
* This uses {@link MethodHandles#publicLookup()} as we only need access to public method of the lookupClass. | ||
* To look up a method on the lookupClass, it must be public and the class must be accessible from this | ||
* module, so if the lookupClass is in a JPMS module it must be exported so that the public methods | ||
* of the lookupClass are accessible outside of the module. | ||
* </p> | ||
* <p> | ||
* The {@link java.lang.invoke.MethodHandles.Lookup#in(Class)} allows us to search specifically | ||
* in the endpoint Class to avoid any potential linkage errors which could occur if the same | ||
* class is present in multiple web apps. Unlike using {@link MethodHandles#publicLookup()} | ||
* using {@link MethodHandles#lookup()} with {@link java.lang.invoke.MethodHandles.Lookup#in(Class)} | ||
* will cause the lookup to lose its public access to the lookup class if they are in different modules. | ||
* </p> | ||
* <p> | ||
* {@link MethodHandles#privateLookupIn(Class, MethodHandles.Lookup)} is also unsuitable because it | ||
* requires the caller module to read the target module, and the target module to open reflective | ||
* access to the lookupClasses private methods. This is possible but requires extra configuration | ||
* to provide private access which is not necessary for the purpose of accessing the public methods. | ||
* </p> | ||
* @param lookupClass the desired lookup class for the new lookup object. | ||
* @return a lookup object to be used to find methods on the lookupClass. | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. |
||
public static MethodHandles.Lookup getApplicationMethodHandleLookup(Class<?> lookupClass) | ||
{ | ||
return MethodHandles.publicLookup().in(lookupClass); | ||
} | ||
|
||
@Override | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you still need the TODO above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove it, I don't know why we would want to do this in the container, it seems better to contain the MethodHandle stuff in the FrameHandler.