将外部jar设置为hadoop classpath

时间:2014-11-05 02:35:36

标签: java hadoop mapreduce bigtop

我正在尝试将外部jar设置为hadoop classpath但到目前为止没有运气。

我有以下设置

  

$ hadoop版本
  Hadoop 2.0.6-alpha   Subversion https://git-wip-us.apache.org/repos/asf/bigtop.git -r ca4c88898f95aaab3fd85b5e9c194ffd647c2109   由詹金斯于2013-10-31T07编译:55Z   来源与校验和95e88b2a9589fa69d6d5c1dbd48d4e   此命令使用/usr/lib/hadoop/hadoop-common-2.0.6-alpha.jar

运行

类路径

  

$ echo $ HADOOP_CLASSPATH
  /home/tom/workspace/libs/opencsv-2.3.jar

我能看到上面的HADOOP_CLASSPATH已被hadoop选中

  

$ hadoop classpath
  /etc/hadoop/conf:/usr/lib/hadoop/lib/:/usr/lib/hadoop/.//:/home/tom/workspace/libs/opencsv-2.3的.jar :/ usr / lib中/ Hadoop的HDFS /./:/ usr / lib中/ Hadoop的HDFS / LIB / :/ usr / lib中/ Hadoop的HDFS /.// :/ usr / lib中/ Hadoop的纱线/ LIB / :/ usr / lib中/ Hadoop的纱线/.//:/ usr / lib中/ Hadoop的映射精简/ LIB / :/ USR / LIB / Hadoop的映射精简/.//

命令

  

$ sudo hadoop jar FlightsByCarrier.jar FlightsByCarrier /user/root/1987.csv / user / root / result

我也尝试使用-libjars选项

  

$ sudo hadoop jar FlightsByCarrier.jar FlightsByCarrier /user/root/1987.csv / user / root / result -libjars / home / tom / workspace / libs / opencsv-2.3.jar

stacktrace

  

14/11/04 16:43:23 INFO mapreduce.Job:正在运行的职位:job_1415115532989_0001   14/11/04 16:43:55 INFO mapreduce.Job:在uber模式下运行的job job_1415115532989_0001:false   14/11/04 16:43:56 INFO mapreduce.Job:地图0%减少0%   14/11/04 16:45:27 INFO mapreduce.Job:地图50%减少0%   14/11/04 16:45:27 INFO mapreduce.Job:任务ID:attempt_1415115532989_0001_m_000001_0,状态:未通过   错误:java.lang。 ClassNotFoundException :au.com.bytecode.opencsv。 CSVParser       在java.net.URLClassLoader $ 1.run(URLClassLoader.java:366)       在java.net.URLClassLoader $ 1.run(URLClassLoader.java:355)       at java.security.AccessController.doPrivileged(Native Method)       在java.net.URLClassLoader.findClass(URLClassLoader.java:354)       at java.lang.ClassLoader.loadClass(ClassLoader.java:425)       at sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:308)       at java.lang.ClassLoader.loadClass(ClassLoader.java:358)       在FlightsByCarrierMapper.map(FlightsByCarrierMapper.java:19)       在FlightsByCarrierMapper.map(FlightsByCarrierMapper.java:10)       在org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144)       在org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:757)       在org.apache.hadoop.mapred.MapTask.run(MapTask.java:339)       在org.apache.hadoop.mapred.YarnChild $ 2.run(YarnChild.java:158)       at java.security.AccessController.doPrivileged(Native Method)       在javax.security.auth.Subject.doAs(Subject.java:415)       在org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1478)       在org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:153)

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:3)

运行地图的节点上缺少外部jar。您必须将其添加到缓存以使其可用。试试:

DistributedCache.addFileToClassPath(new Path("pathToJar"), conf);

不确定弃用了哪个版本DistributedCache,但是从Hadoop 2.2.0开始,您可以使用:

job.addFileToClassPath(new Path("pathToJar")); 

答案 1 :(得分:2)

我尝试在hadoop类路径中设置opencsv jar但它没有工作。我们需要在类路径中显式复制jar才能工作。它确实对我有用。 以下是我遵循的步骤:

我在HDP CLuster中完成了这个。我已经在hbase libs中复制了我的opencsv jar并在运行我的jar之前将其导出

将ExternalJars复制到HDP LIBS:

运行打开的CSV Jar: 1.复制目录/usr/hdp/2.2.9.1-11/hbase/lib/和/usr/hdp/2.2.9.1-11/hadoop-yarn/lib

中的opencsv jar
**sudo cp  /home/sshuser/Amedisys/lib/opencsv-3.7.jar /usr/hdp/2.2.9.1-11/hbase/lib/**

2.使用提供文件权限      sudo chmod 777 opencsv-3.7.jar 3.列出文件      ls -lrt

4. 导出hadoop classpathhbase classpath

5.现在运行你的Jar.It将拿起opencsv jar并正确执行。

答案 2 :(得分:1)

如果要将外部JAR添加到Hadoop类路径,那么最好将JAR复制到hadoop正在查看的现有目录之一。在命令行上运行命令“hadoop classpath”,然后找到一个合适的文件夹并将jar文件复制到该位置,hadoop将从那里获取依赖项。这不适用于CloudEra等,因为您可能没有将文件复制到hadoop类路径文件夹的读/写权限。

看起来您也尝试过LIBJARs选项,您是否编辑了驱动程序类以实现TOOL接口?首先确保编辑驱动程序类,如下所示:

    public class myDriverClass extends Configured implements Tool {

      public static void main(String[] args) throws Exception {
         int res = ToolRunner.run(new Configuration(), new myDriverClass(), args);
         System.exit(res);
      }

      public int run(String[] args) throws Exception
      {

        // Configuration processed by ToolRunner 
        Configuration conf = getConf();
        Job job = new Job(conf, "My Job");

        ...
        ...

        return job.waitForCompletion(true) ? 0 : 1;
      }
    }

现在编辑你的“hadoop jar”命令,如下所示:

hadoop jar YourApplication.jar [myDriverClass] args -libjars path/to/jar/file

现在让我们了解下面发生了什么。基本上我们通过实现TOOL Interface来处理新的命令行参数。 ToolRunner用于运行实现Tool接口的类。它与GenericOptionsParser结合使用来解析泛型hadoop命令行参数并修改工具的配置。

在我们的Main()中,我们调用ToolRunner.run(new Configuration(), new myDriverClass(), args) - 在使用给定的泛型参数解析后,它运行Tool.run(String [])给定的工具,。它使用给定的Configuration,或者如果它为null则构建一个,然后使用可能修改的conf版本设置Tool的配置。

现在在run方法中,当我们调用getConf()时,我们得到了Configuration的修改版本。 因此,请确保您的代码中包含以下行。如果您实现其他所有内容并仍然使用Configuration conf = new Configuration(),则无法正常工作。

Configuration conf = getConf();

答案 3 :(得分:0)

我通过实现ToolRunner找到了另一种解决方法,如下所示。使用这种方法,hadoop接受命令行选项。我们可以避免将文件添加到DistributedCache

的硬编码
 public class FlightsByCarrier extends Configured implements Tool {

       public int run(String[] args) throws Exception {
         // Configuration processed by ToolRunner
         Configuration conf = getConf();

         // Create a JobConf using the processed conf
         JobConf job = new JobConf(conf, FlightsByCarrier.class);

         // Process custom command-line options
         Path in = new Path(args[1]);
         Path out = new Path(args[2]);

         // Specify various job-specific parameters     
         job.setJobName("my-app");
         job.setInputPath(in);
         job.setOutputPath(out);
         job.setMapperClass(MyMapper.class);
         job.setReducerClass(MyReducer.class);

         // Submit the job, then poll for progress until the job is complete
         JobClient.runJob(job);
         return 0;
       }

       public static void main(String[] args) throws Exception {
         // Let ToolRunner handle generic command-line options 
         int res = ToolRunner.run(new Configuration(), new FlightsByCarrier(), args);

         System.exit(res);
       }
     }

答案 4 :(得分:0)

我找到了一个非常简单的问题解决方案: 以root身份登录:

  

cd / usr / lib   找 。 -name" opencsv.jar"

拿起文件的locatin。在我的情况下>我在/usr/lib/hive/lib/opencsv*.jar

下找到了它

现在提交命令

  

hadoop classpath

结果显示hadoop搜索jar文件的目录。 拿起一个目录并将opencsv * jar复制到该目录。

就我而言,它有效。