我正在编写我的@ServerEndpoint
的一些集成测试,在最终运行端点之后,我现在在@OnOpen
中得到一个nullpointer,因为注入失败了。
我已经在github上传了代码:https://github.com/runarhk/Websockets-Test
端点的定义如下:
@ServerEndpoint("/test")
public class MyEndpoint{
@Inject
private SessionHandler sessionHandler;
@OnOpen
public void open(Session session) {
sessionHandler.addSession(session);//sessionhandler is @Singleton
}
@OnClose
public void close(Session session) {
}
@OnError
public void onError(Throwable error) {
}
@OnMessage
public void handleMessage(String payload, Session session) {
}
}
@Singleton
public class SessionHandler {
public void addSession(Session session){}
}
@ClientEndpoint
public class SocketClient {
@OnOpen
public void onOpen(Session session) {
}
@OnMessage
public void onMessage(String message, Session session) {
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
LOGGER.info(String.format("Session %s close because of %s", session.getId(), closeReason));
}
public SocketClient openConnection(URL url) {//URL injected arquillian resource, where url is for http connection..
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
try {
SocketClient client = new SocketClient();
URI uri = URI.create(url.toString().replace("http", "ws") + "test");
container.connectToServer(client, uri);
return client;
} catch (DeploymentException | IOException ex) {
LOGGER.log(Level.SEVERE, null, ex);
throw new RuntimeException(ex);
}
}
public void closeConnection() {
try {
session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "Client requested close"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
我的测试是用spock编写的,在设置中失败
@RunWith(ArquillianSputnik)
class SocketIT extends Specification {
@Deployment
public static Archive archive() {
return ShrinkWrap.create(WebArchive.class, "test-sockets.war")
.addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"))
.addClasses(MyEndpoint.class, SessionHandler.class);
}
@ArquillianResource
URL url;
SocketClient client;
def setup() {
client = SocketClient.openConnection(url);
}
def cleanup() {
client.closeConnection();
}
def 'test connection'() {
given: 'payload'
def payload = "abc"
when: 'sending payload'
client.sendMessage(payload)
then: 'it should not fail'
ass
}
}
我的pom:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>slimy</groupId>
<artifactId>test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tomee.version>1.7.2</tomee.version>
<tomcat.version>7.0.65</tomcat.version>
</properties>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.5</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.5.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- TEST DEPENDENCIES -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.spock</groupId>
<artifactId>arquillian-spock-container</artifactId>
<version>1.0.0.Beta3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>0.7-groovy-2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.1.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat7-websocket</artifactId>
<version>${tomcat.version}</version>
<scope>test</scope>
</dependency>
<!-- For Arquillian Integration tests in TOMEE -->
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>tomee-embedded</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
我的Arquillian.xml文件如下所示:
<?xml version="1.0"?>
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://jboss.org/schema/arquillian"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://www.jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="tomee" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
</configuration>
</container>
</arquillian>
编辑: 我刚下载到1.7.2-plus并在那里运行我的应用程序。它就像一个魅力。那么这可能与tomee-embedded不是一个加号变体有关?
编辑:运行测试时的日志:
INFO: OpenWebBeans Container is starting...
nov 12, 2015 7:06:28 PM org.apache.webbeans.plugins.PluginLoader startUp
INFO: Adding OpenWebBeansPlugin : [CdiPlugin]
nov 12, 2015 7:06:28 PM org.apache.webbeans.plugins.PluginLoader startUp
INFO: Adding OpenWebBeansPlugin : [OpenWebBeansJsfPlugin]
nov 12, 2015 7:06:28 PM org.apache.webbeans.config.BeansDeployer validateInjectionPoints
INFO: All injection points were validated successfully.
nov 12, 2015 7:06:28 PM org.apache.openejb.cdi.OpenEJBLifecycle startApplication
INFO: OpenWebBeans Container has started, it took 255 ms.
nov 12, 2015 7:06:28 PM org.apache.openejb.assembler.classic.Assembler startEjbs
INFO: Created Ejb(deployment-id=SessionHandler, ejb-name=SessionHandler, container=Default Singleton Container)
nov 12, 2015 7:06:28 PM org.apache.openejb.assembler.classic.Assembler startEjbs
INFO: Started Ejb(deployment-id=SessionHandler, ejb-name=SessionHandler, container=Default Singleton Container)
nov 12, 2015 7:06:28 PM org.apache.openejb.assembler.classic.Assembler createApplication
INFO: Deployed Application(path=C:\Users\RunarKristiansen\AppData\Local\Temp\arquillian-tomee-app-working-dir\0\test-sockets)
nov 12, 2015 7:06:29 PM socket.MyEndpoint onError
SEVERE: null
java.lang.NullPointerException
at socket.MyEndpoint.open(MyEndpoint.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:66)
at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:70)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:138)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:651)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
nov 12, 2015 7:06:29 PM org.apache.tomcat.websocket.pojo.PojoEndpointBase onClose
SEVERE: Failed to call onClose method of POJO end point for POJO of type [socket.MyEndpoint]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.tomcat.websocket.pojo.PojoEndpointBase.onClose(PojoEndpointBase.java:107)
at org.apache.tomcat.websocket.WsSession.fireEndpointOnClose(WsSession.java:501)
at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:456)
at org.apache.tomcat.websocket.WsSession.close(WsSession.java:422)
at org.apache.tomcat.websocket.WsSession.close(WsSession.java:416)
at org.apache.tomcat.websocket.pojo.PojoEndpointBase.handleOnOpenError(PojoEndpointBase.java:96)
at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:79)
at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:70)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:138)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:651)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at socket.MyEndpoint.close(MyEndpoint.java:29)
... 19 more
nov 12, 2015 7:06:29 PM utils.SocketClient onClose
INFO: Session 0 close because of CloseReason: code [1000], reason [null]
java.lang.IllegalStateException: The WebSocket session [0] has been closed and no method (apart from close()) may be called on a closed session
at org.apache.tomcat.websocket.WsSession.checkState(WsSession.java:710)
at org.apache.tomcat.websocket.WsSession.getBasicRemote(WsSession.java:409)
at utils.SocketClient.sendMessage(SocketClient.java:64)
at socket.SocketIT.test connection(SocketIT.groovy:42)
nov 12, 2015 7:06:29 PM org.apache.openejb.assembler.classic.Assembler destroyApplication
INFO: Undeploying app: C:\Users\RunarKristiansen\AppData\Local\Temp\arquillian-tomee-app-working-dir\0\test-sockets
nov 12, 2015 7:06:30 PM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-bio-20001"]
nov 12, 2015 7:06:30 PM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["http-bio-20001"]
nov 12, 2015 7:06:30 PM org.apache.catalina.core.StandardService stopInternal
INFO: Stopping service Tomcat
nov 12, 2015 7:06:30 PM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-bio-20001"]`