Автономный клиент Java Websocket NoClassDefFoundError от ContainerProvider

Я новичок в Java, но мне нужно использовать его для небольшого проекта, связанного с WebSocket.

Итак, я установил JDK 1.8.0 и NetBeans 8.1 на свой CentOS 7 в VirtualBox.

Я добавил подключаемый модуль tyrus-standalone-client-jdk 1.12 в pom.xml, чтобы создать автономный клиент 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 в файле JAR реализации» для ServiceLoader API согласно документации Oracle. Итак, я добавил 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

Я прикрепил файл Java и файл pom.xml. Я работал несколько часов и понятия не имею, в чем проблема, поэтому любой ответ на эту тему будет оценен.

Большое спасибо.

===========СПИСОК1: 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();
        }
    }
}

person howToDeleteMyAccount    schedule 05.12.2015    source источник


Ответы (2)


По сути, Tyrus требует Java EE. Это причина, по которой вам нужно перечислить множество зависимостей в pom.xml. Если вы используете Java SE и хотите, чтобы ваш проект был небольшим, используйте другую другую клиентскую библиотеку WebSocket, которая зависит только от Java SE. Например, 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();
    }
}
person Takahiko Kawasaki    schedule 08.12.2015
comment
Спасибо, Такахико, и извините за очень поздний ответ. Я думал, что должен сначала проверить этот способ, а затем ответить, но оказалось, что я сосредоточился на многих других моментах, как только я заработал способ Tyrus. Но хорошо иметь решение nv-websocket-client, так как оно зависит только от Java SE. Я скоро перейду на это решение. Еще раз спасибо и с Новым годом ;-) - person howToDeleteMyAccount; 01.01.2016
comment
Еще раз спасибо, Такахико, так как я тестировал, эта клиентская библиотека пока работает нормально ;-) - person howToDeleteMyAccount; 23.01.2016
comment
Привет, я новичок в java, я использую .net. Tyrus требует Java EE. Не могли бы вы предоставить дополнительную информацию или уточнить, какой компонент является частью Java EE? - person gfan; 25.10.2016
comment
Пакет @gfan javax.websocket включает классы для веб-сокета. Спецификация определяется как JSR 356: API Java для WebSocket. - person Takahiko Kawasaki; 25.10.2016
comment
действительно потрясающе ... жаль, что я нашел его, попробовав несколько других способов - person ycomp; 23.08.2017

Я не уверен, что именно вызвало проблему, так как я продолжал пытаться, и проблемы продолжали возникать в течение последнего дня. Но, наконец, вот оно:
Клиентские зависимости:

        <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 должно быть достаточно, но, в конце концов, Cyber ​​сказал, что ContainerProvider не является препятствием.

Затем все собралось нормально. (с другими кодами Java из моего исходного сообщения, я много пытался включить исходные коды, но сами коды не имеют значения, которые совпадают здесь, в то время как настройка окружения имеет значение. Они в основном основаны на примерах однако руководство пользователя Tyrus 1.9.)

И запуск из NetBeans с помощью maven был в порядке, но когда я перешел к использованию «java -jar Switchclient.jar», возникла та же/похожая проблема, говорящая о проблеме с «Конечной точкой».

Наконец (в качестве последней попытки) я скопировал все эти файлы tar, включенные в путь к классам (ведьма была сгенерирована maven-jar-plugin, указав «<addClasspath>true<addClasspath>» в один каталог, а также скопировала сгенерированный файл jar, после чего это сработало: < br>
[root@cet7 needjars]# 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 needjars]# java -jar Switchclient-1.1-SNAPSHOT. jar
Полученное сообщение: Hello world

Вот так, грязно, но работало. и я на новом старте. Опять же, я действительно новичок в java (один из тех, кто не разбирается в технологиях, просто возьмите его в случае необходимости); и это показало мне соучастие в разработке на основе сообщества, особенно в случае, если технология относительно новая. зависимости и ловушки повсюду. Это часть природы, я думаю...

person howToDeleteMyAccount    schedule 06.12.2015