2017-09-29 18 views
1

私はネットワーキングライブラリとNettyが新しく、クライアントを構築しています。私のテストでは、自分のコードが意図したとおりに正しく動作することを理解していますが、ホストに正しく接続できない場合には、より意味のあるメッセージを伝えたいと思います。だから、私が行ったことは、ポートでlocalhostに接続させてみることです。そこにホストされているものは何もないので、例外がスローされます。しかし、そのクラスへの輸入があるように思われない、Netty - ハンドル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 

私はAnnotatedConnectExceptionキャッチしようとすることを試みてきました。以下は、スタックトレースです。私は、このクラスがAbstractChannelのプライベート例外だと思っています。私は実装をチェックし、それは次のようになります。

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; 
    } 
} 

私も、私は例外でのtry-catchを行うことによって、この例外を処理できることを発見しました。しかし、私はそれがひどい考えであると感じるので、私は可能ならばこれを避けたいと思います。これについては、どのようにすればいいのでしょうか?

EDITは:ここでConnectExceptionをキャッチする私の試みです(。同じことがAnnotatedConnectExceptionのために試みたこれはでConnectExceptionがどこにあるか行われていた):

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."); 
} 

}

ありがとう!

+0

例外をキャッチしようとしたところはどこですか? –

+0

私はどのようにtry-catch例外を表示するために私のコードのスニペットを追加しました。スニペットは現在ConnectExceptionを表示しています。 AnnotatedConnectExceptionと同じ考えです。 – brilam

答えて

0

このライブラリは、実行時にコンテナによって提供される可能性が高く、開発中にプロジェクトのクラスパスに特別な追加を行わずに利用できない可能性があります。しかし、必ずしもこれを行う必要はありません。なぜなら、プロジェクトに低レベルのコンテナ実装の詳細への依存関係を作成するからです。この場合、Nettyライブラリは、別のアプリケーションサーバー(tomcat、jboss、weblogicなど)にデプロイするとローカル開発中にのみ存在する可能性があります。

より一般的なConnectException(これはAnnotatedConnectExceptionになります)をキャッチすることをお勧めします。 ConnectExceptionは標準のJava JDKの一部ですので、追加のクラスパスの変更は必要ありません。これはすべてのアプリケーションサーバーに移植可能です。

例外をキャッチするのは良い考えではないと感じても間違いありません。実行しようとしているコードによってスローされる特定の例外のみを捕捉し、ユーザーまたはログにさらに正確なメッセージを表示できるようにすることが最善です。例外処理技術に関するThis articleが有用かもしれません。

EDIT:

ConnectExceptionを投げることができる、あなたが呼び出しているフレームワークは、それがあることを示していない場合は、例外をキャッチすることを余儀なくされる可能性があります。

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

それは理想的ではないですが、フレームワークAPIはあなたに選択肢を与えませんでした。

+0

ねえ、そこに。説明をありがとう。なぜConnectExceptionを捕まえるのが理にかなっているのか分かりますが、うまくいかないようです。しかし、それは到達不能なキャッチブロックのようですね?私はここに私の最初の投稿に自分のコードを添付しています。 – brilam

0

sync()を削除し、リスナーを使用して接続の成功または失敗を処理します。

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(); 
}