Pregunta

Ante esta pieza 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, no consejos sobre cómo cerrar con seguridad corrientes, esto es el código heredado y la nueva versión hace uso de try / finally)

consigo un ClassCastException en el "ps.println (BUFFER.GET (i))"

Este método se llama varias veces (por ejemplo 5 veces) con una lista única llenos de Cuerdas a continuación, se le llama con una lista llena de cuerdas y un otro objeto (digamos ErrorObject) En el punto de llegar a la primera ErrorObject, obtenemos el ClassCastException.

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

Este problema se produce en el entorno de producción, pero no se puede reproducir en el entorno Dev: Prod: JVM = IBM J9 VM 2.4 J2RE 1.6.0 IBM J9 2,4 AIX ppc-32 jvmap3260-20081105_25433 (activar JIT, AOT habilitado) Dev: WinXP, JDK 1.6.0_16

¿Hay alguna razón este código podría fallar?

Se parcheado hace poco, me temo que el equipo de producción no actualizar el frasco correctamente, pero mi jefe ya comprobado que el parche se aplicó correclty ...

Me preguntaba si el compilador justo a tiempo podría "alambre" el ps.println a la ps.println (String) en lugar del ps.println (Objeto).  Eso podría explicar un problema, pero no tengo ni idea de si esto es posible.

Cualquier consejos bienvenidos, gracias de antemano

EDIT: me pidieron traza completa así que aquí 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
¿Fue útil?

Solución

  

Me preguntaba si el compilador justo a tiempo podría "alambre" el ps.println a la ps.println (String) en lugar del ps.println (Objeto). Eso podría explicar un problema, pero no tengo ni idea de si esto es posible.

No es posible. O al menos no a menos que haya un compilador JIT o código de bytes de errores del compilador. Y sólo se debe culpar a los errores de compilación si tiene pruebas irrefutables de que esto es así.

Sin embargo, lo primero que me gustaría comprobar es que el código se ejecuta realmente se calcula a partir del código fuente que se está viendo. Una manera de confirmar esto sería volver a compilar desde el código fuente, y luego comparar los resultados de la ejecución de javap respectivas copias de la clase. En cuanto a los códigos de bytes también le dirá lo que la sobrecarga de println el compilador de código de bytes está diciendo a utilizar.

Editar - la salida javap muestra claramente que esa versión del código de bytes debe llamar println(Object), y no hay ningún código de operación checkcast a la vista. Un error del compilador JIT que llama al método equivocado y inserta espontáneamente código para hacer un classcast está sonando cada vez más inverosímil.

Otros consejos

Declarar el método toString () con la conversión a cadena dentro de la clase ErrorObject y añadir + "" a println () llamada. Al igual que pintln (errorObjList + "");

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top