TyrusSession implements Session, DistributedSession { @Override public void close() throws IOException { cleanAfterClose(); changeStateToClosed(); basicRemote.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, null)); } TyrusSession(WebSocketContainer container, TyrusWebSocket socket, TyrusEndpointWrapper endpointWrapper,
                 String subprotocol, List<Extension> extensions, boolean isSecure,
                 URI requestURI, String queryString, Map<String, String> pathParameters, Principal principal,
                 Map<String, List<String>> requestParameterMap, final ClusterContext clusterContext,
                 String connectionId, final String remoteAddr, DebugContext debugContext); @Override String getProtocolVersion(); @Override String getNegotiatedSubprotocol(); @Override javax.websocket.RemoteEndpoint.Async getAsyncRemote(); @Override javax.websocket.RemoteEndpoint.Basic getBasicRemote(); @Override boolean isOpen(); @Override void close(); @Override void close(CloseReason closeReason); @Override int getMaxBinaryMessageBufferSize(); @Override void setMaxBinaryMessageBufferSize(int maxBinaryMessageBufferSize); @Override int getMaxTextMessageBufferSize(); @Override void setMaxTextMessageBufferSize(int maxTextMessageBufferSize); @Override Set<Session> getOpenSessions(); Set<RemoteSession> getRemoteSessions(); Set<DistributedSession> getAllSessions(); @Override List<Extension> getNegotiatedExtensions(); @Override long getMaxIdleTimeout(); @Override void setMaxIdleTimeout(long maxIdleTimeout); @Override boolean isSecure(); @Override WebSocketContainer getContainer(); @Override void addMessageHandler(MessageHandler handler); @Override void addMessageHandler(Class<T> clazz, MessageHandler.Whole<T> handler); @Override void addMessageHandler(Class<T> clazz, MessageHandler.Partial<T> handler); @Override Set<MessageHandler> getMessageHandlers(); @Override void removeMessageHandler(MessageHandler handler); @Override URI getRequestURI(); @Override Map<String, List<String>> getRequestParameterMap(); @Override Map<String, String> getPathParameters(); @Override Map<String, Object> getUserProperties(); @Override Map<String, Object> getDistributedProperties(); @Override String getQueryString(); @Override String getId(); @Override Principal getUserPrincipal(); Map<Session, Future<?>> broadcast(String message); Map<Session, Future<?>> broadcast(ByteBuffer message); long getHeartbeatInterval(); void setHeartbeatInterval(long heartbeatInterval); @Override String toString(); String getRemoteAddr();  }
@Test public void testIdleTimeoutFutureIsCanceled() throws IOException { final AtomicBoolean canceled = new AtomicBoolean(false); final InvocationHandler scheduledFutureHandler = (proxy, method, args) -> { switch (method.getName()) { case "cancel": canceled.set(true); return true; default: return null; } }; final InvocationHandler scheduledExecutorServiceHandler = (proxy, method, args) -> { switch (method.getName()) { case "schedule": return Proxy.newProxyInstance( getClass().getClassLoader(), new Class[]{ScheduledFuture.class}, scheduledFutureHandler ); default: return null; } }; final WebSocketContainer webSocketContainer = new TestContainer() { @Override public ScheduledExecutorService getScheduledExecutorService() { return (ScheduledExecutorService) Proxy.newProxyInstance( getClass().getClassLoader(), new Class[]{ScheduledExecutorService.class}, scheduledExecutorServiceHandler ); } }; final Session session = createSession(endpointWrapper, webSocketContainer); session.close(); assertTrue(canceled.get()); }