hadoop -libjars和ClassNotFoundException

时间:2012-10-26 22:42:55

标签: hadoop mapreduce hdfs cloudera

请帮助,我被困住了。 这是我运行工作的代码。

hadoop jar mrjob.jar ru.package.Main -files hdfs://0.0.0.0:8020/MyCatalog/jars/metadata.csv -libjars hdfs://0.0.0.0:8020/MyCatalog/jars/opencsv.jar,hdfs://0.0.0.0:8020/MyCatalog/jars/gson.jar,hdfs://0.0.0.0:8020/MyCatalog/jars/my-utils.jar /MyCatalog/http_requests.seq-r-00000 /MyCatalog/output/result_file

我确实得到了这些警告:

12/10/26 18:35:50 WARN util.GenericOptionsParser: The libjars file hdfs://0.0.0.0:8020/MyCatalog/jars/opencsv.jar is not on the local filesystem. Ignoring.
12/10/26 18:35:50 WARN util.GenericOptionsParser: The libjars file hdfs://0.0.0.0:8020/MyCatalog/jars/gson.jar is not on the local filesystem. Ignoring.
12/10/26 18:35:50 WARN util.GenericOptionsParser: The libjars file hdfs://0.0.0.0:8020/MyCatalog/jars/my-utils.jar is not on the local filesystem. Ignoring.

然后:线程“main”中的异常java.lang.NoClassDefFoundError: 在Main类中我尝试从名为my-utils.jar

的jar实例化类
  1. 所有这些罐子都在hfds中(我通过文件浏览器看到它们)
  2. my-utils.jar确实包含类,这是 NoClassDefFoundError
  3. 的原因

    我做错了什么?

    UPD: 我正在检查 GenericOptionsParser 的源代码:

    /**
       * If libjars are set in the conf, parse the libjars.
       * @param conf
       * @return libjar urls
       * @throws IOException
       */
      public static URL[] getLibJars(Configuration conf) throws IOException {
        String jars = conf.get("tmpjars");
        if(jars==null) {
          return null;
        }
        String[] files = jars.split(",");
        List<URL> cp = new ArrayList<URL>();
        for (String file : files) {
          Path tmp = new Path(file);
          if (tmp.getFileSystem(conf).equals(FileSystem.getLocal(conf))) {
            cp.add(FileSystem.getLocal(conf).pathToFile(tmp).toURI().toURL());
          } else {
            LOG.warn("The libjars file " + tmp + " is not on the local " +
              "filesystem. Ignoring.");
          }
        }
        return cp.toArray(new URL[0]);
      }
    

    所以: 1.逗号之间没有空格 2.仍然没有得到它...我试图指向:本地文件系统,hdfs文件系统,结果是一样的。似乎没有添加类......

3 个答案:

答案 0 :(得分:4)

问题解决了。正确的调用是:

hadoop jar my-job.jar ru.package.Main -files /home/cloudera/uploaded_jars/metadata.csv -libjars /home/cloudera/uploaded_jars/opencsv.jar,/home/cloudera/uploaded_jars/gson.jar,/home/cloudera/uploaded_jars/url-raiting-utils.jar /MyCatalog/http_requests.seq-r-00000 /MyCatalog/output/scoring_result

其中

  

/ MyCatalog

是hdfs路径,

  

/家庭/ Cloudera的/ uploaded_jars /

是本地fs路径 问题出在工作罐中。 以前我尝试使用只有三个类的简单jar 来运行作业:Mapper,Reducer,Main class 。 现在我确实提供了另一个由maven生成的(它生成了两个) 第二个作业jar包含所有依赖库。在里面。结构看起来像: MY-job.jar

- LIB

- aopalliance-1.0.jar asm-3.2.jar avro-1.5.4.jar ... commons-beanutils-1.7.0.jar commons-beanutils-core-1.8.0.jar .. 。zookeeper-3.4.3-cdh4.0.0.jar

lib文件夹中有76个罐子。

它有效,但我不明白为什么。

答案 1 :(得分:1)

仅仅因为它们在HDFS上,并不意味着它们位于您正在运行的作业的类路径中。

如果你真的只是想解决这个问题,我会用maven来构建一个“胖罐”,其中包含你在一个jar中的所有依赖项。您可以使用shade plugin

执行此操作

但是,看着你的命令,它看起来是错的。我认为使用-libjars,described here使用“job”命令可能会更好。我不确定您是否可以使用“hadoop jar”命令指定外部jar。

答案 2 :(得分:0)

原因是您的mrjob.jar确定了Hadoop客户端作业所需的jar。您可以提供一个胖罐子,也可以将所有罐子包含在HADOOP_CLASSPATH下。

另一方面,-libjars设置Map和Reduce任务所需的其他jar。

阅读此http://grepalex.com/2013/02/25/hadoop-libjars/