Search code examples
javaspring-bootspring-integration

Spring Integration : No publisher available to publish TCP Connection related events


I am using Spring Integration with Spring Boot. I have a TCP Client [TcpNetClientConnectionFactory] with TcpOutboundGateway setup. I can see the below warnings in Production[No publisher available to publish].

enter image description here Log Snippet

Based on my checking this warning is shown when the org.springframework.context.ApplicationEventPublisher is null.

Code:

@Bean
    @ServiceActivator(inputChannel = "a04A08OutgoingChannel")
    public MessageHandler a04A08OutgoingGate() {
        final TcpOutboundGateway gate = new TcpOutboundGateway();
        // Connection configured in client mode to send the message over the TCP socket
        // and wait for acknowledgement
        gate.setConnectionFactory(connectionFactory.connectionFactory(host, port));
        gate.setReplyChannelName("a04A08ReplyToString");
        gate.setRemoteTimeout(60_000);
        return gate;
    }
    
    @Transformer(inputChannel = "a04A08ReplyToString")
    public String transform(byte[] bytes) {
        String reply = new String(bytes);
        log.debug("transform - a04A08ReplyToString channel " + reply);
        return new String(bytes);
    }
    
    public String outgoingMessage(String message) {
        String reply = null;
        log.info("Message being Sent : " + message);
        try {
            // Send the message to the TCP socket and wait for acknowledgement
            reply = a04a08OutgoingGateway.sendMessage(message);
        } catch (ConnectException e) {
            log.error(e.getMessage(),e);
        }
        log.info("Acknowledgement received : " + reply);
        return reply;
    }

ConnectionFactory.java:

public AbstractClientConnectionFactory connectionFactory(String host, int port) {
        final AbstractClientConnectionFactory connectionFactory = new TcpNetClientConnectionFactory(host, port);
        connectionFactory.setSerializer(customDeserializer);
        connectionFactory.setDeserializer(customDeserializer);
        //connectionFactory.setSoKeepAlive(true);
        connectionFactory.setSingleUse(true);// This property when set to false ensures that one shared connection is used for all
                                                // request/replies and each caller blocks waiting for the socket
        
        return connectionFactory;
    }

Edit 1 : Included CustomDeserializer.java

@Override
    public void serialize(String object, OutputStream outputStream) throws IOException {
        log.info("[Serialize] Serializing data : length ==> " + object.length());
        outputStream.write(object.getBytes());
        log.info("[Serialize] data posted to stream");

    }

    @Override
    public byte[] deserialize(InputStream inputStream) throws IOException {
        log.info("[Deserialize] De-Serializing data");
        BufferedReader input = new BufferedReader(new InputStreamReader(inputStream));

        StringBuffer stringbuffer = new StringBuffer();
        
        while (true) {
            int value = input.read();
            if (value == 28) {
                break;
            } else {
                if (value != -1) {
                    stringbuffer.append((char) value + "");
                } else {
                    break;
                }
            }
        }

        log.info("[deserialize.readFromSocket()]: " + stringbuffer.toString());

        return stringbuffer.toString().getBytes();
    }

The TCP server is able to receive the messages sent by the TCP client. [Note: TCP server is a different system and not maintained by us].I have 2 queries.

  1. Will this warning have any impact? Can anyone elaborate on the warning? Even when the warnings are seen the messages from TCP client are sent to TCP server without any issues.

  2. We faced below issue (Caused by: org.springframework.messaging.MessagingException: Exception while awaiting reply; nested exception is java.net.SocketTimeoutException: Read timed out) in production recently. When we faced the below exception, telnet to the server port worked but the messages were not received by the server. The issue was automatically resolved when the TCP server was restarted. My question : Is this issue related to the warning in point #1. These warnings are seen even on normal days when the messages are sent to the server without any issues.

enter image description here Error logs

P.S: I also checked the post : No publisher available to publish TcpConnectionOpenEvent / TcpConnectionCloseEvent


Solution

  • It is not related; sounds like a server problem if restarting it solves it.

    The connection factory must be declared as a @Bean so that spring can inject the event publisher.