Как сделать монолитный jar.file? - PullRequest
0 голосов
/ 22 марта 2012

Мне нужно создать jar-файл задания hadoop, использующий mahout и кучу других библиотек. Мне нужно, чтобы я мог запускать задание без дополнительных jar.files, чтобы все указанные классы были упакованы с результирующим файлом jar. Как это можно сделать?

Ответы [ 5 ]

2 голосов
/ 23 марта 2012

Hadoop умеет читать баночки в банке.Внесите изменения в свой скрипт Ant, чтобы включить все jar-файлы зависимостей в папку с именем lib, и добавьте эту папку lib в выходной Jar-файл.Иногда это лучший выбор, если у вас есть несколько больших jar-файлов, так как это сокращает время создания jar-файла.

См. Эту статью, чтобы узнать о некоторых вариантах использования сторонних библиотек с hadoop

2 голосов
/ 22 марта 2012

Сконфигурируйте ваш файл сборки для копирования всех ссылочных классов в каталог сборки. Например, в ant:

    <path id="classpathunjar">
        <fileset dir="${lib.dir}" includes="*.jar" excludes="sqljdbc4.jar"/>
    </path>


    <target name="compile" depends="clean">
        ...
        <unjar dest="${build.dir}">
            <path refid="classpathunjar" />
        </unjar>
        ...
   </target>

Но лучше, если вы сможете обойтись без этого. Используйте функцию libjars для загрузки jar-файлов во все узлы, если вы делаете это для запуска заданий mapreduce в кластере hadoop

1 голос
/ 23 марта 2012

Обратите внимание, что дополнительные jar-файлы должны быть помещены в подкаталог lib / (да, jar-файлы внутри jar-файла). Я использую следующую сборку maven, которую я нашел где-то еще.

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
  <id>job</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>false</unpack>
      <scope>runtime</scope>
      <outputDirectory>lib</outputDirectory>
      <excludes>
        <exclude>org.apache.hadoop:hadoop-core</exclude>
        <exclude>${artifact.groupId}:${artifact.artifactId}</exclude>
      </excludes>
    </dependencySet>
    <dependencySet>
      <unpack>false</unpack>
      <scope>system</scope>
      <outputDirectory>lib</outputDirectory>
      <excludes>
        <exclude>${artifact.groupId}:${artifact.artifactId}</exclude>
      </excludes>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <directory>${basedir}/target/classes</directory>
      <outputDirectory>/</outputDirectory> 
      <excludes>
        <exclude>*.jar</exclude>
      </excludes>
    </fileSet>
  </fileSets>
</assembly>
1 голос
/ 22 марта 2012

В общем смысле это иногда невозможно, так как файлы JAR имеют ресурсы, которые должны находиться в определенных местах, и два конфликтующих, но необходимых ресурса могут помешать комбинации (Think META-INF / MANIFEST.MF)

Однако во многих случаях это очень просто. В основном вы распаковываете JAR-файл, который нужно добавить (это формат zip-файла), и «добавляете» классы и что-то еще в существующий JAR-файл.

Лучший выбор, если вы создаете исполняемый файл JAR, - это добавить запись ClassPath в ваш запускающий файл MANIFEST.MF и отправить оба файла JAR в структуре каталогов, совместимой с добавленной вами записью ClassPath.

1 голос
/ 22 марта 2012

Jar - это просто Zip контейнер.

Вы можете вручную распаковать и изменить файл Jar с необходимыми классами или использовать, например, дескриптор jar-with-dependencies *1007* сборки Maven система.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...