문제

이 코드가 주어지면 :

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

(스트림을 안전하게 닫는 방법에 대한 조언은 없으며, 이것은 레거시 코드이며 새 버전은 시도 / 마침내 사용합니다)

"ps.println (buffer.get (i))"에서 classcastException을받습니다.

이 방법은 문자열로 만 채워진 목록으로 여러 번 (5 회)라고 불리며, 1st ErrorObject에 도달 할 때 문자열로 채워진 목록과 다른 객체 (예 : ErrorObject)로 호출됩니다. ClassCastException을 얻습니다. .

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

이 문제는 생산 환경에서 발생하지만 Dev 환경에서는 재현 할 수 없습니다 : Prod : JVM = IBM J9 VM 2.4 J2RE 1.6.0 IBM J9 2.4 AIX PPC-32 JVMAP3260-20081105_25433 (JIT 활성화, AOT ENABLED) DEV : WINXP, JDK 1.6 .0_16

이 코드가 실패 할 수있는 이유가 있습니까?

최근에 패치되었는데, 제작 팀이 항아리를 올바르게 업그레이드하지 않았을까 걱정되지만 상사는 이미 패치가 적용되었는지 확인했습니다 ...

Ps.Println (Object) 대신 Ps.Println을 Ps.Println (String)에 "와이어"할 수 있는지 궁금했습니다. 그것은 그러한 문제를 설명 할 수 있지만, 이것이 가능한지 전혀 모른다.

모든 조언을 환영합니다. 미리 감사드립니다

편집 : 나는 전체 스택 추적을 요청 받았으므로 여기에 있습니다.

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
도움이 되었습니까?

해결책

Ps.Println (Object) 대신 Ps.Println을 Ps.Println (String)에 "와이어"할 수 있는지 궁금했습니다. 그것은 그러한 문제를 설명 할 수 있지만, 이것이 가능한지 전혀 모른다.

불가능합니다. 또는 바이트 코드 컴파일러 또는 JIT 컴파일러 버그가 없다면 최소한 그렇지 않습니다. 그리고 이것이 그렇지 않다는 증거가 없다면 컴파일러 버그를 비난해야합니다.

그러나 내가 확인할 첫 번째는 실행중인 코드가 실제로보고있는 소스 코드에서 컴파일되었다는 것입니다. 이것을 확인하는 한 가지 방법은 소스에서 다시 컴파일 한 다음 실행 결과를 비교하는 것입니다. javap 수업의 각 사본에서. 바이트 코드를 보면 어떤 오버로드가 println 바이트 코드 컴파일러는 사용한다고 말합니다.

편집하다 - javap 출력은 해당 버전의 바이트 코드가 호출해야 함을 분명히 보여줍니다. println(Object), 그리고 아니요 checkcast 시야에 OPCODE. 잘못된 메소드를 호출하는 JIT 컴파일러 버그 그리고 자발적으로 클래스 캐스트를하도록 코드를 삽입하면 점점 더 불가피하게 들릴 수 있습니다.

다른 팁

errorObject 클래스에서 내부 문자열로 변환하여 toString () 메소드를 선언하고 println () 호출에 +""를 추가하십시오. pintln (errorobjlist+"")처럼;

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top