0

I am trying to use websockets in my application to provide one-to-one private messaging. I have been following this project in my implementation. With my front project in angular I am able to establish the connection with the cloned chat service from the authors github, but when I try to connect to my own, I am getting this error:

2020-11-04 19:21:53.918 ERROR 21648 --- [nio-7000-exec-9] o.s.w.s.m.StompSubProtocolHandler        : Failed to parse TextMessage payload=[CONNECT
ac..], byteCount=56, last=true] in session 0vmhpgm0. Sending STOMP ERROR to client.

java.lang.NoSuchMethodError: 'java.lang.String org.springframework.util.StreamUtils.copyToString(java.io.ByteArrayOutputStream, java.nio.charset.Charset)'
    at org.springframework.messaging.simp.stomp.StompDecoder.readCommand(StompDecoder.java:220) ~[spring-messaging-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.messaging.simp.stomp.StompDecoder.decodeMessage(StompDecoder.java:143) ~[spring-messaging-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.messaging.simp.stomp.StompDecoder.decode(StompDecoder.java:115) ~[spring-messaging-5.2.10.RELEASE.jar:5.2.10.RELEASE]

The only difference between my project and the other one is that I use postgres, so my repo and service differs, but this code is never reached before the error, as I put breakpoints all around the place and none hit. I cant figure out what the error in this really means, as it's very vague and doesn't point me in any specific direction.

My config:


@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/user");
        config.setApplicationDestinationPrefixes("/app");
        config.setUserDestinationPrefix("/user");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry
                .addEndpoint("/ws")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    @Override
    public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
        DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
        resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setObjectMapper(new ObjectMapper());
        converter.setContentTypeResolver(resolver);
        messageConverters.add(converter);
        return false;
    }
}

Chat controller:


@Controller
public class ChatController {

    @Autowired private SimpMessagingTemplate messagingTemplate;
    @Autowired private ChatMessageService chatMessageService;
    @Autowired private ChatRoomService chatRoomService;

    @MessageMapping("/chat")
    public void processMessage(@Payload ChatMessage chatMessage) {
        var chatId = chatRoomService
                .getChatId(chatMessage.getSenderId(), chatMessage.getRecipientId(), true);
        chatMessage.setChatId(chatId.get());

        ChatMessage saved = chatMessageService.save(chatMessage);
        messagingTemplate.convertAndSendToUser(
                chatMessage.getRecipientId().toString(),"/queue/messages",
                new ChatNotification(
                        saved.getId(),
                        saved.getSenderId(),
                        saved.getSenderName()));
    }

    @GetMapping("/messages/{senderId}/{recipientId}/count")
    public ResponseEntity<Long> countNewMessages(
            @PathVariable UUID senderId,
            @PathVariable UUID recipientId) {

        return ResponseEntity
                .ok(chatMessageService.countNewMessages(senderId, recipientId));
    }

    @GetMapping("/messages/{senderId}/{recipientId}")
    public ResponseEntity<?> findChatMessages ( @PathVariable UUID senderId,
                                                @PathVariable UUID recipientId) {
        return ResponseEntity
                .ok(chatMessageService.findChatMessages(senderId, recipientId));
    }

    @GetMapping("/messages/{id}")
    public ResponseEntity<?> findMessage ( @PathVariable UUID id) {
        return ResponseEntity
                .ok(chatMessageService.findById(id));
    }
}

As I said, my front-end should not be a problem, as it is connecting with the other backend, but just to be sure here is my angular snippet:

import * as Stomp from 'stompjs';
import * as SockJS from 'sockjs-client';
// ...

  connect() {
    const sockJS = new SockJS(API_URL + 'ws');
    this.stompClient = Stomp.over(sockJS);
    this.stompClient.connect({}, this.onConnected, this.onError);
  }

I would gladly appreciate some help, as I don't even know what could be broken/missing, its my first time even using websockets and I can't find similiar problems online.

EDIT: added pom file as requested:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>pl.edu.pjatk.mroz</groupId>
    <artifactId>project-API</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>project-API</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>

        <!--SPRING-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>5.3.1.RELEASE</version>
        </dependency>

        <!--SPRINGBOOT-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.6.RELEASE</version>

        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>


        <dependency>
            <groupId>com.corundumstudio.socketio</groupId>
            <artifactId>netty-socketio</artifactId>
            <version>1.7.18</version>
        </dependency>



        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.12</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mindrot</groupId>
            <artifactId>jbcrypt</artifactId>
            <version>0.4</version>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <!-- API, java.xml.bind module -->
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>2.3.2</version>
        </dependency>

        <!-- Runtime, com.sun.xml.bind module -->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.885</version>
        </dependency>


        <!--testing-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.2.6.RELEASE</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <version>5.3.1.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>

    <build>
        <finalName>rental</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.4.RELEASE</version>
            </plugin>
        </plugins>
    </build>

</project>
2
  • 2
    Judging from the error you have incompatible versions in your dependency management. Which probably means you are trying to outsmart the dependency management solution you are using. Please add your pom or build file to the question. Commented Nov 4, 2020 at 19:04
  • Thanks, updated the question. Commented Nov 4, 2020 at 19:40

3 Answers 3

1

You seem to have messed up dependencies as you use different spring versions.

The culprit of this issue is -

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

Due to this dependency, you are having spring-core-5.2.5.RELEASE.

The logs shows that you are using spring-messaging-5.2.10.RELEASE version which is making use of StreamUtils copyToString method which got added with 5.2.6 version.

If you ensure that you use spring-core-5.2.10.RELEASE version, that should resolve the issue.

You should make use of properties section of your pom. Add a new property for Spring Boot version. Note that spring boot 2.3.1 will pull spring 5.2.10.RELEASE versions.

<properties>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>

        <spring.boot.version>2.3.1.RELEASE</spring.boot.version>
</properties>

Then use it inside dependencies like -

<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot</artifactId>
                <version>${spring.boot.version}</version>
            </dependency>

You should do it similarly for all spring boot starter dependencies. Plus remove those explicit spring dependencies like spring-context.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, thats what I ended up doing - added needed dependencies only when started working on the sockets, didnt even about version mismatch. Best regards!
1

Since you are using spring boot you need to use the same version for all artefacts.

For example in pom.xml you should have something like those lines:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>

Make sure you are using the same versions of springboot dependencies.

edit after you added pom.xml:

Just in case try spring initializer here: https://start.spring.io/ to make sure you have all the correct versions. Compare generated pom.xml with yours.

1 Comment

Thank you, I didn't notice my pom was meesed up due to the fact that the project has been started long time ago. Works like a charm now, best wishes!
1

I run into the same issue but moving to a newer springboot version was not possible. The solution I found was downgrading the spring-messaging version to 5.2.5.RELEASE (and the same for spring-websocket) and it worked.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.