diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java index a47d3a88b6e..b8c3abc164f 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java @@ -141,23 +141,18 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc private WebSocketServerFactory(ServletContext context, WebSocketPolicy policy, DecoratedObjectFactory objectFactory, Executor executor, ByteBufferPool bufferPool) { this.context = context; + this.defaultPolicy = policy; this.objectFactory = objectFactory; this.executor = executor; - - handshakes.put(HandshakeRFC6455.VERSION, new HandshakeRFC6455()); - - addBean(scheduler); - addBean(bufferPool); - - this.contextClassloader = Thread.currentThread().getContextClassLoader(); - - this.defaultPolicy = policy; - this.eventDriverFactory = new EventDriverFactory(this); this.bufferPool = bufferPool; - this.extensionFactory = new WebSocketExtensionFactory(this); - this.sessionFactories.add(new WebSocketSessionFactory(this)); this.creator = this; + this.contextClassloader = Thread.currentThread().getContextClassLoader(); + this.eventDriverFactory = new EventDriverFactory(this); + this.extensionFactory = new WebSocketExtensionFactory(this); + + this.handshakes.put(HandshakeRFC6455.VERSION, new HandshakeRFC6455()); + this.sessionFactories.add(new WebSocketSessionFactory(this)); // Create supportedVersions List versions = new ArrayList<>(); @@ -176,6 +171,9 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc rv.append(v); } supportedVersions = rv.toString(); + + addBean(scheduler); + addBean(bufferPool); } public void addSessionListener(WebSocketSession.Listener listener) diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerFactoryTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerFactoryTest.java new file mode 100644 index 00000000000..29b6b0cbddd --- /dev/null +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerFactoryTest.java @@ -0,0 +1,77 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.server; + +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.Executor; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.log.StdErrLog; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.websocket.api.WebSocketBehavior; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.junit.Test; + +public class WebSocketServerFactoryTest +{ + private int setLogLevel(Class clazz, int newLevel) + { + int oldLevel = StdErrLog.LEVEL_DEFAULT; + Logger logger = Log.getLogger(clazz); + if (logger instanceof StdErrLog) + { + StdErrLog stdErrLog = (StdErrLog) logger; + oldLevel = stdErrLog.getLevel(); + stdErrLog.setLevel(newLevel); + } + + return oldLevel; + } + + @Test + public void testInit() + { + WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER); + Executor executor = new QueuedThreadPool(); + ByteBufferPool bufferPool = new MappedByteBufferPool(); + + int wsFactoryLevel = setLogLevel(WebSocketServerFactory.class, StdErrLog.LEVEL_DEBUG); + int abstractLifecycleLevel = setLogLevel(AbstractLifeCycle.class, StdErrLog.LEVEL_DEBUG); + int containerLifecycleLevel = setLogLevel(ContainerLifeCycle.class, StdErrLog.LEVEL_DEBUG); + try + { + WebSocketServerFactory wsFactory = new WebSocketServerFactory(policy, executor, bufferPool); + // The above init caused NPE due to bad constructor initialization order with debug active + assertThat("wsFactory.toString()", wsFactory.toString(), notNullValue()); + } + finally + { + setLogLevel(WebSocketServerFactory.class, wsFactoryLevel); + setLogLevel(AbstractLifeCycle.class, abstractLifecycleLevel); + setLogLevel(ContainerLifeCycle.class, containerLifecycleLevel); + } + } +}