当前位置: 首页 > 知识库问答 >
问题:

如何将外部jar添加到hadoop作业中?

严正诚
2023-03-14

我有一个Hadoop作业,其中映射器必须使用外部jar。

我试图将这个jar传递给映射器的JVM

通过hadoop命令上的-libjars参数

hadoop jar mrrunner.jar DAGMRRunner -libjars <path_to_jar>/colt.jar

via作业。addFileToClassPath

job.addFileToClassPath(new Path("<path_to_jar>/colt.jar"));

HADOOP_CLASSPATH。

g1mihai@hydra:/home/g1mihai/$ echo $HADOOP_CLASSPATH
<path_to_jar>/colt.jar

这些方法都不起作用。这是我得到的堆栈跟踪。它抱怨的缺失类是SparseDoubleMatrix1D在colt.jar.

如果我需要提供任何其他调试信息,请告诉我。谢谢

15/02/14 16:47:51 INFO mapred.MapTask: Starting flush of map output
15/02/14 16:47:51 INFO mapred.LocalJobRunner: map task executor complete.
15/02/14 16:47:51 WARN mapred.LocalJobRunner: job_local368086771_0001
java.lang.Exception: java.lang.NoClassDefFoundError: Lcern/colt/matrix/impl/SparseDoubleMatrix1D;
        at org.apache.hadoop.mapred.LocalJobRunner$Job.runTasks(LocalJobRunner.java:462)
        at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:522)
Caused by: java.lang.NoClassDefFoundError: Lcern/colt/matrix/impl/SparseDoubleMatrix1D;
        at java.lang.Class.getDeclaredFields0(Native Method)
        at java.lang.Class.privateGetDeclaredFields(Class.java:2499)
        at java.lang.Class.getDeclaredField(Class.java:1951)
        at java.io.ObjectStreamClass.getDeclaredSUID(ObjectStreamClass.java:1659)
        at java.io.ObjectStreamClass.access$700(ObjectStreamClass.java:72)
        at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:480)
        at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:468)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:468)
        at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:365)
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:602)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
        at BoostConnector.ConnectCalculateBoost(BoostConnector.java:39)
        at DAGMapReduceSearcher$Map.map(DAGMapReduceSearcher.java:46)
        at DAGMapReduceSearcher$Map.map(DAGMapReduceSearcher.java:22)
        at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
        at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:784)
        at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
        at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:243)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: cern.colt.matrix.impl.SparseDoubleMatrix1D
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 28 more

共有3个答案

陆才俊
2023-03-14

使用分布式缓存-您可以在缓存中拥有任何可执行文件或小型参考文件,并将其用于MR作业。

https://hadoop.apache.org/docs/r1.2.1/api/org/apache/hadoop/filecache/DistributedCache.html

运行MR作业有两种方法,一种是在运行时使用类名,另一种是在导出jar时提到主类。

hadoop jar jarname.jar DriverClassName Input-Location Output-Location
hadoop jar jarname.jar Input-Location Output-Location
郁烨
2023-03-14

我用了这个:

$ export LIBJARS=$HOME/.m2/repository/net/sf/opencsv/opencsv/2.3/opencsv-2.3.jar,$HOME/.m2/repository/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar,$HOME/.m2/repository/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0.jar,$HOME/.m2/repository/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar
$ export HADOOP_CLASSPATH=`echo ${LIBJARS} | sed s/,/:/g`
$ $HADOOP_HOME/bin/hadoop jar $HOME/.m2/repository/hadoopTest/hadoopTest/0.0.2-SNAPSHOT/hadoopTest-0.0.2-SNAPSHOT.jar hadoopTest.testTask.TestTask -libjars ${LIBJARS} $HADOOP_HOME/input/ $HADOOP_HOME/output

它可以与Hadoop 3.2.0配合使用。

袁秦迟
2023-03-14

我相信这个问题值得一个详细的回答,我昨天被困在这个问题上,浪费了很多时间。我希望这个答案能帮助所有碰巧遇到这个问题的人。有几个选项可以解决此问题:

>

使用“Hadoop classpath”-在命令行上运行命令“Hadoop classpath”,然后找到一个合适的文件夹并将jar文件复制到该位置,Hadoop将从那里获取依赖项。这不适用于CloudEra等,因为您可能没有将文件复制到hadoop类路径文件夹的读/写权限。

我使用的选项是使用Hadoop jar命令指定-LIBJARS。首先确保您编辑了驱动程序类:

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

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

在Main()中,我们调用了ToolRunner。run(new Configuration(),new myDriverClass(),args)-这将逐个工具运行给定的工具。使用给定的泛型参数进行分析后运行(字符串[])。它使用给定的配置,如果为null,则构建一个配置,然后使用可能修改的conf版本设置工具的配置。

现在在run方法中,当我们调用getConf()时,我们得到了配置的修改版本。因此,请确保您的代码中有以下行。如果您实现了所有其他功能,并且仍然使用Configuration conf=new Configuration(),那么什么都不会起作用。

Configuration conf = getConf();
 类似资料:
  • 是的...已经讨论了很多了。 但是,有很多不明确的地方,提供了一些答案...包括在jars/executor/driver配置或选项中重复jar引用。 类路径的影响 驱动程序 执行程序(用于正在运行的任务) 两者 一点也不 对于任务(对每个执行者) 用于远程驱动程序(如果在群集模式下运行) 方法 方法 或 或 不要忘记,spark-submit的最后一个参数也是一个.jar文件。 如果我从文档中猜

  • 我正在尝试在服务器上运行hadoop作业。版本为。 我有一大堆罐子,我在运行: 即使对应的类在JAR中,我也会得到下面的错误: 线程“main”java.lang.noClassDeffounder中出现异常错误:org/apache/avro/mapreduce/avrokeyInputFormat在generateTrainningData.main(generateTrainningData

  • 这个标题非常接近如何在IntelliJ IDEA中添加外部库?以及将外部jar(lib/*.jar)添加到IntelliJ IDEA项目的正确方法。然而,我已经检查过了。 在“如何在IntelliJ IDEA中添加外部库?”,我不能很好地理解最佳答案的含义,也不能很好地理解在评论空间中提出相同问题的人。所以,有人给了他一个回答,显示了“向IntelliJ IDEA项目添加外部jar(lib/*.j

  • *用Winrar打开。jar文件,转到/lib文件夹,手动选择my文件,然后确保选择Winrar为您提供压缩选项的左下角的No Compression选项,以防您在Google上找到该选项,但没有人回答。

  • 我试过这样做:将外部jar(lib/*.jar)添加到IntelliJ IDEA项目的正确方法是在lib文件夹(我已经创建)下添加一个外部jar库文件“temp.jar”,并将其标记为库。然后我构建/重新构建项目,错误仍然表示包com。实例temp不存在。我正在使用Intellij IDEA 13.1免费版和Gradle。

  • 我是Android Studio的新手。我需要做的是在 文件夹下面的 中添加几个jar文件。 如果有人知道怎么做,请帮助我。