복붙노트

[HADOOP] hadoop -libjars 및 ClassNotFoundException

HADOOP

hadoop -libjars 및 ClassNotFoundException

제발 도와 줘, 나는 붙어있다. 여기에 직장을 운영하는 코드가 있습니다.

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 : 메인 클래스의 줄에 my-utils.jar라는 이름의 항아리로부터 클래스를 인스턴스화하려고한다.

내가 뭘 잘못 했니?

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 파일 시스템, 결과는 동일하다. 클래스가 추가되지 않은 것 같습니다 ...

해결법

  1. ==============================

    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 경로입니다.

    로컬 fs 경로입니다. 문제는 작업 항아리에있었습니다. 이전에는 매퍼 (Mapper), 감속기 (Reducer), Main 클래스의 세 가지 클래스 만 사용하여 간단한 병을 사용하여 작업을 실행하려고했습니다. 이제 나는 메이븐 (maven)에 의해 생성 된 다른 하나를 제공했다 (그것들 중 두 개를 생성한다) 두 번째 작업 jar에는 모든 종속성 라이브러리가 들어 있습니다. 이것 안에. 구조는 다음과 같습니다. 내 job.jar

    -lib

    --Aoopalians-1.3.13 Assam-1.2.2-Avr-1.3.15 ... Commons-Benutils-1.3.13 Commons-Benutils-Core-1.3.1 .........

    lib 폴더에는 76 개의 jar 파일이 있습니다.

    그것은 효과가 있지만 왜 이해가 안되요.

  2. ==============================

    2.그들이 HDFS에 있기 때문에 그들이 당신이 일하고있는 직업의 classpath에 있다는 것을 의미하지는 않습니다.

    그들이 HDFS에 있기 때문에 그들이 당신이 일하고있는 직업의 classpath에 있다는 것을 의미하지는 않습니다.

    정말로이 문제를 해결하고 싶다면 maven을 사용하여 하나의 jar에 모든 의존성을 포함하는 "fat jar"를 빌드하십시오. Shade Plugin을 사용하여이 작업을 수행 할 수 있습니다.

    그러나 당신의 명령을 보면, 그것은 틀린 것처럼 보입니다. 여기에 설명 된 -libjars와 함께 "job"명령을 사용하면 더 나은 행운이 될 것입니다. "hadoop jar"명령을 사용하여 외부 jar를 지정할 수 있는지 확신 할 수 없습니다.

  3. ==============================

    3.그 이유는 mrjob.jar이 Hadoop 클라이언트 작업에 필요한 jar를 결정하기 때문입니다. 뚱뚱한 항아리를 제공하거나 HADOOP_CLASSPATH 아래에 항아리를 모두 포함하십시오.

    그 이유는 mrjob.jar이 Hadoop 클라이언트 작업에 필요한 jar를 결정하기 때문입니다. 뚱뚱한 항아리를 제공하거나 HADOOP_CLASSPATH 아래에 항아리를 모두 포함하십시오.

    반면, -libjars는 Map 및 Reduce 작업에 필요한 추가 항아리를 설정합니다.

    읽기 http://grepalex.com/2013/02/25/hadoop-libjars/

  4. from https://stackoverflow.com/questions/13095402/hadoop-libjars-and-classnotfoundexception by cc-by-sa and MIT license