2012-06-21 17 views
15

के साथ विफल रहता है मेरा हैडऑप संस्करण 1.0.3 है, जब मैं एकाधिक इनपुट का उपयोग करता हूं, तो मुझे यह त्रुटि मिली।हैडऑप एकाधिक इनपुट क्लासकास्टएक्सप्शन

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) 

मैंने एकल इनपुट पथ का परीक्षण किया, कोई समस्या नहीं। मैं googled और इस लिंक https://issues.apache.org/jira/browse/MAPREDUCE-1178 जो 0.21 इस बग ने कहा कि पाया केवल जब मैं

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

का उपयोग करें। लेकिन मैं 1.0.3 का उपयोग कर रहा हूं, क्या यह बग फिर से आती है। किसी को भी एक ही समस्या है या कोई मुझे बता सकता है कि इसे कैसे ठीक किया जाए? धन्यवाद

यहाँ छवि नक्शाकार की स्थापना कोड है, 4 लाइन जहां त्रुटि उत्पन्न होती है:

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

क्या आप अपनी 'छविमैपर' कक्षा के लिए कोड पोस्ट कर सकते हैं - ऐसा लगता है कि आप इनपुट सेटअप को अपनी सेटअप विधि में FileInputSplit में डालने का प्रयास कर रहे हैं। –

+0

मेरे पास एक समान समस्या है .. क्या कोई समाधान मौजूद है? – sunitha

उत्तर

29

मेरी टिप्पणी पर बाद, TaggedInputSplit के लिए Javadocs पुष्टि करता है कि आप शायद कर रहे हैं गलत तरीके से करने के लिए इनपुट विभाजन कास्टिंग एक FileSplit:

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

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

मेरा अनुमान है अपने स्थापना विधि है कुछ इस तरह दिखता

दुर्भाग्य से TaggedInputSplit सार्वजनिक दिखाई नहीं दे रहा है, इसलिए आप आसानी से instanceof स्टाइल चेक नहीं कर सकते हैं, उसके बाद एक कास्ट के बाद और वास्तविक अंतर्निहित FileSplit प्राप्त करने के लिए TaggedInputSplit.getInputSplit() पर कॉल करें। इसलिए या तो आपको स्रोत को अपडेट करने और & को फिर से संकलित करने की आवश्यकता होगी, एक जेआईआरए टिकट पोस्ट करें ताकि यह भविष्य के संस्करण में तय किया जा सके (यदि यह पहले से 2+ में नहीं किया गया है) या कुछ बुरा बुरा प्रदर्शन करें प्रतिबिंब hackery अंतर्निहित InputSplit

यह पूरी तरह से अपरीक्षित है को पाने के लिए:

@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 
    } 
} 

प्रतिबिंब hackery समझाया:

TaggedInputSplit जा रहा है की घोषणा की रक्षा की गुंजाइश के साथ, यह नहीं दिखाई दे रहा है org.apache.hadoop.mapreduce.lib.input पैकेज के बाहर कक्षाओं के लिए, और इसलिए आप उस सेटअप को अपनी सेटअप विधि में संदर्भित नहीं कर सकते हैं। इस के आसपास पाने के लिए, हम प्रतिबिंब आधारित संचालन का निष्पादन:

  1. वर्ग के नाम का निरीक्षण करने से हम इसे पूरी तरह से योग्य नाम

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

  2. हम जानते हैं का उपयोग प्रकार TaggedInputSplit के लिए परीक्षण कर सकते हैं हम लिपटे इनपुट स्प्लिट को पुनर्प्राप्त करने के लिए TaggedInputSplit.getInputSplit() विधि को कॉल करना चाहते हैं, इसलिए हम Class.getMethod(..) विधि का संदर्भ प्राप्त करने के लिए प्रतिबिंब विधि का उपयोग करते हैं:

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

  3. कक्षा अभी भी सार्वजनिक दिखाई नहीं दे रही है इसलिए हम सेट एक्सेस करने योग्य (..) विधि से ओवरराइड, एक अपवाद

    getInputSplitMethod.setAccessible(true);

  4. अंत में हम इनपुट विभाजन के संदर्भ पर विधि आह्वान फेंकने से सुरक्षा प्रबंधक रोकने और एक FileSplit (करने के लिए परिणाम कास्ट करने के लिए आशावादी की अपनी एक उदाहरण उम्मीद इस प्रकार):

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

+1

यह वही है जैसा आपने अनुमान लगाया था। मैंने आपके कोड की कोशिश की और अब यह काम कर रहा है। तुम बहुत समर्थक हो! –

+0

मैंने कोड फिर से पढ़े लेकिन मुझे अभी भी यकीन नहीं है कि यह कैसे काम करता है। क्या आप प्रतिबिंब हैकरी के बारे में एक संक्षिप्त स्पष्टीकरण दे सकते हैं? धन्यवाद। –

+0

अंत में जोड़ा गया अनुभाग देखें –

0

मैं इस एक ही समस्या थी, लेकिन वास्तविक समस्या यह है कि मैं अभी भी सेट करने के बाद InputFormat की स्थापना की गई थी एकाधिक इनपुट:

job.setInputFormatClass(SequenceFileInputFormat.class); 

एक बार जब मैंने इस पंक्ति को हटा दिया तो सबकुछ ठीक काम करता था।

संबंधित मुद्दे