java - ClassCastException 是由 Just In Time 中的错误引起的吗?

标签 java aix classcastexception

鉴于这段代码:

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();
}

(请不要提供有关如何安全关闭流的建议,这是遗留代码,新版本使用了 try/finally)

我在“ps.println(buffer.get(i))”处收到 ClassCastException

此方法被调用多次(比如 5 次),列表中仅填充了字符串 然后,使用一个充满 String 和另一个对象(例如 ErrorObject)的列表来调用它 当我们到达第一个 ErrorObject 时,我们得到 ClassCastException。

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

该问题在生产环境中出现,但在开发环境中无法重现: 产品:jvm=IBM J9 VM 2.4 J2RE 1.6.0 IBM J9 2.4 AIX ppc-32 jvmap3260-20081105_25433(启用 JIT,启用 AOT) 开发:WinXP、JDK 1.6.0_16

此代码是否有任何原因可能失败?

最近打了补丁,我担心制作组没有正确升级jar,但是我的老板已经检查了补丁是否正确应用...

我想知道即时编译器是否可以将 ps.println “连接”到 ps.println(String) 而不是 ps.println(Object)。 这可以解释这样的问题,但我不知道这是否可能。

欢迎任何建议,提前谢谢

编辑: 我被问到完整的堆栈跟踪,所以这里是:

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)

编辑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

最佳答案

I was wondering if the Just in Time compiler could "wire" the ps.println to the ps.println(String) instead of the ps.println(Object). That could explain such a problem, but I have no idea if this possible.

这是不可能的。或者至少不会,除非存在字节码编译器或 JIT 编译器错误。如果您有无可辩驳的证据表明情况确实如此,您应该只责怪编译器错误。

但是,我要检查的第一件事是正在执行的代码确实是从您正在查看的源代码编译而来的。确认这一点的一种方法是从源代码重新编译,然后比较在类的各个副本上运行 javap 的结果。查看字节码还会告诉您字节码编译器要使用哪个 println 重载。

编辑 - javap 输出清楚地表明该版本的字节码应该调用 println(Object),并且没有 checkcast 操作码在眼前。 JIT 编译器错误调用错误的方法自发地插入代码来进行类转换,这听起来越来越难以置信。

关于java - ClassCastException 是由 Just In Time 中的错误引起的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2425487/

相关文章:

java - 将简单的 XML 行优雅地转换为 Map

java - 如何使用 Java 以 CSV 格式导出数据?

java - Firebird、Jaybird 和 Hibernate 的依赖项

java.lang.ClassCastException : entity. SysLogEntity 无法转换为实体.SysLogEntity

java - 尝试创建代理对象时出现 ClassCastException

java - 将异常从 CXF 拦截器传播到异常映射器

aix - 需要帮助根据 aix 中的 pid 获取进程名称

linux - 在 AIX 6.1 中运行 SUDO 时,配置文件没有被执行?

c - 获取 AIX 5 上的用户安全属性

java - 如何更改 mxgraph 中 mxCell 和 mxPoint 之间的边缘样式?