2012-06-21 7 views
15

Moja wersja Miaoop jest 1.0.3, kiedy używam wielu wątków, mam ten błąd.Mileop Wielokrotne wprowadzanie nie powiodło się z ClassCastException

java.lang.ClassCastException: org.apache.hadoop.mapreduce.lib.input.TaggedInputSplit cannot be cast to org.apache.hadoop.mapreduce.lib.input.FileSplit 
at org.myorg.textimage$ImageMapper.setup(textimage.java:80) 
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:142) 
at org.apache.hadoop.mapreduce.lib.input.DelegatingMapper.run(DelegatingMapper.java:55) 
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764) 
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370) 
at org.apache.hadoop.mapred.Child$4.run(Child.java:255) 
at java.security.AccessController.doPrivileged(Native Method) 
at javax.security.auth.Subject.doAs(Subject.java:416) 
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121) 
at org.apache.hadoop.mapred.Child.main(Child.java:249) 

Przetestowałem pojedynczą ścieżkę wejściową, bez problemu. Tylko wtedy, gdy używam

MultipleInputs.addInputPath(job, TextInputpath, TextInputFormat.class, 
      TextMapper.class); 
    MultipleInputs.addInputPath(job, ImageInputpath, 
      WholeFileInputFormat.class, ImageMapper.class); 

google i znalazłem ten link https://issues.apache.org/jira/browse/MAPREDUCE-1178 który powiedział 0.21 miał ten błąd. Ale używam wersji 1.0.3, czy ten błąd powraca. Ktoś ma ten sam problem lub ktoś może mi powiedzieć, jak to naprawić? Dzięki

oto kod konfiguracja obrazu odwzorowującym, 4. Linia jest, gdy pojawia się błąd:

protected void setup(Context context) throws IOException, 
      InterruptedException { 
     InputSplit split = context.getInputSplit(); 
     Path path = ((FileSplit) split).getPath(); 
     try { 
      pa = new Text(path.toString()); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
+0

Czy możesz opublikować kod dla klasy 'ImageMapper' - wygląda na to, że próbujesz rzucić podział wejściowy do FileInputSplit w swojej metodzie instalacji. –

+0

Mam podobny problem .. Czy istnieje jakieś rozwiązanie? – sunitha

Odpowiedz

29

Nawiązując do moich uwag, Javadocs dla TaggedInputSplit potwierdza, że ​​jesteś prawdopodobnie błędnie odlewania split wejściowy FileSplit:

/** 
* An {@link InputSplit} that tags another InputSplit with extra data for use 
* by {@link DelegatingInputFormat}s and {@link DelegatingMapper}s. 
*/ 

Moje przypuszczenie jest metoda setup wygląda mniej więcej tak:

@Override 
protected void setup(Context context) throws IOException, 
     InterruptedException { 
    FileSplit split = (FileSplit) context.getInputSplit(); 
} 

Niestety TaggedInputSplit nie jest widoczny publicznie, więc nie można łatwo wykonać testu stylu instanceof, a następnie rzucić, a następnie zadzwonić pod numer TaggedInputSplit.getInputSplit(), aby uzyskać rzeczywisty plik bazowy FileSplit. Tak więc albo musisz zaktualizować źródło samodzielnie i ponownie skompilować & wdrożyć, wysłać bilet JIRA, aby poprosić o naprawienie go w przyszłej wersji (jeśli już nie działał w 2+) lub wykonać nieprzyjemny odbicie hackery dostać się do bazowego InputSplit

jest to całkowicie niesprawdzone:

@Override 
protected void setup(Context context) throws IOException, 
     InterruptedException { 
    InputSplit split = context.getInputSplit(); 
    Class<? extends InputSplit> splitClass = split.getClass(); 

    FileSplit fileSplit = null; 
    if (splitClass.equals(FileSplit.class)) { 
     fileSplit = (FileSplit) split; 
    } else if (splitClass.getName().equals(
      "org.apache.hadoop.mapreduce.lib.input.TaggedInputSplit")) { 
     // begin reflection hackery... 

     try { 
      Method getInputSplitMethod = splitClass 
        .getDeclaredMethod("getInputSplit"); 
      getInputSplitMethod.setAccessible(true); 
      fileSplit = (FileSplit) getInputSplitMethod.invoke(split); 
     } catch (Exception e) { 
      // wrap and re-throw error 
      throw new IOException(e); 
     } 

     // end reflection hackery 
    } 
} 

reflection hackery wyjaśnił:

z TaggedInputSplit zadeklarowane chronionym zakresie, nie jest widoczny do klas poza pakietem org.apache.hadoop.mapreduce.lib.input, a zatem nie można odwoływać się do tej klasy w swojej metodzie instalacji. Aby obejść ten problem, możemy wykonać szereg operacji opartych refleksji:

  1. inspekcji nazwę klasy, możemy przetestować typu TaggedInputSplit używając to w pełni kwalifikowana nazwa

    splitClass.getName().equals("org.apache.hadoop.mapreduce.lib.input.TaggedInputSplit")

  2. Wiemy chcemy wywołać metodę TaggedInputSplit.getInputSplit(), aby odzyskać opakowany podział wejściowy, więc wykorzystujemy metodę odbicia Class.getMethod(..), aby uzyskać odniesienie do metody:

    Method getInputSplitMethod = splitClass.getDeclaredMethod("getInputSplit");

  3. Ta klasa wciąż nie jest widoczna, więc używamy setAccessible (..) Aby zastąpić to, zatrzymując menedżera zabezpieczeń przed rzuceniem wyjątku

    getInputSplitMethod.setAccessible(true);

  4. Wreszcie możemy wywołać metodę w odniesieniu do podziału wejściowego i oddanych wynik FileSplit (optymistycznie nadzieją jego wystąpienie ten typ):

    fileSplit = (FileSplit) getInputSplitMethod.invoke(split);

+1

To jest dokładnie to samo, co zgadłeś. Wypróbowałem twój kod i teraz działa. Jesteś taki pro! –

+0

Przeczytałem kody ponownie, ale nadal nie jestem pewien, jak to działa. Czy możesz podać krótkie wyjaśnienie dotyczące hackery odbicia? Dzięki. –

+0

Zapoznaj się z dodaną sekcją na końcu: –

0

miałem ten sam problem, ale rzeczywisty problem, że ja wciąż ustawiania InputFormat po skonfigurowaniu wielokrotne wprowadzanie:

Po usunięciu tej linii wszystko działało dobrze.

Powiązane problemy