Pergunta

Estou usando Java 1.4 com Log4J.

Parte do meu código envolve serialização e desserialização de objetos de valor (POJOs).

Cada um dos meus POJOs declara um logger com

private final Logger log = Logger.getLogger(getClass());

O serializador reclama que org.apache.log4j.Logger não é serializável.

Devo usar

private final transient Logger log = Logger.getLogger(getClass());

em vez de?

Foi útil?

Solução

Que tal usar um registrador de estática? Ou você precisa de uma referência logger diferente para cada instância da classe? campos estáticos não são serializados por padrão; você pode explicitamente declarar campos para serialize com um privado, estático, array final ObjectStreamField chamado serialPersistentFields. Veja a Oracle documentação

conteúdo Adicionado: Como você usa getLogger (getClass ()) , você vai usar o mesmo logger em cada instância. Se você quiser usar logger separado para cada instância que você tem de se diferenciar no nome do logger no -method getLogger (). por exemplo. getLogger (getClass (). getNome () + hashCode ()). então você deve usar o atributo transitória para se certificar de que o logger não é serializado.

Outras dicas

O registrador deve ser estático; isso tornaria não serializável.

Não há nenhuma razão para fazer logger não-estático, a menos que você tem uma forte razão para fazê-lo assim.

Se você realmente quer ir a abordagem transitória você precisará redefinir o log quando o objeto é desserializado. A maneira de fazer isso é implementar o método:

 private void readObject(java.io.ObjectInputStream in) 
   throws IOException, ClassNotFoundException;

Os javadocs para Serializable tem informações sobre este método.

A sua implementação vai ser algo como:

 private void readObject(java.io.ObjectInputStream in) 
     throws IOException, ClassNotFoundException {
   log = Logger.getLogger(...);
   in.defaultReadObject();
 }

Se você não fizer isso, então log será nulo após deserializing seu objeto.

De qualquer declarar seu campo logger como estático ou como passageira.

Ambas as formas garantir a writeObject () não tentará escrever o campo para o fluxo de saída durante a serialização.

campos Normalmente logger são declarados estático, mas se você precisa que ele seja um campo de instância apenas declará-la transitória, como geralmente é feito para qualquer campo não serializável. Após a desserialização campo logger será nulo, porém, assim que você tem que implementar um método readObject () para inicializar corretamente.

Tente fazer a estática Logger vez. Que você não precisa se preocupar com a serialização porque ele é tratado pelo carregador de classe.

Esses tipos de casos, particularmente em EJB, são geralmente tratadas através rosca estado local. Normalmente, o caso de uso é algo que você tem uma transação particular que está enfrentando um problema e você precisa para elevar o registo de depuração para essa operação para que possa gerar registro detalhado sobre o funcionamento problema. Levar algum estado local de segmento em toda a transação e usar isso para selecionar o logger correta. Sinceramente eu não sei onde seria benéfico para definir o nível em uma instância neste ambiente porque o mapeamento de instâncias para a transação deve ser uma função nível de contêiner, você não vai realmente ter o controle de qual instância é usado em uma determinada transacção de qualquer maneira.

Mesmo nos casos em que você está lidando com um DTO não é geralmente uma boa idéia para projetar seu sistema de tal forma que uma determinada instância específica é necessária porque o projeto pode evoluir facilmente nas maneiras que fazem que uma má escolha . Você poderia vir ao longo de um mês a partir de agora e decidir que considerações de eficiência (caching ou alguma outra otimização do ciclo de vida em mudança) vai quebrar a sua suposição sobre o mapeamento de casos em unidades de trabalho.

Se quiser que o Logger ser por exemplo, então sim, você iria querer fazer isso transitória se você estiver indo para serializar seus objetos. Log4J Madeireiros não são serializado, não na versão do Log4J que eu estou usando de qualquer maneira, por isso, se você não fizer seus campos Logger transitória você vai ter exceções em serialização.

Os madeireiros não são serializado por isso você deve usar transitória quando armazená-los em campos de instância. Se você deseja restaurar o logger após a desserialização você pode armazenar o Nível (String) indide seu objeto que não obter serializado.

Há boas razões para usar um registrador instância. Um bom caso de uso é assim que você pode declarar o logger em um super-classe e usá-lo em todas as sub-classes (a única desvantagem é que os logs do super-classe são atribuídos à sub-classe, mas geralmente é fácil ver que).

(Como outros já mencionados uso estático ou transitória).

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