2017-09-29 2 views
1

Ich bin neu in Netzwerk-Bibliotheken und Netty, und ich baue einen Client. Aus meinen Tests verstehe ich, dass mein Code ordnungsgemäß funktioniert, aber ich möchte eine aussagekräftigere Nachricht geben, wenn er nicht richtig mit dem Host verbunden werden kann. Also, was ich getan habe, ist es zu versuchen, es mit localhost am Port verbinden und ich habe nichts gehostet dort, so würde es eine Ausnahme werfen. Unten ist der Stack-Trace:Netty - Handle AnnotatedConnectException

Exception in thread "main" io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /127.0.0.1:8484 
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) 
    at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source) 
    at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:353) 
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:340) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:633) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) 
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) 
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) 
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: java.net.ConnectException: Connection refused: no further information 
    ... 11 more 

ich versucht habe AnnotatedConnectException zu versuchen, Beifang, aber es nicht zu dieser Klasse keine Importe zu sein scheint. Ich vermute, dass diese Klasse in AbstractChannel eine private Ausnahme ist. Ich überprüfte die Umsetzung und es ist:

private static final class AnnotatedConnectException extends ConnectException { 

    private static final long serialVersionUID = 3901958112696433556L; 

    AnnotatedConnectException(ConnectException exception, SocketAddress remoteAddress) { 
     super(exception.getMessage() + ": " + remoteAddress); 
     initCause(exception); 
     setStackTrace(exception.getStackTrace()); 
    } 

    @Override 
    public Throwable fillInStackTrace() { 
     return this; 
    } 
} 

Ich habe auch festgestellt, dass ich, indem Sie einen Try-Catch mit Ausnahme diese Ausnahme umgehen konnte. Ich möchte dies jedoch möglichst vermeiden, da ich denke, dass es eine schreckliche Idee ist. Irgendwelche Ideen, ob das gemacht werden kann und wie?

EDIT: Hier ist mein Versuch, einen Connect zu fangen (. Das gleiche versucht wurde AnnotatedConnectException Dies wurde getan, wo das Connect ist):

public void connectToServer(String host, int port) { 
Bootstrap bootstrap = new Bootstrap(); 
/* 
* Creates/configures the handler group which will handle the connection and keep the connection 
* alive. 
*/ 
EventLoopGroup handlerGroup = new NioEventLoopGroup(); 
bootstrap.group(handlerGroup).channel(NioSocketChannel.class) 
    .option(ChannelOption.SO_KEEPALIVE, true).handler(new ChannelInitializer<SocketChannel>() { 
     @Override 
     protected void initChannel(SocketChannel socketChannel) { 
     /* 
     * Handles a connection when it is connected (ie. decoding/encoding packets and 
     * handling the packets that the server sends back to the client). 
     */ 
     socketChannel.pipeline().addLast("MapleProtocolDecoder", new MapleProtocolDecoder()); 
     socketChannel.pipeline().addLast("ServerHandler", new ServerHandler()); 
     socketChannel.pipeline().addLast("MapleProtocolEncoder", new MapleProtocolEncoder()); 
     } 
    }); 

try { 
    // Connects the client 
    ChannelFuture channelFuture = bootstrap.connect(host, port).sync(); 
    // Waits until the connection is closed 
    channelFuture.channel().closeFuture().sync(); 
} catch (InterruptedException e) { 
    handlerGroup.shutdownGracefully(); 
    System.out.println("[Info] The client has disconnected!"); 
} catch (ConnectException e) { 
    System.out.println(e.getClass().getCanonicalName()); 
    System.out.println("[Info] The server is offline."); 
} 

}

Dank!

+0

Wo ist Ihr Versuch zu versuchen und die Ausnahme zu fangen? –

+0

Ich habe einen Ausschnitt meines Codes hinzugefügt, um zu zeigen, wie ich Ausnahmen versuche. Während das Snippet derzeit ConnectException anzeigt. Es ist die gleiche Idee mit AnnotatedConnectException. – brilam

Antwort

0

Diese Bibliothek wird wahrscheinlich zur Laufzeit von Ihrem Container bereitgestellt und steht Ihnen möglicherweise während der Entwicklung nicht zur Verfügung, ohne sie dem Klassenpfad Ihres Projekts hinzuzufügen. Dies ist jedoch nicht unbedingt der Fall, da dann eine Abhängigkeit von Ihrem Projekt zu einem Containerimplementierungsdetail auf niedriger Ebene erstellt wird. In diesem Fall ist die Netty-Bibliothek möglicherweise nur während der lokalen Entwicklung vorhanden, wenn Sie die Bereitstellung auf einem anderen App-Server beenden (Tomcat, Jboss, Weblogic usw.).

Ich würde vorschlagen, einfach die allgemeinere ConnectException, die AnnotatedConnectException erweitert. ConnectException ist Teil des Standard-Java-JDK, daher sind keine zusätzlichen Änderungen am Klassenpfad erforderlich, und dies ist auf allen App-Servern übertragbar.

Sie haben das Gefühl, dass das Einfangen von Exception keine gute Idee ist. Es empfiehlt sich, nur die spezifischen Ausnahmen abzufangen, die von dem Code ausgelöst werden sollen, der ausgeführt werden soll, damit Sie dem Benutzer oder in Ihren Protokollen genauere Nachrichten präsentieren können. This article zu Ausnahmebehandlungstechniken könnte nützlich sein.

EDIT:

Wenn der Rahmen Sie anrufen, bedeutet nicht, dass kann ein ConnectException werfen ist, dann könnten Sie Ausnahme fangen gezwungen werden:

try { 
     // your code 
    } catch (InterruptedException e) { 
     // Do something 
    } catch (Exception e) { 
     // Do something else 
    } 

Es ist nicht ideal, aber die Framework-API hat Ihnen keine andere Wahl gelassen.

+0

Hey da. Danke für die Klarstellungen. Ich kann sehen, warum das Erfassen der ConnectException sinnvoll ist, aber es scheint, dass es nicht funktioniert. Aber es scheint, als wäre es ein unerreichbarer Catch-Block? Ich habe meinen Code in meinem ersten Beitrag hier angehängt. – brilam

0

Entfernen Sie sync() und behandeln Sie den Erfolg oder Misserfolg der Verbindung mit einem Listener.

try { 
    ChannelFuture channelFuture = bootstrap.connect(host, port); 
    channelFuture.addListener(f -> { 
     if (!f.isSuccess() && f.cause() instanceof ConnectException) { 
      System.out.println("[Info] The server is offline."); 
     } 
    }); 
    channelFuture.await(); 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
}