Skip to content
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

JettyWebSocketCreator referenced from a method is not visible from class loader with Jetty10RequestUpgradeStrategy #29256

Closed
2is10 opened this issue Oct 4, 2022 · 8 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@2is10
Copy link

2is10 commented Oct 4, 2022

Affects: 5.3.23

I have a working websocket configured and running on Spring 5.3.23 with Jetty 9.4.48.v20220622. When I attempt to upgrade to Jetty 10.0.12, the server responds with 500 Server Error when clients try to open a websocket connection due to the following exception:

org.sf.web.socket.server.HandshakeFailureException: Failed to upgrade; nested exception is java.lang.IllegalArgumentException: org.eclipse.jetty.websocket.server.JettyWebSocketCreator referenced from a method is not visible from class loader
at org.sf.web.socket.server.jetty.Jetty10RequestUpgradeStrategy.upgrade(Jetty10RequestUpgradeStrategy.java:124)
at org.sf.web.socket.server.support.AbstractHandshakeHandler.doHandshake(AbstractHandshakeHandler.java:297)
at org.sf.web.socket.server.support.WebSocketHttpRequestHandler.handleRequest(WebSocketHttpRequestHandler.java:178)
at org.sf.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
at org.sf.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)

at org.eclipse.jetty.io.ssl.SslConnection$1.run(SslConnection.java:132)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:933)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1077)
at java.base/java.lang.Thread.run(Thread.java:833)

Caused by: java.lang.IllegalArgumentException: org.eclipse.jetty.websocket.server.JettyWebSocketCreator referenced from a method is not visible from class loader
at java.base/java.lang.reflect.Proxy$ProxyBuilder.ensureVisible(Proxy.java:883)
at java.base/java.lang.reflect.Proxy$ProxyBuilder.validateProxyInterfaces(Proxy.java:721)
at java.base/java.lang.reflect.Proxy$ProxyBuilder.(Proxy.java:648)
at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:440)
at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329)
at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205)
at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:438)
at java.base/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1037)
at org.sf.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:126)
at org.sf.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:118)
at org.sf.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:97)
at org.sf.web.socket.server.jetty.Jetty10RequestUpgradeStrategy.createJettyWebSocketCreator(Jetty10RequestUpgradeStrategy.java:134)
at org.sf.web.socket.server.jetty.Jetty10RequestUpgradeStrategy.upgrade(Jetty10RequestUpgradeStrategy.java:116)
... 116 more

The IllegalArgumentException originates in java.lang.reflect.Proxy.ensureVisible, which is attempting to ensure the visibility of JettyWebSocketCreator to a org.eclipse.jetty.webapp.WebAppClassLoader. Note that JettyWebSocketCreator has already been successfully loaded by the main class loader. For some reason though, the WebAppClassLoader can't find it.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Oct 4, 2022
@rstoyanchev rstoyanchev added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Jan 24, 2023
@rstoyanchev rstoyanchev self-assigned this Jan 31, 2023
@rstoyanchev rstoyanchev added this to the 5.3.26 milestone Jan 31, 2023
@rstoyanchev rstoyanchev changed the title Jetty10RequestUpgradeStrategy - HandshakeFailureException: Failed to upgrade; nested exception is java.lang.IllegalArgumentException: org.eclipse.jetty.websocket.server.JettyWebSocketCreator referenced from a method is not visible from class loader Jetty10RequestUpgradeStrategy - JettyWebSocketCreator referenced from a method is not visible from class loader Jan 31, 2023
@rstoyanchev rstoyanchev changed the title Jetty10RequestUpgradeStrategy - JettyWebSocketCreator referenced from a method is not visible from class loader "JettyWebSocketCreator referenced from a method is not visible from class loader" with Jetty10RequestUpgradeStrategy Jan 31, 2023
@rstoyanchev rstoyanchev changed the title "JettyWebSocketCreator referenced from a method is not visible from class loader" with Jetty10RequestUpgradeStrategy JettyWebSocketCreator referenced from a method is not visible from class loader with Jetty10RequestUpgradeStrategy Jan 31, 2023
@rstoyanchev rstoyanchev added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 31, 2023
@rstoyanchev
Copy link
Contributor

@2is10, I've updated how JettyWebSocketCreator is created to refer to the same ClassLoader as the one in which the Class itself was loaded. If you're able to give it a try and confirm it works for you with a 5.3.26-SNAPSHOT that would be great.

@2is10
Copy link
Author

2is10 commented Feb 14, 2023

@rstoyanchev Missed the earlier notification. Will try this out. Thank you!

@rstoyanchev
Copy link
Contributor

Thanks, that would be great! I can't reproduce the issue myself, but I did try with a sample to confirm the change works.

@2is10
Copy link
Author

2is10 commented Mar 1, 2023

Hmm. 5.3.26-SNAPSHOT is not found in our configured maven repositories. I may just wait for release 5.3.26 to confirm the fix.

@bclozel
Copy link
Member

bclozel commented Mar 1, 2023

@2is10 You can configure additional repositories like this:

  <repositories>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
    <repository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <releases>
        <enabled>false</enabled>
      </releases>
    </repository>
  </repositories>

or this:

repositories {
  mavenCentral()
  maven { url 'https://repo.spring.io/milestone' }
  maven { url 'https://repo.spring.io/snapshot' }
}

@2is10
Copy link
Author

2is10 commented Mar 17, 2023

Thanks @bclozel. I just tried again with 5.3.26-SNAPSHOT. JettyWebSocketCreator is now accessible, but a NullPointerException occurs in Jetty10RequestUpgradeStrategy a few lines later. The container returned here is null:

Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext);

The method invoked by reflection there is JettyWebSocketServerContainer.getContainer:

public static JettyWebSocketServerContainer getContainer(ServletContext servletContext)
{
    return (JettyWebSocketServerContainer)servletContext.getAttribute(JETTY_WEBSOCKET_CONTAINER_ATTRIBUTE);
}

That returns null if JettyWebSocketServerContainer.ensureContainer is never called. There is a single caller of that method in that library (websocket-jetty-server-10.0.14.jar): JettyWebSocketServletContainerInitializer.initialize. Its doc says it should be invoked via JettyWebSocketServletContainerInitializer.configure. Is that Spring’s job or mine?

@bclozel
Copy link
Member

bclozel commented Mar 17, 2023

Rossen did verify the fix with a sample, but maybe your application has a different setup or use case. Could you share a minimal sample that demonstrates the issue?

@2is10
Copy link
Author

2is10 commented Mar 20, 2023

Our server code is nearly 10 years old, quite large, and doesn’t use Spring Boot. It would take me hours to produce a minimal sample. Here’s an idea. Could you run your sample with a breakpoint in JettyWebSocketServletContainerInitializer.initialize and share the stack trace? That would help me understand how you expect it to get called.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

4 participants