Можно ли добавить jars в maven 2 build classpath без их установки?

Maven2 сводит меня с ума во время экспериментальной/быстрой и грязной фазы разработки.

У меня есть файл pom.xml, который определяет зависимости для структуры веб-приложения, которую я хочу использовать, и я могу быстро генерировать стартовые проекты из этого файла. Однако иногда я хочу связать с сторонней библиотекой, у которой еще нет файла pom.xml, поэтому вместо того, чтобы создавать файл pom.xml для стороннего lib вручную и устанавливать его, и добавлять зависимость к my pom.xml, я просто хотел бы сказать Maven: "Помимо моих определенных зависимостей, включите любые банки, которые находятся в /lib тоже".

Кажется, что это должно быть просто, но если это так, я чего-то не хватает.

Любые указатели на то, как это сделать, очень ценятся. Короче говоря, если есть простой способ указать maven в каталог /lib и легко создать pom.xml со всеми вложенными банками, сопоставленными с одной зависимостью, которую я мог бы затем назвать/установить и связать одним махом также будет достаточно.

Ответы

Ответ 1

Проблемы популярных подходов

Большинство ответов, которые вы найдете в Интернете, предложит либо установить зависимость в вашем локальном репозитории, либо указать "системную" область в pom и распределить зависимость с источником вашего проекта. Но оба этих решения на самом деле ошибочны.

Почему вы не должны применять подход "Установить для локального репо"

Когда вы устанавливаете зависимость в своем локальном репозитории, она остается там. Ваш артефакт распространения будет отлично работать, если он имеет доступ к этому репозиторию. Проблема в большинстве случаев заключается в том, что этот репозиторий будет находиться на вашей локальной машине, поэтому не будет возможности разрешить эту зависимость на любой другой машине. Ясно, что ваш артефакт зависит от конкретной машины - это не способ справиться с ситуациями. В противном случае эта зависимость должна быть локально установлена ​​на каждой машине, работающей с этим проектом, которая не лучше.

Почему вы не должны применять подход "Системная область"

Баны, на которые вы зависите, с подходом "Системная область" не устанавливаются ни в какой репозиторий или не привязаны к вашим целевым пакетам. Поэтому у вашего дистрибутива не будет возможности разрешить эту зависимость при ее использовании. Я считаю, что причиной тому стало то, что использование системной области даже устарело. В любом случае вы не хотите полагаться на устаревшую функцию.

Статическое решение для репозитория в проекте

Поместив это в свой pom:

<repository>
    <id>repo</id>
    <releases>
        <enabled>true</enabled>
        <checksumPolicy>ignore</checksumPolicy>
    </releases>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
    <url>file://${project.basedir}/repo</url>
</repository>

для каждого артефакта с идентификатором группы формы x.y.z Maven будет включать следующее местоположение внутри вашего проекта dir в поиске артефактов:

repo/
| - x/
|   | - y/
|   |   | - z/
|   |   |   | - ${artifactId}/
|   |   |   |   | - ${version}/
|   |   |   |   |   | - ${artifactId}-${version}.jar

Чтобы подробнее рассказать об этом, вы можете прочитать это сообщение в блоге.

Использовать Maven для установки в проект repo

Вместо того, чтобы вручную создавать эту структуру, я рекомендую использовать плагин Maven для установки ваших банок в качестве артефактов. Таким образом, для установки артефакта в репозиторий in-project в папке repo выполните:

mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]

Если вы выберете этот подход, вы сможете упростить декларацию репозитория в pom до:

<repository>
    <id>repo</id>
    <url>file://${project.basedir}/repo</url>
</repository>

Вспомогательный script

Поскольку выполнение команды установки для каждой библиотеки вызывает раздражение и определенно подверженность ошибкам, я создал утилиту script, которая автоматически устанавливает все банки из папки lib в репозиторий проекта, а также автоматически разрешать все метаданные (groupId, artifactId и т.д.) из имен файлов. script также распечатывает зависимости xml, которые вы можете скопировать-вставить в pom.

Включить зависимости в целевом пакете

Когда вы создадите репозиторий внутри проекта, вы решите проблему распределения зависимостей проекта с его источником, но с тех пор ваш артефакт проекта будет зависеть от не опубликованных банок, поэтому, когда вы 'установить его в репозиторий, он будет иметь неразрешимые зависимости.

Чтобы обойти эту проблему, я предлагаю включить эти зависимости в ваш целевой пакет. Это можно сделать либо с помощью Плагина сборки, либо с помощью OneJar Plugin. Официальную документацию на OneJar легко понять.

Ответ 2

Только для выброса кода

установить scope == систему и просто создать groupId, artifactId и версию

<dependency>
    <groupId>org.swinglabs</groupId>
    <artifactId>swingx</artifactId>
    <version>0.9.2</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/swingx-0.9.3.jar</systemPath>
</dependency>

Примечание: системные зависимости не копируются в приведенные jar/war
(см. Как включить системные зависимости в войну, построенные с использованием maven)

Ответ 3

Вы можете создать локальный репозиторий в своем проекте

Например, если в структуре проекта есть libs

  • В папке libs вы должны создать структуру каталогов, например: /groupId/artifactId/version/artifactId-version.jar

  • В вашем pom.xml вы должны зарегистрировать репозиторий

    <repository>
        <id>ProjectRepo</id>
        <name>ProjectRepo</name>
        <url>file://${project.basedir}/libs</url>
    </repository>
    
  • и добавьте зависимость как обычно

    <dependency>
        <groupId>groupId</groupId>
        <artifactId>artifactId</artifactId>
        <version>version</version>
    </dependency>
    

Вот и все.

Для получения более подробной информации: Как добавить внешние библиотеки в Maven

Ответ 4

Примечание. При использовании области "Система" (как указано на этой странице), Maven нуждается в абсолютных путях.

Если ваши банки находятся под вашим корнем проекта, вам нужно будет префикс ваших значений systemPath с помощью ${basedir}.

Ответ 5

Вам действительно нужно получить фреймворк через репозиторий и определить свои зависимости впереди. Использование области системы - распространенная ошибка, которую люди используют, потому что они "не заботятся об управлении зависимостями". Беда в том, что при этом вы получаете извращенную сборку maven, которая не будет показывать maven в нормальном состоянии. Вам будет лучше следовать подходу, например this.

Ответ 6

Это то, что я сделал, он также работает вокруг проблемы с пакетом, и он работает с извлеченным кодом.

Я создал новую папку в проекте, в моем случае я использовал repo, но не стесняйтесь использовать src/repo

В моем POM у меня была зависимость, которая не находится в каких-либо общедоступных хранилищах maven

<dependency>
    <groupId>com.dovetail</groupId>
    <artifactId>zoslog4j</artifactId>
    <version>1.0.1</version>
    <scope>runtime</scope>
</dependency>

Затем я создал следующие каталоги repo/com/dovetail/zoslog4j/1.0.1 и скопировал JAR файл в эту папку.

Я создал следующий файл POM для представления загруженного файла (этот шаг не является обязательным, но он удаляет ПРЕДУПРЕЖДЕНИЕ) и помогает следующему парню выяснить, откуда я получил файл.

<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dovetail</groupId>
    <artifactId>zoslog4j</artifactId>
    <packaging>jar</packaging>
    <version>1.0.1</version>
    <name>z/OS Log4J Appenders</name>
    <url>http://dovetail.com/downloads/misc/index.html</url>
    <description>Apache Log4j Appender for z/OS Logstreams, files, etc.</description>
</project>

Два дополнительных файла, которые я создаю, это контрольные суммы SHA1 для POM и JAR для удаления отсутствующих предупреждений контрольной суммы.

shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar \
          > repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar.sha1

shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom \
          > repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom.sha1

Наконец, я добавлю следующий фрагмент в свой pom.xml, который позволяет мне ссылаться на локальный репозиторий

<repositories>
    <repository>
        <id>project</id>
        <url>file:///${basedir}/repo</url>
    </repository>
</repositories>

Ответ 7

Плагин установки Maven имеет использование командной строки для установки jar в локальный репозиторий, POM не является обязательным, но вам нужно будет указать GroupId, ArtifactId, Version и Packaging (все материалы POM).

Ответ 8

Так мы добавляем или устанавливаем локальную банку

    <dependency>
        <groupId>org.example</groupId>
        <artifactId>iamajar</artifactId>
        <version>1.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/iamajar.jar</systemPath>
    </dependency>

i дал некоторые значения по умолчанию groupId и artifactId, потому что они являются обязательными:)

Ответ 9

Использование <scope>system</scope> является ужасной идеей по причинам, объясняемым другими, установка файла вручную в локальный репозиторий делает сборку невоспроизводимой, а использование <url>file://${project.basedir}/repo</url> не является хорошей идеей либо потому, что (1) это может быть не правильно сформированный URL file (например, если проект выгружен в каталоге с необычными символами), (2) результат неприменим, если этот проект POM используется как зависимость от кого-то проекта elses.

Предполагая, что вы не хотите загружать артефакт в общедоступный репозиторий, предложение Симеона о вспомогательном модуле выполняет эту работу. Но теперь есть более простой способ...

Рекомендация

Используйте non-maven-jar-maven-plugin. Именно то, о чем вы просили, без каких-либо недостатков других подходов.

Ответ 10

Я нашел другой способ сделать это, см. здесь сообщение Героку

Подводя итог (извините за некоторые копии и вставки)

  • Создайте каталог repo в корневой папке:
yourproject
+- pom.xml
+- src
+- repo
  • Запустите это, чтобы установить банку в локальный каталог репо
mvn deploy:deploy-file -Durl=file:///path/to/yourproject/repo/ -Dfile=mylib-1.0.jar -DgroupId=com.example -DartifactId=mylib -Dpackaging=jar -Dversion=1.0
  • Добавьте этот pom.xml:
<repositories>
    <!--other repositories if any-->
    <repository>
        <id>project.local</id>
        <name>project</name>
        <url>file:${project.basedir}/repo</url>
    </repository>
</repositories>


<dependency>
    <groupId>com.example</groupId>
    <artifactId>mylib</artifactId>
    <version>1.0</version>  
</dependency>

Ответ 11

После долгого обсуждения с парнями CloudBees о надлежащей упаковке maven таких JAR-приложений они сделали интересное предложение для решения:

Создание поддельного проекта Maven, который присоединяет ранее существовавший JAR в качестве первичного артефакта, который входит в состав POM install: install-file. Вот пример такого рода POM:

 <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <version>2.3.1</version>
            <executions>
                <execution>
                    <id>image-util-id</id>
                    <phase>install</phase>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                    <configuration>
                        <file>${basedir}/file-you-want-to-include.jar</file>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>${project.artifactId}</artifactId>
                        <version>${project.version}</version>
                        <packaging>jar</packaging>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Но для его реализации необходимо изменить существующую структуру проекта. Во-первых, вы должны иметь в виду, что для каждого такого типа JAR должен быть создан другой поддельный проект Maven (модуль). И должен быть создан родительский проект Maven, включающий все подмодули, которые включают: все обертки JAR и существующий основной проект. Структура может быть:

корневой проект (содержащий родительский файл POM включает в себя все подмодули с XML-элементом module) (упаковка POM)

JAR 1 оболочка проекта Maven (упаковка POM)

JAR 2 оболочка проекта Maven (упаковка POM)

основной существующий дочерний проект Maven (WAR, JAR, EAR....)

Когда родительский процесс, запущенный через mvn: install или mvn: упаковка принудительно, и будут выполняться подмодули. Это может быть обеспокоено здесь минусом, поскольку структуру проекта следует изменить, но в конце предлагает нестационарное решение.

Ответ 12

Проблема с systemPath заключается в том, что банки зависимостей не будут распределены по вашим артефактам как транзитивные зависимости. Попробуйте то, что я разместил здесь: Лучше ли Mavenize создавать файлы проекта jar или помещать их в WEB-INF/lib?

Затем объявляйте зависимости, как обычно.

И, пожалуйста, прочитайте примечание нижнего колонтитула.

Ответ 13

Если вы хотите быстрое и грязное решение, вы можете сделать следующее (хотя я не рекомендую это ни для чего, кроме тестовых проектов, maven будет жаловаться по длине, что это не правильно).

Добавьте запись зависимости для каждого файла jar, который вам нужен, желательно с perl script или что-то подобное и скопируйте/вставьте в ваш файл pom.

#! /usr/bin/perl

foreach my $n (@ARGV) {

    [email protected]*/@@;

    print "<dependency>
    <groupId>local.dummy</groupId>
    <artifactId>$n</artifactId>
    <version>0.0.1</version>
    <scope>system</scope>
    <systemPath>\${project.basedir}/lib/$n</systemPath>
</dependency>
";

Ответ 14

Что мне кажется самым простым, просто настройте ваш maven-compiler-plugin, чтобы включить ваши пользовательские банки. В этом примере загружаются любые файлы jar в каталоге lib.

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <includes>
                    <include>lib/*.jar</include>
                </includes>
            </configuration>
        </plugin>

Ответ 15

Быстрое и пакетное решение (на основе ответа Алекса):

libs.bat

@ECHO OFF
FOR %%I IN (*.jar) DO (
echo ^<dependency^>
echo ^<groupId^>local.dummy^</groupId^>
echo ^<artifactId^>%%I^</artifactId^>
echo ^<version^>0.0.1^</version^>
echo ^<scope^>system^</scope^>
echo ^<systemPath^>${project.basedir}/lib/%%I^</systemPath^>
echo ^</dependency^>
)

Выполните его следующим образом: libs.bat > libs.txt. Затем откройте libs.txt и скопируйте его содержимое как зависимости.

В моем случае мне нужно было только библиотеки для компиляции моего кода, и это решение было наилучшим для этой цели.

Ответ 16

Странное решение, которое я нашел:

с помощью Eclipse

  • создать простой (не-maven) проект java
  • добавить основной класс
  • добавить все банки в путь к классам
  • export Runnable JAR (это важно, потому что здесь нет другого способа сделать это)
  • выберите Извлечь необходимые библиотеки в сгенерированный JAR
  • решить проблемы с лицензией.
  • tadammm... установить сгенерированную банку в ваш m2repo
  • добавьте эту единственную зависимость в другие ваши проекты.

веселит, Балинт

Ответ 17

Несмотря на то, что это не соответствует вашей проблеме, я брошу это здесь. Мои требования:

  • Ящики, которые не могут быть найдены в онлайн-хранилище maven, должны находиться в SVN.
  • Если один разработчик добавляет другую библиотеку, другим разработчикам не стоит беспокоиться об установке вручную.
  • IDE (NetBeans в моем случае) должна быть в состоянии найти источники и javadocs для предоставления автозаполнения и помощи.

Сначала поговорим о (3): просто наличие банок в папке и каким-то образом их объединение в финальную банку не сработает здесь, так как среда IDE не поймет это. Это означает, что все библиотеки должны быть установлены правильно. Тем не менее, я не хочу, чтобы все устанавливали его с помощью "mvn install-file".

В моем проекте мне нужен метавидит. Здесь мы идем:

  • Создайте новый проект maven (назовите его "shared-libs" или что-то в этом роде).
  • Загрузите metawidget и извлеките zip в src/main/lib.
  • В папке doc/api содержатся javadocs. Создайте почтовый индекс содержимого (doc/api/api.zip).
  • Измените pom как это
  • Создайте проект, и библиотека будет установлена.
  • Добавить библиотеку в зависимости от вашего проекта или (если вы добавили зависимость в проекте shared-libs), добавьте shared-libs в качестве зависимости, чтобы сразу получить все библиотеки.

Каждый раз, когда у вас есть новая библиотека, просто добавьте новое исполнение и расскажите всем, чтобы снова создать проект (вы можете улучшить этот процесс с помощью иерархиев проекта).

Ответ 18

Чтобы установить стороннюю банку, которая не находится в репозитории maven, используйте maven-install-plugin.

Ниже приведены шаги:

  • Загрузите файл jar вручную из источника (веб-сайта)
  • Создайте папку и поместите в нее свой файл jar
  • Запустите команду ниже, чтобы установить стороннюю банку в локальный репозиторий maven.

mvn install: install-file -Dfile = -DgroupId = -DartifactId = -Dversion = -Dpackaging =

Ниже приведен пример, например, я использовал его для simonsite log4j

mvn install: install-file -Dfile =/Пользователи/athanka/ git/MyProject/repo/log4j-rolling-appender.jar -DgroupId = uk.org.simonsite -DartifactId = log4j-roll-appender -Dversion = 20150607-2059 -Dpackaging = jar

  1. В pom.xml включена зависимость ниже

      <dependency> 
            <groupId>uk.org.simonsite</groupId>
            <artifactId>log4j-rolling-appender</artifactId>
            <version>20150607-2059</version> 
      </dependency>
    
  2. Запустите команду mvn clean install для создания вашей упаковки

Ниже приведена ссылка:

https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html

Ответ 19

Для тех, кто не нашел здесь хорошего ответа, это то, что мы делаем, чтобы получить банку со всеми необходимыми зависимостями в ней. Этот ответ (fooobar.com/questions/8245/...) упоминает использование плагина Maven Assembly, но на самом деле не дает примера в ответе. И если вы не прочитаете весь путь до конца ответа (довольно длинный), вы можете пропустить его. Добавление ниже к вашему pom.xml приведет к созданию target/${PROJECT_NAME}-${VERSION}-jar-with-dependencies.jar

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <!-- get all project dependencies -->
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <!-- MainClass in mainfest make a executable jar -->
                <archive>
                  <manifest>
                    <mainClass>my.package.mainclass</mainClass>
                  </manifest>
                </archive>

            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id>
                <!-- bind to the packaging phase -->
                <phase>package</phase> 
                <goals>
                    <goal>single</goal>
                </goals>
              </execution>
            </executions>
        </plugin>

Ответ 20

Это не ответит, как добавить их в ваш POM, и может быть без проблем, но просто добавит ли каталог lib к вашей работе в classpath? Я знаю, что это то, что я делаю, когда мне нужна внешняя банка, которую я не хочу добавлять в мои репозитории Maven.

Надеюсь, что это поможет.

Ответ 21

Что работает в нашем проекте, это то, что написал Архимед Траяно, но у нас в нашем .m2/settings.xml что-то вроде этого:

 <mirror>
  <id>nexus</id>
  <mirrorOf>*</mirrorOf>
  <url>http://url_to_our_repository</url>
 </mirror>

а значение * должно быть изменено на центральное. Поэтому, если его ответ не работает для вас, вы должны проверить свои настройки .xml

Ответ 22

Я упомянул некоторый код python в комментарии к ответу от @alex lehmann, поэтому размещаю его здесь.

def AddJars(jarList):
  s1 = ''
  for elem in jarList:
   s1+= """
     <dependency>
        <groupId>local.dummy</groupId>
        <artifactId>%s</artifactId>
        <version>0.0.1</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/manual_jars/%s</systemPath>
     </dependency>\n"""%(elem, elem)
  return s1

Ответ 23

Вы можете добавить jar, выполнив:

Для gradle просто поместите следующий код в build.gradle:

dependencies {
...
compile fileTree(dir: 'lib', includes: ['suitetalk-*0.jar'])
...
}

а для мавена просто следуйте шагам:

Для Intellij: File-> проект structure-> modules-> зависимость tab-> нажмите + sign-> jar и dependency-> выберите банки, которые вы хотите import-> ok-> применить (если они видны) ) → оК

Помните, что если у вас есть какой-либо java.lang.NoClassDefFoundError: Could not initialize class исключение java.lang.NoClassDefFoundError: Could not initialize class во время выполнения, это означает, что зависимости в jar не установлены, для этого вам нужно добавить все зависимости в родительский проект.

Ответ 24

Мне просто нужен быстрый и грязный обходной путь... Я не мог запустить script из Nikita Volkov: синтаксическая ошибка + для этого требуется строгий формат для названий баннеров.

Я сделал этот Perl script, который работает с любым форматом для имен файлов jar и генерирует зависимости в xml, чтобы его можно было скопировать в pom.

Если вы хотите использовать его, убедитесь, что вы понимаете, что делает script, вам может потребоваться изменить папку lib и значение для groupId или artifactId...

#!/usr/bin/perl

use strict;
use warnings;

open(my $fh, '>', 'dependencies.xml') or die "Could not open file 'dependencies.xml' $!";
foreach my $file (glob("lib/*.jar")) {
    print "$file\n";
    my $groupId = "my.mess";
    my $artifactId = "";
    my $version = "0.1-SNAPSHOT";
    if ($file =~ /\/([^\/]*?)(-([0-9v\._]*))?\.jar$/) {
        $artifactId = $1;
        if (defined($3)) {
            $version = $3;
        }
        `mvn install:install-file -Dfile=$file -DgroupId=$groupId -DartifactId=$artifactId -Dversion=$version -Dpackaging=jar`;
        print $fh "<dependency>\n\t<groupId>$groupId</groupId>\n\t<artifactId>$artifactId</artifactId>\n\t<version>$version</version>\n</dependency>\n";
        print " => $groupId:$artifactId:$version\n";
    } else {
        print "##### BEUH...\n";
    }
}
close $fh;