ContainerProvider的独立Java Websocket客户端NoClassDefFoundError

时间:2015-12-05 17:26:30

标签: java maven websocket client tyrus

我是Java的新手,但我必须用它来做一个与WebSocket相关的小项目。

因此,我在我的CentOS 7上的VirtualBox中安装了JDK 1.8.0和NetBeans 8.1。

我在 pom.xml 中添加了 tyrus-standalone-client-jdk 1.12 插件,以构建独立的Websocket客户端,并且构建得很好。但是,我遇到了以下错误:

[root@cet7 ~]# java -jar "/root/NetBeansProjects/Switchclient/target/Switchclient-1.0-SNAPSHOT.jar"

Exception in thread "main" java.lang.NoClassDefFoundError: javax/websocket/ContainerProvider
    at org.sample.switchclient.Switchclient.main(Switchclient.java:21)
Caused by: java.lang.ClassNotFoundException: javax.websocket.ContainerProvider
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

[root@cet7 ~]# java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)

我做了一些搜索,发现ContainerProvider的容器实现的完全限定类名必须列在 META-INF / services / javax.websocket.ContainerProvider < / em>文件在实现JAR文件&#34;适用于根据Oracle文档的ServiceLoader API。所以,我将 serviceloader-maven-plugin 添加到pom.xml中。结果是它确实生成了 META-INF / services / javax.websocket.ContainerProvider 文件,但没有任何内容,并且运行时错误继续存在。我尝试手动修改内容并将其重新打包到JAR中但它没有用:

  1. org.glassfish.tyrus.container.inmemory.InMemoryContainerProvider
  2. org.glassfish.tyrus.client.ClientManager
  3. 我已经附加了Java文件和 pom.xml 。我已经工作了几个小时,并且无法确定问题是什么,所以对此线程的任何回复都将受到赞赏。

    非常感谢。

    =========== LIST1:pom.xml ===========

    <?xml version="1.0" encoding="UTF-8"?>
    <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>org.sample</groupId>
        <artifactId>Switchclient</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>2.6</version>
                    <configuration>
                        <archive>
                <manifest>
                                <addClasspath>true</addClasspath>
                                <mainClass>org.sample.switchclient.Switchclient</mainClass>
                </manifest>
                        </archive>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>eu.somatik.serviceloader-maven-plugin</groupId>
                    <artifactId>serviceloader-maven-plugin</artifactId>
                    <version>1.0.6</version>
                    <configuration>
                        <services>
                            <param>javax.websocket.ContainerProvider</param>
                        </services>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>generate</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
        <dependencies>
            <dependency>
                <groupId>org.glassfish.tyrus.bundles</groupId>
                <artifactId>tyrus-standalone-client-jdk</artifactId>
                <version>1.12</version>
            </dependency>
        </dependencies>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
    
    </project>
    

    =========== LIST2:Switchclient.java ===========
        包org.sample.switchclient;

    import java.net.URI;
    import javax.websocket.ClientEndpoint;
    import javax.websocket.ContainerProvider;
    import javax.websocket.OnMessage;
    import javax.websocket.Session;
    import javax.websocket.WebSocketContainer;
    
    @ClientEndpoint
    public class Switchclient {
        @OnMessage
        public void onRemoteMessage (String message) {
            System.out.println("Received msg: "+message); 
        }
    
        public static void main(String[] args) {
            WebSocketContainer container = null;
            Session session = null;
            try{
                container = ContainerProvider.getWebSocketContainer();
                session = container.connectToServer (Switchclient.class, URI.create("ws://localhost:8080/Switchserver/"));
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

2 个答案:

答案 0 :(得分:5)

基本上,Tyrus需要 Java EE 。这就是你必须在pom.xml中列出很多依赖项的原因。如果您使用Java SE并希望保持项目较小,请使用另一个仅依赖于Java SE的WebSocket客户端库。例如, nv-websocket-client (我的)。

只需将以下依赖项添加到pom.xml

即可
<dependency>
    <groupId>com.neovisionaries</groupId>
    <artifactId>nv-websocket-client</artifactId>
    <version>1.13</version>
</dependency>

然后尝试:

import com.neovisionaries.ws.client.*;

public class Switchclient
{
    public static void main(String[] args) throws Exception
    {
        WebSocket websocket = new WebSocketFactory()
            .createSocket("ws://localhost:8080/Switchserver/")
            .addListener(new WebSocketAdapter() {
                @Override
                public void onTextMessage(WebSocket ws, String message) {
                    System.out.println("Received msg: " + message);
                }
            })
            .connect();

        // Don't forget to call disconnect() after use.
        // websocket.disconnect();
    }
}

答案 1 :(得分:2)

我不确定究竟是什么导致了这个问题,因为我一直在努力,问题在过去的一天里不断跳出来。但最后是这样的:
客户端依赖:

        <dependency>
        <groupId>javax.websocket</groupId>
        <artifactId>javax.websocket-client-api</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.tyrus.bundles</groupId>
        <artifactId>tyrus-standalone-client</artifactId>
        <version>1.12</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.tyrus</groupId>
        <artifactId>tyrus-container-grizzly-client</artifactId>
        <version>1.12</version>
    </dependency>

乍一看似乎javax.websocket-client-api应该足够了但最终网络说ContainerProvider不是障碍

然后,所有内置OK。 (使用我原始帖子中的不同java代码,我尝试了很多包括源代码,但是代码本身并不重要,而环境设置很重要。它们主要基于然而,Tyrus 1.9 user guide的例子。)

然后由maven从NetBeans运行就可以了,但是当我去使用&#34; java -jar Switchclient.jar&#34;时,同样/类似的问题跳出来说&#34; Endpoint&#34的问题;

最后(作为最后一次尝试)我复制了包含在类路径中的所有tar文件(由maven-jar-plugin生成,指定&#34; <addClasspath>true<addClasspath>&#34;到一个目录中,还复制了生成的jar文件,然后它起作用了:

[root @ cet7 neededjars] #ls
grizzly-framework-2.3.22.jar tyrus-client-1.12.jar
grizzly-http-2.3.22.jar tyrus-container-grizzly-client-1.12.jar
grizzly-http-server-2.3.22.jar tyrus-core-1.12.jar
javax.websocket-api-1.1.jar tyrus-spi-1.12.jar
javax.websocket-client-api-1.1.jar tyrus-standalone-client-1.12.jar
Switchclient-1.1-SNAPSHOT.jar
[root @ cet7 neededjars] #java -jar Switchclient-1.1-SNAPSHOT.jar
收到消息:Hello world

这就是它,肮脏而又有效。我开始了一个新的开始。再一次,我是java的新手(其中一个非硬技术人员,只是在需要的时候拿起它);它向我展示了基于社区的发展的共谋,特别是在技术相对较新的情况下。各地的依赖和陷阱。这是我猜的性质的一部分......