2

RemoteExceptions をスローするときに例外チェーンを使用するのは悪い考えですか? 次のようなことを行う RMI サーバーがあります。

public Object doSomething() throws RemoteException
{
    try
    {
        return getData();
    }
    catch (CustomException ex)
    {
        throw new RemoteException(ex);
    }
}

クライアントで ClassNotFoundException が原因で UnmarshallException が発生しています。プラス面としては、CustomException 自体がエクスポートされていることがわかります。残念ながら、この男の奥深くにある別の例外はエクスポートされません。これが ClassNotFoundException の出番です。階層は次のようなものだと思います。

RemoteException -> CustomException -> SQLException -> NotExportedException

問題は、CustomException がエクスポートされることは保証できますが、下位レベルの例外がエクスポートされることは保証できないということです。

このため、RemoteExceptions で例外チェーンを使用することは決してありません。代わりに、おそらくサーバー側でスタック トレースをログに記録し、「原因」例外がチェーンされていないプレーンなバニラ RemoteException をスローする必要があると思います。以前にこの状況に対処した人はいますか?

4

2 に答える 2

5

CustomException を RemoteException でラップするのではなく、次のようにリモート インターフェイスを変更することができます。

interface Foo extends Remote {

  Object doSomething() throws CustomException, RemoteException;

}

ここでの原則は、RMI ランタイムのみが RemoteExceptions を発生させる必要があるということです。アプリケーションロジックではなく、リモート処理で何らかの障害が発生したことを示しています。実際、具体的な実装では . を宣言する必要さえありませんRemoteException

ただし、サービスがサードパーティのライブラリから例外をキャッチしているが、throws 句でそれを公開したくない場合は、これでは処理できません。

public Object doSomething() throws CustomException {
  try {
    return theirSvc.getData();
  } catch (ThirdPartyException ex) {
    throw new CustomException("Failed to obtain requested data.");
    // or: throw new CustomException("Failed to obtain requested data.", ex) ?
  }
}

この場合、「リーキーな抽象化」を作成しないことをお勧めします。そうしないと、そのサードパーティ ライブラリについて知る必要がないクライアントで依存関係が作成されます。

通常、同じエラーが繰り返しログに記録されるため、ログスローは悪い習慣です。しかし、この場合、スローされた例外がクライアントに転送されるため、正当化されると思います。クライアントとサーバーの両方でログに記録すると便利な場合があります。したがって、catch ブロックは次のようになります。

catch (ThirdPartyException ex) {
   String message = "Failed to obtain requested data.";
   log.error(message, ex);
   throw new CustomException(message);
 }

このようにして、ThirdPartyException の依存関係はサーバーに限定され、サーバー ログには適切な実装固有の情報が含まれ、エラーはクライアントに正しく報告されます。

于 2008-12-08T23:05:40.687 に答える
3

ソース例外からメッセージ + 全体のスタック トレースをキャプチャし、それをリモート例外の内容として渡します。そうすれば、すべてのスタックの詳細を取得できますが、シリアル化できない内部例外について心配する必要はありません。

他のサードパーティ (または独自の「ファーストパーティ」カスタム例外) 内に他のオブジェクトが含まれている可能性があることはわかりません!

于 2008-12-08T23:09:34.797 に答える