Issue #4800 - prevent LinkageErrors for WS lookup on JDK 14
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
f5b0dc56d2
commit
870a765464
|
@ -727,10 +727,10 @@ public abstract class JavaxWebSocketFrameHandlerFactory
|
|||
* 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.
|
||||
* This method needs to return a Lookup instance which has only {@link java.lang.invoke.MethodHandles.Lookup#PUBLIC}
|
||||
* access on the lookup class only. Previously we could use {@link MethodHandles#publicLookup()}, however
|
||||
* in JDK 14 this was changed to only include {@link java.lang.invoke.MethodHandles.Lookup#UNCONDITIONAL},
|
||||
* so instead we use {@link MethodHandles#lookup()} and manually drop all access modes we don't want to allow.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link java.lang.invoke.MethodHandles.Lookup#in(Class)} allows us to search specifically
|
||||
|
@ -740,6 +740,11 @@ public abstract class JavaxWebSocketFrameHandlerFactory
|
|||
* will cause the lookup to lose its public access to the lookup class if they are in different modules.
|
||||
* </p>
|
||||
* <p>
|
||||
* 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>
|
||||
* {@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
|
||||
|
@ -750,7 +755,14 @@ public abstract class JavaxWebSocketFrameHandlerFactory
|
|||
*/
|
||||
public static MethodHandles.Lookup getApplicationMethodHandleLookup(Class<?> lookupClass)
|
||||
{
|
||||
return MethodHandles.publicLookup().in(lookupClass);
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
lookup = lookup
|
||||
.dropLookupMode(MethodHandles.Lookup.UNCONDITIONAL)
|
||||
.dropLookupMode(MethodHandles.Lookup.MODULE)
|
||||
.dropLookupMode(MethodHandles.Lookup.PRIVATE)
|
||||
.dropLookupMode(MethodHandles.Lookup.PACKAGE)
|
||||
.dropLookupMode(MethodHandles.Lookup.PROTECTED);
|
||||
return lookup.in(lookupClass);
|
||||
}
|
||||
|
||||
private static class DecodedArgs
|
||||
|
|
|
@ -473,10 +473,10 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle
|
|||
* 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.
|
||||
* This method needs to return a Lookup instance which has only {@link java.lang.invoke.MethodHandles.Lookup#PUBLIC}
|
||||
* access on the lookup class only. Previously we could use {@link MethodHandles#publicLookup()}, however
|
||||
* in JDK 14 this was changed to only include {@link java.lang.invoke.MethodHandles.Lookup#UNCONDITIONAL},
|
||||
* so instead we use {@link MethodHandles#lookup()} and manually drop all access modes we don't want to allow.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link java.lang.invoke.MethodHandles.Lookup#in(Class)} allows us to search specifically
|
||||
|
@ -486,6 +486,11 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle
|
|||
* will cause the lookup to lose its public access to the lookup class if they are in different modules.
|
||||
* </p>
|
||||
* <p>
|
||||
* 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>
|
||||
* {@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
|
||||
|
@ -496,7 +501,14 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle
|
|||
*/
|
||||
public static MethodHandles.Lookup getApplicationMethodHandleLookup(Class<?> lookupClass)
|
||||
{
|
||||
return MethodHandles.publicLookup().in(lookupClass);
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
lookup = lookup
|
||||
.dropLookupMode(MethodHandles.Lookup.UNCONDITIONAL)
|
||||
.dropLookupMode(MethodHandles.Lookup.MODULE)
|
||||
.dropLookupMode(MethodHandles.Lookup.PRIVATE)
|
||||
.dropLookupMode(MethodHandles.Lookup.PACKAGE)
|
||||
.dropLookupMode(MethodHandles.Lookup.PROTECTED);
|
||||
return lookup.in(lookupClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.eclipse.jetty.unixsocket.server.UnixSocketConnector;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledOnJre;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
|
@ -441,7 +440,7 @@ public class DistributionTests extends AbstractDistributionTest
|
|||
{
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS));
|
||||
// we do not test that anymore because it doesn't work for java14
|
||||
//assertFalse(run2.getLogs().stream().anyMatch(s -> s.contains("LinkageError")));
|
||||
assertFalse(run2.getLogs().stream().anyMatch(s -> s.contains("LinkageError")));
|
||||
|
||||
startHttpClient();
|
||||
ContentResponse response = client.GET("http://localhost:" + port + "/test1/index.jsp");
|
||||
|
|
Loading…
Reference in New Issue