简体   繁体   English

ChainMapper泛型的Java Hadoop问题

[英]Java Hadoop problems with ChainMapper Generics

Hi I am currently facing an issue with Java Generics: The method I need to use has this signature 嗨,我目前遇到Java泛型问题:我需要使用的方法具有此签名

static<K1,V1,K2,V2> void addMapper(JobConf job, 
           Class<? extends Mapper<K1,V1,K2,V2>> klass, 
           Class<? extends K1> inputKeyClass, 
           Class<? extends V1> inputValueClass, 
           Class<? extends K2> outputKeyClass, 
           Class<? extends V2> outputValueClass, 
           boolean byValue, JobConf mapperConf) 

and this is how I call it 这就是我所说的

ChainMapper.addMapper(conf, NameMapper.class, 
           Object.class, Object.class, Object.class, Object.class, 
           false, nameYearConf);

where NameMapper is defined as follows 其中NameMapper定义如下

public class NameMapper extends Mapper<Object, Object, Object, Object> { }

and also the other two parameters are correctly intialized 并且另外两个参数已正确初始化

JobConf conf = new JobConf(); JobConf nameYearConf = new JobConf(false);

when I try to compile I obtain the following error 当我尝试编译时,出现以下错误

    src\MeanYear.java:107: error: method addMapper in class ChainMapper cannot be applied to given types;
                    ChainMapper.addMapper(conf, NameMapper.class, Object.class,
                               ^
      required: JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf
      found: JobConf,Class<MeanYear.NameMapper>,Class<Object>,Class<Object>,Class<Object>,Class<Object>,boolean,JobConf
      reason: no instance(s) of type variable(s) K1,V1,K2,V2 exist so that argument type Class<MeanYear.NameMapper> conforms to formal parameter type Class<? extends Mapper<K1,V1,K2,V2>>
      where K1,V1,K2,V2 are type-variables:
        K1 extends Object declared in method <K1,V1,K2,V2>addMapper(JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf)
        V1 extends Object declared in method <K1,V1,K2,V2>addMapper(JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf)
        K2 extends Object declared in method <K1,V1,K2,V2>addMapper(JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf)
        V2 extends Object declared in method <K1,V1,K2,V2>addMapper(JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf)

I really cannot understand what I am doing wrong, I tried some similar examples and the compiles and they work. 我真的不明白我在做什么错,我尝试了一些类似的示例并进行了编译,并且它们可以正常工作。 I have also tried some examples provided here, but without success. 我也尝试过这里提供的一些示例,但没有成功。 Thanks. 谢谢。

At a glance my guess is you're mixing classes from the new and old api packages: 乍一看,我猜您正在混合新旧api包中的类:

ChainMapper (as of 1.1.2) is only implemented for the old API package (org.apache.hadoop.mapred ), and hasn't been ported to the new API package ( org.apache.hadoop.mapreduce ). ChainMapper (从1.1.2版本开始)仅针对旧的API包(org.apache.hadoop.mapred )实现,尚未移植到新的API包( org.apache.hadoop.mapreduce )。

As such the second argument to ChainMapper.addMapper ( Class<? extends Mapper<K1,V1,K2,V2>> klass ) is expected to be of type org.apache.hadoop.mapred.Mapper . 因此, ChainMapper.addMapperClass<? extends Mapper<K1,V1,K2,V2>> klass )的第二个参数预期为org.apache.hadoop.mapred.Mapper类型。

As your current mapper NameMapper extends the Mapper class, this leads me to believe that this is the new api Mapper class ( org.apache.hadoop.mapreduce ), as the new API is a class, not an interface 当您当前的映射器NameMapper扩展了Mapper类时,这使我相信这是新的api Mapper类( org.apache.hadoop.mapreduce ),因为新的API是一个类,而不是接口

You should be able to fix by amending the signature of your NameMapper class to match that of the old API Mapper interface: 您应该能够通过修改NameMapper类的签名以使其与旧的API Mapper接口的签名匹配来进行修复:

public class NameMapper extends MapReduceBase 
                        implements Mapper<Object, Object, Object, Object> { }

This will also mean your current map method's signature will need to change from 这也意味着您当前的地图方法的签名需要从

protected void map(Object key, Object value, Context context) { }
// to
public void map(Object key, Object value, OutputCollector collector,
                Reporter reporter) { }

And if you're using the setup and cleanup methods of the new Mapper API, you'll need to replace them too: 而且,如果您正在使用新的Mapper API的设置和清除方法,则也需要替换它们:

public void close() { } // instead of cleanup(Context) {}
public void configure(JobConf conf) { } // instead of setup(Context) {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM