Repository: netty/netty
Issue: suggestion: netty/example/objectecho inform about missing "implements Serializable" on client side

Hello,

as new user i wanted to try Objectecho "Example", and was confused when i sent **Serializable Object** that were **containing** an **"non-serializable" Object** as some depth field(that i didnt notice earlier), it was not sent at all, and i received no information at all. It took me time to debug and notice that one of its fields was an object that didnt implement Serializable.

Thats why i just throw some suggestion to add into "Objectecho Example" some new user friendly code to inform about it like:

**1)** some "Objectecho Example"  class extending ObjectEncoder:

    @Override
    public boolean acceptOutboundMessage(Object msg) throws Exception {
        if(!super.acceptOutboundMessage(msg)){
            // some information
        }
        return true;
    }

**OR**

(i didnt try enable Asserts, so if you use some, this option might be better)
**2)** **Just add comment about it**, to let new users know they will receive NO information when trying to send complex Objects that in some depth contains non-serializable Object.

**Please note this refer only to "Objectecho Example"  and Encoder (so its client side).** 

Just thought it could be helpfull for new users having same problem.

### Expected behavior

- some warning/error/information for "Objectecho Example"  if there is missing Serializable

### Actual behavior

- Demo give NO information if sent object do not match, client and server print **no information/warning/error at all.**

### Steps to reproduce

- in "Objectecho Example"  try sent Serializable object with not serializable Object in it, it will not be sent and no information will be printed anywhere. Also comments do not mention anything about it.

### Netty version

4.1.43

And ofc, hello to netty users/devs ;)

Please close it if "Objectecho Example" is not prepared for new users and its for testing purpose, or if you think its not needed, since its just suggestion.

Issue comments:
Enable `DEBUG` log level.
if you mean:

p.addLast(new LoggingHandler(LogLevel.DEBUG));

do not help. No information is printed. **(using non-serialized object - that dont work)**

--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
**BELOW IS WORKING CASE(when i use serialized object), BUT PROBABLY FOUND SOME new BUG**:

Anyway im not sure if i found some BUG or what.
im having Client+Server in same application(just in 2 threads),

by default without logging i have:

> lis 07, 2020 1:08:56 PM io.netty.handler.logging.LoggingHandler channelRegistered
> INFO: [id: 0x70dbfa79] REGISTERED
> lis 07, 2020 1:08:56 PM io.netty.handler.logging.LoggingHandler bind
> INFO: [id: 0x70dbfa79] BIND: 0.0.0.0/0.0.0.0:6143
> lis 07, 2020 1:08:56 PM io.netty.handler.logging.LoggingHandler channelActive
> INFO: [id: 0x70dbfa79, L:/0:0:0:0:0:0:0:0:6143] ACTIVE
> lis 07, 2020 1:08:56 PM io.netty.handler.logging.LoggingHandler channelRead
> INFO: [id: 0x70dbfa79, L:/0:0:0:0:0:0:0:0:6143] READ: [id: 0x1ff7f916, L:/127.0.0.1:6143 - R:/127.0.0.1:59428]
> lis 07, 2020 1:08:56 PM io.netty.handler.logging.LoggingHandler channelReadComplete
> INFO: [id: 0x70dbfa79, L:/0:0:0:0:0:0:0:0:6143] READ COMPLETE
> Server Channel Active
> ByteBuf out size: 256

when i add for example 

p.addLast(new LoggingHandler(LogLevel.WARN));

i have:

> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler channelRegistered
> INFO: [id: 0x47da6a0b] REGISTERED
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler channelRegistered
> WARNING: [id: 0x107f76a8] REGISTERED
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler connect
> WARNING: [id: 0x107f76a8] CONNECT: localhost/127.0.0.1:6143
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler bind
> INFO: [id: 0x47da6a0b] BIND: 0.0.0.0/0.0.0.0:6143
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler channelActive
> INFO: [id: 0x47da6a0b, L:/0:0:0:0:0:0:0:0:6143] ACTIVE
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler channelActive
> WARNING: [id: 0x107f76a8, L:/127.0.0.1:59414 - R:localhost/127.0.0.1:6143] ACTIVE
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler channelRead
> INFO: [id: 0x47da6a0b, L:/0:0:0:0:0:0:0:0:6143] READ: [id: 0x1c26ccdb, L:/127.0.0.1:6143 - R:/127.0.0.1:59414]
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler channelReadComplete
> INFO: [id: 0x47da6a0b, L:/0:0:0:0:0:0:0:0:6143] READ COMPLETE
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler channelRegistered
> WARNING: [id: 0x1c26ccdb, L:/127.0.0.1:6143 - R:/127.0.0.1:59414] REGISTERED
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler channelActive
> WARNING: [id: 0x1c26ccdb, L:/127.0.0.1:6143 - R:/127.0.0.1:59414] ACTIVE
> Server Channel Active
> ByteBuf out size: 256
> lis 07, 2020 1:05:02 PM io.netty.handler.logging.LoggingHandler write
> WARNING: [id: 0x1c26ccdb, L:/127.0.0.1:6143 - R:/127.0.0.1:59414] WRITE: 98B
>          +-------------------------------------------------+
>          |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
> +--------+-------------------------------------------------+----------------+
> 

and when i set 

p.addLast(new LoggingHandler(LogLevel.ERROR));

i see:

> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler channelRegistered
> INFO: [id: 0xc67da6c8] REGISTERED
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler channelRegistered
> SEVERE: [id: 0x80004f41] REGISTERED
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler connect
> SEVERE: [id: 0x80004f41] CONNECT: localhost/127.0.0.1:6143
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler bind
> INFO: [id: 0xc67da6c8] BIND: 0.0.0.0/0.0.0.0:6143
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler channelActive
> INFO: [id: 0xc67da6c8, L:/0:0:0:0:0:0:0:0:6143] ACTIVE
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler channelActive
> SEVERE: [id: 0x80004f41, L:/127.0.0.1:59420 - R:localhost/127.0.0.1:6143] ACTIVE
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler channelRead
> INFO: [id: 0xc67da6c8, L:/0:0:0:0:0:0:0:0:6143] READ: [id: 0x223834f5, L:/127.0.0.1:6143 - R:/127.0.0.1:59420]
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler channelReadComplete
> INFO: [id: 0xc67da6c8, L:/0:0:0:0:0:0:0:0:6143] READ COMPLETE
> Server Channel Active
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler channelRegistered
> SEVERE: [id: 0x223834f5, L:/127.0.0.1:6143 - R:/127.0.0.1:59420] REGISTERED
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler channelActive
> SEVERE: [id: 0x223834f5, L:/127.0.0.1:6143 - R:/127.0.0.1:59420] ACTIVE
> ByteBuf out size: 256
> lis 07, 2020 1:06:43 PM io.netty.handler.logging.LoggingHandler write
> SEVERE: [id: 0x223834f5, L:/127.0.0.1:6143 - R:/127.0.0.1:59420] WRITE: 98B
>          +-------------------------------------------------+
>          |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
> +--------+-------------------------------------------------+----------------+

While EVERYTHING WORK FINE (since i use serialialized object in this example)

how can i know if this is SEVERE or WARN or INFO, while it just depends what level i set, it anyway print same info that is harmless...

**or myabe i just dont understand what "LoggingHandler" is for**







This should help: https://github.com/netty/netty/pull/10807

Pull request review comments:
@chrisvest this doesn't work as this will block the eventloop. Use a `ChannelFutureListener` 
please revert this change ^^

Patch that resolved the issue:
diff --git a/example/src/main/java/io/netty/example/objectecho/ObjectEchoClientHandler.java b/example/src/main/java/io/netty/example/objectecho/ObjectEchoClientHandler.java
index 07f2f6bcf01..314747180fb 100644
--- a/example/src/main/java/io/netty/example/objectecho/ObjectEchoClientHandler.java
+++ b/example/src/main/java/io/netty/example/objectecho/ObjectEchoClientHandler.java
@@ -15,12 +15,16 @@
  */
 package io.netty.example.objectecho;
 
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import static io.netty.channel.ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE;
+
 /**
  * Handler implementation for the object echo client.  It initiates the
  * ping-pong traffic between the object echo client and server by sending the
@@ -43,7 +47,8 @@ public ObjectEchoClientHandler() {
     @Override
     public void channelActive(ChannelHandlerContext ctx) {
         // Send the first message if this handler is a client-side handler.
-        ctx.writeAndFlush(firstMessage);
+        ChannelFuture future = ctx.writeAndFlush(firstMessage);
+        future.addListener(FIRE_EXCEPTION_ON_FAILURE); // Let object serialisation exceptions propagate.
     }
 
     @Override


Test patch: