Pergunta

É uma má idéia de exceção uso encadeamento quando jogando RemoteExceptions? Temos um servidor RMI que faz algo parecido com isto:

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

Estou ficando UnmarshallException causada por uma ClassNotFoundException em meu cliente. No lado positivo, verifica-se que em si CustomException é exportada. . Infelizmente, outra exceção no fundo esse cara não é exportado, que é onde o ClassNotFoundException vem em Eu acho que a hierarquia é algo como isto:

RemoteException -> CustomException -> SQLException -> NotExportedException

O problema que eu vejo é que mesmo que nós podemos garantir que CustomException é exportado, nós não podemos garantir que todas as exceções de nível mais baixo são.

Estou inclinado para NUNCA utilizar a exceção de encadeamento com RemoteExceptions por causa disso. Em vez disso, eu acho que provavelmente deve registrar o rastreamento de pilha no lado do servidor e jogue um RemoteException planície, baunilha, sem exceção "causa" acorrentado a ele. Qualquer um tratado com essa situação antes?

Foi útil?

Solução

Ao invés de CustomException embrulho em RemoteException, você pode modificar sua interface remota como esta:

interface Foo extends Remote {

  Object doSomething() throws CustomException, RemoteException;

}

O princípio aqui é que apenas o tempo de execução RMI deve ser levantando RemoteExceptions; eles sinalizam alguma falha na comunicação remota, não na lógica da aplicação. Na verdade, as implementações concretas nem sequer precisa declarar o RemoteException.

Mas, isso não lidar com o caso em que o serviço está pegando uma exceção de alguma biblioteca de terceiros, mas não quero expor que, em uma cláusula 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) ?
  }
}

Neste caso, eu recomendo que você não criar uma "abstração de fuga", onde uma dependência seria criada em um cliente que de outra forma não têm necessidade de saber sobre essa biblioteca de terceiros.

Normalmente, registrando e arremesso é uma prática ruim, porque o mesmo erro é registrado repetidamente. Mas, neste caso, eu acho que é justificada, uma vez que a exceção lançada é transportado para o cliente; pode ser útil para registrá-lo tanto no cliente e servidor. Assim, o bloco termina catch up parecido com isto:

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

Desta forma, a dependência ThirdPartyException é limitado para o servidor, os logs do servidor contêm informações específicas de implementação apropriada, eo erro é corretamente relatado para o cliente.

Outras dicas

Nós capturar a mensagem + toda rastreamento de pilha de exceção fonte e passou que, em como o conteúdo da exceção remota. Dessa forma, você obter todos os detalhes de pilha, mas você não precisa se preocupar com qualquer um de qualquer das excepções interno que é não serializável.

Você nunca sabe o que outros objetos podem estar dentro de algum outro terceiro (ou mesmo o seu próprio "primeiro partido" exceções personalizadas!)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top