Pergunta

Dado este pedaço de código:

public static void writeFile(File file,List buffer)throws IOException{
    File fic = new File(file.getCanonicalPath());
    cat.debug("writing file : "+fic.getAbsolutePath());
    FileOutputStream out = new FileOutputStream(fic);
    PrintStream ps = new PrintStream(out);
    for(int i=0;i<buffer.size();i++){
        ps.println(buffer.get(i));
    }
    ps.flush();
    ps.close();
    out.close();
}

(por favor, nenhum conselho sobre como fluxos perto com segurança, este é o código legado ea nova versão faz uso de try / finally)

Eu recebo um ClassCastException no "ps.println (BUFFER.GET (i))"

Este método é chamado várias vezes (digamos, 5 vezes) com uma lista única cheia de Cordas em seguida, ele é chamado com uma lista cheia de cordas e um outro objeto (digamos ErrorObject) No ponto chegamos ao 1º ErrorObject, temos o ClassCastException.

com.mycompany.ErrorObject incompatible with java.lang.String

Este problema ocorre em ambiente de produção, mas não pode ser reproduzido no ambiente Dev: Prod: jvm = J9 IBM VM 2.4 J2RE 1.6.0 IBM J9 2,4 ppc AIX-32 jvmap3260-20081105_25433 (JIT activado, activado AOT) Dev: WinXP, JDK 1.6.0_16

Há alguma razão este código poderia falhar?

Foi corrigida recentemente, temo que a equipe de produção não atualizar o jar corretamente, mas meu chefe já verificado que o patch foi aplicado correclty ...

Eu queria saber se o Just in Time compilador poderia "fio" do ps.println ao ps.println (String) em vez do ps.println (Object). Isso poderia explicar um problema tão grande, mas eu não tenho idéia se isso possível.

Qualquer conselhos bem-vindo, agradeço antecipadamente

EDIT: i foi perguntado rastreamento de pilha completo por isso aqui está:

java.lang.ClassCastException: com.mycompany.util.ErrorObject incompatible with java.lang.String
    at com.mycompany.util.FileUtils.writeFile(FileUtils.java:91)
    at com.mycompany.util.FileUtils.writeFile(FileUtils.java:50)
    at com.mycompany.itools.task.DBCompareInits.doDBTask(DBCompareInits.java:959)
    at com.mycompany.itools.task.DBTask.doTask(DBTask.java:115)
    at com.mycompany.itools.task.TaskGroup.startGroup(TaskGroup.java:115)
    at com.mycompany.runner.Runner.main(Runner.java:209)

EDIT 2: javap -c

   65:  invokeinterface #20,  1; //InterfaceMethod java/util/List.size:()I
   70:  if_icmpge   92
   73:  aload   4
   75:  aload_1
   76:  iload   5
   78:  invokeinterface #21,  2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
   83:  invokevirtual   #31; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
   86:  iinc    5, 1
   89:  goto    62
   92:  aload   4
   94:  invokevirtual   #32; //Method java/io/PrintStream.flush:()V
   97:  aload   4
   99:  invokevirtual   #33; //Method java/io/PrintStream.close:()V
   102: aload_3
   103: invokevirtual   #28; //Method java/io/FileOutputStream.close:()V
Foi útil?

Solução

Eu queria saber se o Just in Time compilador poderia "fio" do ps.println ao ps.println (String) em vez do ps.println (Object). Isso poderia explicar um problema tão grande, mas eu não tenho idéia se isso possível.

Não é possível. Ou pelo menos não a menos que haja um compilador bytecode ou JIT compilador bug. E você só deve culpar os erros do compilador se você tiver provas irrefutáveis ??de que isso é assim.

No entanto, a primeira coisa que eu iria verificar é que o código está sendo executado foi realmente compilado a partir do código-fonte que você está olhando. Uma maneira de confirmar isso seria para recompilar a partir da fonte, e então comparar os resultados da execução javap nas respectivas cópias da classe. Olhando para os bytecodes também irá dizer-lhe que a sobrecarga de println o compilador bytecode está dizendo para uso.

Editar - a saída javap mostra claramente que essa versão do bytecode deve chamar println(Object), e não há opcode checkcast à vista. Um erro compilador JIT que chama o método errado e espontaneamente insere código para fazer um classcast está soando cada vez mais implausível.

Outras dicas

Declare método toString () com a conversão para string dentro na classe ErrorObject e adicionar + "" para println call (). Como pintln (errorObjList + "");

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