Websocket 使用web套接字的Arquillian TomEE嵌入式测试中的CDI注入

Websocket 使用web套接字的Arquillian TomEE嵌入式测试中的CDI注入,websocket,cdi,spock,jboss-arquillian,apache-tomee,Websocket,Cdi,Spock,Jboss Arquillian,Apache Tomee,我正在为我的@ServerEndpoint编写一些集成测试,在最终让端点运行之后,我现在在@OnOpen中得到一个空指针,因为注入失败 我已经在github上上传了代码: 端点的定义如下所示: @ServerEndpoint("/test") public class MyEndpoint{ @Inject private SessionHandler sessionHandler; @OnOpen public void open(Session sessi

我正在为我的
@ServerEndpoint
编写一些集成测试,在最终让端点运行之后,我现在在
@OnOpen
中得到一个空指针,因为注入失败

我已经在github上上传了代码:

端点的定义如下所示:

@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);
        }
    }
}
<?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>
我的测试是用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>

您在可部署war中打包了SessionHandler,但显示了GameSessionHandler。你可以编辑你的帖子来反映你所拥有的吗?很抱歉,现在已经修复了,我认为所有需要复制的代码都在帖子中提供了。你仍然显示一个没有定义的GameSessionHandler类型。无论如何,我建议查看tom ee/open webbeans组件生成的日志,以查看bean(即SessionHandler)是否由于某种原因(例如,档案中没有引用的类)而未以静默方式加载。如果需要,您可以使用自定义日志记录。您是否尝试向文件
arquillian.xml
中添加一行
?这只会使容器无法启动,添加
javax.servlet:javax.servlet api
依赖项并不能修复它。。
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"]`