【问题标题】:hadoop -libjars and ClassNotFoundExceptionhadoop -libjars 和 ClassNotFoundException
【发布时间】:2012-10-26 22:42:54
【问题描述】:

请帮忙,我卡住了。 这是我运行作业的代码。

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 的原因

我做错了什么?

统一更新: 我正在检查 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文件系统,结果是一样的。好像没有添加类...

【问题讨论】:

标签: hadoop mapreduce hdfs cloudera


【解决方案1】:

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

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

在哪里

/我的目录

是hdfs路径,

/home/cloudera/uploaded_jars/

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

-

--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 个 jars。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 我现在不能同意你的看法。 blog.cloudera.com/blog/2011/01/… 它在 100% 之前工作。然后我开始重构并......或者我打破了一些东西,或者 Cloudera 4 中存在错误
    • 并且:从 0.19 开始,使用 -libjars 添加的 jars 也可用于客户端类路径,由 HADOOP-3570 修复。
    • 当 jars 在编译时存在,然后在运行时不存在时,几乎总是会发生此错误。这几乎肯定是一个类路径问题
    • 我明白。我确实打印到 MR-JOB 主类中的控制台配置对象。这些罐子是通过参数传递的。我确实在本地和 HDFS 中看到了它们。当然,我确实想念一些东西。请指教。
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多