2011-09-15 165 views
3

時,我有以下代碼:ClassCastException異常錯誤鑄造回原班

public void doJob() { 
    MyObj s; 

    for (Object o : MyObj.all().fetch()) { 
     s = (MyObj) o; // ClassCastException here 

     if (!s.fileExists()) { 
     //Do some stuff 
     } 
    } 
} 

這是引發此異常:

play.exceptions.JavaExecutionException: models.MyObj cannot be cast to models.MyObj 
    at play.jobs.Job.call(Job.java:155) 
    at Invocation.Job(Play!) 
Caused by: java.lang.ClassCastException: models.MyObj cannot be cast to models.MyObj 
    at jobs.OrphanSurveys.doJob(OrphanSurveys.java:18) 
    at play.jobs.Job.doJobWithResult(Job.java:50) 
    at play.jobs.Job.call(Job.java:146) 
    ... 1 more 

(此方法的播放作業類中運行,如果該事項)

MyObj.all().fetch()返回某種包含數據庫中所有MyObj對象的Iterable。 MyObj從Play繼承此方法!框架的模型類,如果重要的話。這就是爲什麼它返回的列表是Object而不是MyObj,我無法改變它的工作原理。

那麼,有什麼理由不能回到MyObj?我可以看到如何從Object回傳一些奇怪的東西,但Java似乎知道對象的類是什麼。

謝謝!

+2

打印'o.getClass()。getName()'時列出了什麼類名? – rsp

回答

2

它看起來像你有ClassLoader問題。 fetch()方法返回的對象被加載到與當前線程中使用的ClassLoader不同的ClassLoader中,用於嘗試和投射。

試試這個來確認。將三行代碼添加到您的代碼中。

for (Object o : MyObj.all().fetch()) { 
    // Check classloaders 
    System.out.println(o.getClass().getClassLoader()); 
    System.out.println(MyObj.class.getClassLoader()); 
    break; 
    // 
    s = (MyObj) o; // ClassCastException here 

    if (!s.fileExists()) { 
    //Do some stuff 
    } 
} 
+0

我加了你提到的幾行(除了'break',它讓編譯器抱怨無法訪問的代碼= /)。神奇的是,這似乎解決了這個問題,因爲這兩個類加載器的輸出是相同的,並且不再抱怨演員陣容。當然,我很懷疑,所以我會讓它在一夜之間運行,看看它是否會在以後再發生。但是,現在爲+1:D – andronikus

+1

然後,由於這些代碼行不會影響類加載,因此運行時中的某些內容必須發生更改。 – Robin

+0

這就是我的想法,是的。 Play做了一些花哨的動態編譯,可能會糾結起來。這開始看起來像是一種競爭狀態,這既令人興奮又令人恐懼。幸運的是,這不是一個至關重要的過程。如果一夜之間出現問題,我會在明天發佈相關的日誌輸出。 – andronikus

0

從您的堆棧跟蹤中,顯然,您的集合中還有其他一些條目。 在你的循環中使用o.getClass().getName()知道什麼是.all().fetch()真的返回。

注意:也許一些model.Survey對象?

+0

啊,對不起。我使用的實際班級被稱爲「調查」,但我試圖通過使用「MyObj」變得非常簡單。我一定錯過了那一個!修正了我的問題。他們應該都是同一個班級。 – andronikus

+0

「由......引起」很明顯,即使在編輯之前,演員在同一班上失敗。 – Robin

2

我在StackOverflow上看到了最近發佈的一篇文章,指出如果兩個其他類相同的同類實例由不同的類加載器加載,則不能在它們之間進行投射。

Post in question

檢查無論你是不是受多個classloader條件也在這裏。