2014-03-25 21 views
8

在Eclipse中彙編時,我的MapReduce作業運行正常,Eclipse項目中包含所有可能的Hadoop和Hive jar作爲依賴關係。 (這些是單節點,本地Hadoop安裝附帶的罐子)。Hadoop:java.lang.IncompatibleClassChangeError:找到的接口org.apache.hadoop.mapreduce.JobContext,但期望的類

然而,嘗試使用Maven項目組裝運行同一程序時(見下文),我得到:

Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface org.apache.hadoop.mapreduce.JobContext, but class was expected 

當程序正在使用以下Maven項目組裝此異常情況:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.bigdata.hadoop</groupId> 
    <artifactId>FieldCounts</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>FieldCounts</name> 
    <url>http://maven.apache.org</url> 

    <properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 

    <dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>3.8.1</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.hadoop</groupId> 
     <artifactId>hadoop-hdfs</artifactId> 
     <version>2.2.0</version> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.hadoop</groupId> 
     <artifactId>hadoop-common</artifactId> 
     <version>2.2.0</version> 
    </dependency> 
<dependency> 
    <groupId>org.apache.hadoop</groupId> 
    <artifactId>hadoop-mapreduce-client-jobclient</artifactId> 
    <version>2.2.0</version> 
</dependency> 
<dependency> 
    <groupId>org.apache.hive.hcatalog</groupId> 
    <artifactId>hcatalog-core</artifactId> 
    <version>0.12.0</version> 
</dependency> 
<dependency> 
    <groupId>com.google.guava</groupId> 
    <artifactId>guava</artifactId> 
    <version>16.0.1</version> 
</dependency> 
    </dependencies>  
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>2.3.2</version> 
     <configuration> 
      <source>${jdk.version}</source> 
      <target>${jdk.version}</target> 
     </configuration> 
     </plugin>  
    <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <executions> 
     <execution> 
     <goals> 
      <goal>attached</goal> 
     </goals> 
     <phase>package</phase> 
     <configuration> 
      <descriptorRefs> 
      <descriptorRef>jar-with-dependencies</descriptorRef> 
      </descriptorRefs> 
      <archive> 
      <manifest> 
       <mainClass>com.bigdata.hadoop.FieldCounts</mainClass> 
      </manifest> 
      </archive> 
     </configuration> 
    </execution> 
    </executions> 
</plugin> 
</plugins> 
</build>  
</project> 

*請告知在何處以及如何找到兼容的Hadoop罐子? *

[update_1] 我正在運行的Hadoop 2.2.0.2.0.6.0-101

正如我在這裏找到:https://github.com/kevinweil/elephant-bird/issues/247

Hadoop的1.0.3:JobContext是一類

的Hadoop 2.0.0:JobContext是一個接口

在我的pom.xml我有三個罐子版本2.2.0

hadoop-hdfs 2.2.0 
hadoop-common 2.2.0 
hadoop-mapreduce-client-jobclient 2.2.0 
hcatalog-core 0.12.0 

唯一的例外是hcatalog-core哪個版本是0.12.0,我找不到任何最近這個罐子的版本,我需要它!

我怎樣才能找到這4個罐子中的哪一個產生java.lang.IncompatibleClassChangeError: Found interface org.apache.hadoop.mapreduce.JobContext, but class was expected

請給我一個想法如何解決這個問題。 (我看到的唯一的解決辦法是編譯一切從源代碼!)

[/ update_1]

我MarReduce工作的

全文:

package com.bigdata.hadoop; 

import java.io.IOException; 
import java.util.*; 

import org.apache.hadoop.conf.*; 
import org.apache.hadoop.io.*; 
import org.apache.hadoop.mapreduce.*; 
import org.apache.hadoop.util.*; 
import org.apache.hcatalog.mapreduce.*; 
import org.apache.hcatalog.data.*; 
import org.apache.hcatalog.data.schema.*; 
import org.apache.log4j.Logger; 

public class FieldCounts extends Configured implements Tool { 

    public static class Map extends Mapper<WritableComparable, HCatRecord, TableFieldValueKey, IntWritable> { 

     static Logger logger = Logger.getLogger("com.foo.Bar"); 

     static boolean firstMapRun = true; 
     static List<String> fieldNameList = new LinkedList<String>(); 
     /** 
     * Return a list of field names not containing `id` field name 
     * @param schema 
     * @return 
     */ 
     static List<String> getFieldNames(HCatSchema schema) { 
      // Filter out `id` name just once 
      if (firstMapRun) { 
       firstMapRun = false; 
       List<String> fieldNames = schema.getFieldNames(); 
       for (String fieldName : fieldNames) { 
        if (!fieldName.equals("id")) { 
         fieldNameList.add(fieldName); 
        } 
       } 
      } // if (firstMapRun) 
      return fieldNameList; 
     } 

     @Override 
     protected void map(WritableComparable key, 
          HCatRecord hcatRecord, 
          //org.apache.hadoop.mapreduce.Mapper 
          //<WritableComparable, HCatRecord, Text, IntWritable>.Context context) 
          Context context) 
      throws IOException, InterruptedException { 

      HCatSchema schema = HCatBaseInputFormat.getTableSchema(context.getConfiguration()); 

      //String schemaTypeStr = schema.getSchemaAsTypeString(); 
      //logger.info("******** schemaTypeStr ********** : "+schemaTypeStr); 

      //List<String> fieldNames = schema.getFieldNames(); 
      List<String> fieldNames = getFieldNames(schema); 
      for (String fieldName : fieldNames) { 
       Object value = hcatRecord.get(fieldName, schema); 
       String fieldValue = null; 
       if (null == value) { 
        fieldValue = "<NULL>"; 
       } else { 
        fieldValue = value.toString(); 
       } 
       //String fieldNameValue = fieldName+"."+fieldValue; 
       //context.write(new Text(fieldNameValue), new IntWritable(1)); 
       TableFieldValueKey fieldKey = new TableFieldValueKey(); 
       fieldKey.fieldName = fieldName; 
       fieldKey.fieldValue = fieldValue; 
       context.write(fieldKey, new IntWritable(1)); 
      } 

     }  
    } 

    public static class Reduce extends Reducer<TableFieldValueKey, IntWritable, 
             WritableComparable, HCatRecord> { 

     protected void reduce(TableFieldValueKey key, 
           java.lang.Iterable<IntWritable> values, 
           Context context) 
           //org.apache.hadoop.mapreduce.Reducer<Text, IntWritable, 
           //WritableComparable, HCatRecord>.Context context) 
      throws IOException, InterruptedException { 
      Iterator<IntWritable> iter = values.iterator(); 
      int sum = 0; 
      // Sum up occurrences of the given key 
      while (iter.hasNext()) { 
       IntWritable iw = iter.next(); 
       sum = sum + iw.get(); 
      } 

      HCatRecord record = new DefaultHCatRecord(3); 
      record.set(0, key.fieldName); 
      record.set(1, key.fieldValue); 
      record.set(2, sum); 

      context.write(null, record); 
     } 
    } 

    public int run(String[] args) throws Exception { 
     Configuration conf = getConf(); 
     args = new GenericOptionsParser(conf, args).getRemainingArgs(); 

     // To fix Hadoop "META-INFO" (http://stackoverflow.com/questions/17265002/hadoop-no-filesystem-for-scheme-file) 
     conf.set("fs.hdfs.impl", 
       org.apache.hadoop.hdfs.DistributedFileSystem.class.getName()); 
     conf.set("fs.file.impl", 
       org.apache.hadoop.fs.LocalFileSystem.class.getName()); 

     // Get the input and output table names as arguments 
     String inputTableName = args[0]; 
     String outputTableName = args[1]; 
     // Assume the default database 
     String dbName = null; 

     Job job = new Job(conf, "FieldCounts"); 

     HCatInputFormat.setInput(job, 
       InputJobInfo.create(dbName, inputTableName, null)); 
     job.setJarByClass(FieldCounts.class); 
     job.setMapperClass(Map.class); 
     job.setReducerClass(Reduce.class); 

     // An HCatalog record as input 
     job.setInputFormatClass(HCatInputFormat.class); 

     // Mapper emits TableFieldValueKey as key and an integer as value 
     job.setMapOutputKeyClass(TableFieldValueKey.class); 
     job.setMapOutputValueClass(IntWritable.class); 

     // Ignore the key for the reducer output; emitting an HCatalog record as 
     // value 
     job.setOutputKeyClass(WritableComparable.class); 
     job.setOutputValueClass(DefaultHCatRecord.class); 
     job.setOutputFormatClass(HCatOutputFormat.class); 

     HCatOutputFormat.setOutput(job, 
       OutputJobInfo.create(dbName, outputTableName, null)); 
     HCatSchema s = HCatOutputFormat.getTableSchema(job); 
     System.err.println("INFO: output schema explicitly set for writing:" 
       + s); 
     HCatOutputFormat.setSchema(job, s); 
     return (job.waitForCompletion(true) ? 0 : 1); 
    } 

    public static void main(String[] args) throws Exception { 
     String classpath = System.getProperty("java.class.path"); 
     //System.out.println("*** CLASSPATH: "+classpath);  
     int exitCode = ToolRunner.run(new FieldCounts(), args); 
     System.exit(exitCode); 
    } 
} 

而且類複雜的組合鍵:

package com.bigdata.hadoop; 

import java.io.DataInput; 
import java.io.DataOutput; 
import java.io.IOException; 

import org.apache.hadoop.io.WritableComparable; 

import com.google.common.collect.ComparisonChain; 

public class TableFieldValueKey implements WritableComparable<TableFieldValueKey> { 

     public String fieldName; 
     public String fieldValue; 

     public TableFieldValueKey() {} //must have a default constructor 
     // 

     public void readFields(DataInput in) throws IOException { 
     fieldName = in.readUTF(); 
     fieldValue = in.readUTF(); 
     } 

     public void write(DataOutput out) throws IOException { 
     out.writeUTF(fieldName); 
     out.writeUTF(fieldValue); 
     } 

     public int compareTo(TableFieldValueKey o) { 
     return ComparisonChain.start().compare(fieldName, o.fieldName) 
      .compare(fieldValue, o.fieldValue).result(); 
     } 

    } 
+0

其中的Hadoop是在集羣中使用(僞),用於獲取版本的集羣中使用「的Hadoop版本」的版本? – sachin

回答

0

顯然,您的Hadoop和Hive版本之間的版本不兼容。您需要升級(或降級)Hadoop版本或Hive版本。

這是由於Hadoop的1和Hadoop 2之間的不兼容

10

Hadoop的已經經歷了巨大的代碼重構了從Hadoop 1.0Hadoop 2.0。一個副作用 是針對Hadoop 1.0編譯的代碼與Hadoop 2.0不兼容,反之亦然。 但是源代碼大部分是兼容的,因此只需要重新編譯目標代碼爲 的Hadoop發行版。

當您運行 針對Hadoop 2.0上的Hadoop 1.0編譯的代碼時,異常「Found interface X, but class was expected」非常常見,反之亦然。

您可以在羣集中找到正確的hadoop版本,然後在pom.xml文件中指定hadoop版本使用羣集中使用的相同版本的hadoop構建項目並進行部署。

+1

@Chiron請查看我在問題文本中的更新。 – dokondr

1

您需要重新編譯「hcatalog-core」以支持Hadoop 2.0.0。 目前 「hcatalog核」 只支持Hadoop的1.0

0

查找條目類似這樣的

<dependency> 
      <groupId>org.apache.hadoop</groupId> 
      <artifactId>hadoop-core</artifactId> 
      <version>1.2.1</version> 
</dependency> 
在你的pom.xml

。 這些定義了要使用的hadoop版本。根據您的要求更改或刪除它們。

0

即使我遇到了這個問題。 正嘗試將hive-hcatalog-core-0.13.0.jar與HCatMultipleInputs配合使用。我們正在使用hadoop 2.5.1。

下面的代碼改變幫我解決這個問題:

 

//JobContext ctx = new JobContext(conf,jobContext.getJobID()); 
JobContext ctx = new Job(conf); 

相關問題