【问题标题】:Hadoop Java Class cannot be found找不到 Hadoop Java 类
【发布时间】:2018-05-16 22:03:05
【问题描述】:

线程“main”java.lang.ClassNotFoundException:WordCount-> 中的异常与此问题有关,看来我肯定又错过了一个小点,这花了我几个小时才弄清楚。
我将尽可能清楚地了解路径、代码本身以及我尝试过但没有奏效的其他可能的解决方案。
我有点确定我正确配置了 Hadoop,因为直到最后一个阶段一切都在正常工作。
但仍然发布详细信息:

  1. 环境变量和路径

>

HADOOP VARIABLES START
export HADOOP_HOME=/usr/local/hadoop
export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
export HADOOP_INSTALL=/usr/local/hadoop
export HADOOP_CLASSPATH=/usr/lib/jvm/java-8-oracle/lib/tools.jar
export PATH=$PATH:$HADOOP_INSTALL/bin
export PATH=$PATH:$HADOOP_INSTALL/sbin
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
#export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_INSTALL/lib/native
#export HADOOP_OPTS="-Djava.library.path=$HADOOP_INSTALL/lib"
export JAVA_HOME=/usr/lib/jvm/java-8-oracle
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$JAVA_HOME/bin

#HADOOP VARIABLES END

类本身:

package com.cloud.hw03;

/**
 * Hello world!
 *
 */
import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCount {

  public static class TokenizerMapper
       extends Mapper<Object, Text, Text, IntWritable>{

    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        context.write(word, one);
      }
    }
  }

  public static class IntSumReducer
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values,
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      result.set(sum);
      context.write(key, result);
    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf, "wordcount");
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    job.setJarByClass(WordCount.class);
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

我为编译和运行做了什么:

  1. 在与我的 WordCount maven 项目(eclipse-workspace)相同的文件夹中创建 jar 文件

    $ hadoop com.sun.tools.javac.Main WordCount.java

    $ jar cf WordCount.jar WordCount*.class

  2. 运行程序:(我已经创建了一个目录并在hdfs中复制了输入输出文件)

hadoop jar WordCount.jar WordCount /input/inputfile01 /input/outputfile01

结果是:线程“main”中的异常 java.lang.ClassNotFoundException: WordCount

由于我与 WordCount.class 在同一目录中,并且我在同一目录中创建了我的 jar 文件,因此我没有指定 WordCount 的完整路径,因此我在此目录中运行上述第二个命令:

我已经添加了 job.setJarByClass(WordCount.class);到代码所以没有帮助。感谢您花时间回答!
我确定我又做了一些意想不到的事情,4 小时都搞不清楚

【问题讨论】:

    标签: java hadoop mapreduce


    【解决方案1】:

    Hadoop 网站上的 Wordcount 示例代码不使用包

    既然你有一个,你将运行完全合格的课程。与常规 Java 应用程序完全相同的方式

    hadoop jar WordCount.jar com.cloud.hw03.WordCount
    

    另外,如果你真的有一个 Maven 项目,那么hadoop com.sun.tools.javac.Main 是不正确的。您实际上会使用 Maven 来编译和创建包含所有类的 JAR,而不仅仅是 WordCount* 文件

    例如,从带有 pom.xml 的文件夹中

    mvn package 
    

    否则需要在父目录下

    hadoop com.sun.tools.javac.Main ./com/cloud/hw03/WordCount.java
    

    并从该目录运行jar cf 命令

    【讨论】:

    • 我在com.cloud.hw03目录下(截图中),还需要指定包吗?如果不指定完整路径,则无法再次找到 WordCount 类(我运行了您提到的命令和相同的错误-ClassNotFoundException)
    • JAR 包含完全限定的类名。它与您从中运行命令的文件夹无关
    • 您永远不应该手动将 JAR 添加到 Maven 项目中......实际上使用 Maven 来管理您的依赖项,正如它设计的那样。此外,您的项目应该在任何 IDE 和终端中运行,而不是依赖于“Eclipse”或“机器上的 JAR”mvnrepository.com/artifact/org.apache.hadoop/hadoop-client/…
    • 我创建了一个真正的 maven 文件并添加了所有需要的依赖项。创建了一个 jar 文件并运行 jar -tf WordCount.jar 命令实际上显示 WordCount.class 在 jar 文件内(没有包名)。令人惊讶的是,我仍然无法运行该程序,因为它再次显示未找到类。我不应该使用其他方法,比如用 javac 编译。我用于编译: 1. hadoop com.sun.tools.javac.Main *.java 2. jar cf WordCount.jar *.class 和运行:hadoop jar WordCount.jar WordCount /input /output
    • 我需要通过指定包名来创建 jar 文件,但我应该发出命令的当前目录应该在包之前,即如果包名是 com.hadoop,那么我需要在父目录中创建一个 jar(您还提到了 id),所以我将您的答案标记为正确。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多