Maven: додайте залежність до баночки відносним шляхом


232

У мене є власна баночка, яку я хочу додати до своєї пом’ї як залежності.

Але я не хочу додавати його до сховища. Причина в тому, що я хочу, щоб мої звичайні команди Maven, такі як mvn compileі т.д., працювали поза коробкою. (Не вимагаючи від розробників a, додавати його до якогось сховища самостійно).

Я хочу, щоб jar знаходився у вкладці 3rdparty у контролі джерела та посилався на нього відносним шляхом від файлу pom.xml.

Чи можна це зробити? Як?

Відповіді:


343

Я хочу, щоб jar знаходився у вкладці 3rdparty у контролі джерела та посилався на нього відносним шляхом від файлу pom.xml.

Якщо ви дійсно хочете цього (зрозуміти, якщо ви не можете використовувати корпоративне сховище), то моя порада буде використовувати «сховище файлів» локальне для проекту і не використовувати в systemконтекстну залежність. systemScoped слід уникати таких залежностей не працюють добре в багатьох ситуаціях (наприклад , в зборі), вони викликають більше проблем , ніж користі.

Отже, замість цього оголосіть сховище, локальне для проекту:

<repositories>
  <repository>
    <id>my-local-repo</id>
    <url>file://${project.basedir}/my-repo</url>
  </repository>
</repositories>

Встановіть свою бібліотеку третьої сторони в ньому , використовуючи install:install-fileз localRepositoryPathпараметром:

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
                         -DartifactId=<myArtifactId> -Dversion=<myVersion> \
                         -Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

Оновлення: виявляється, що install:install-fileігнорує, localRepositoryPathколи використовується версія 2.2 плагіна. Однак він працює з версією 2.3 і пізнішої версії плагіна. Тому використовуйте повністю кваліфіковане ім'я плагіна, щоб вказати версію:

mvn org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file \
                         -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
                         -DartifactId=<myArtifactId> -Dversion=<myVersion> \
                         -Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

документація maven-install-plugin

Нарешті, заявіть про це як про будь-яку іншу залежність (але без systemсфери застосування):

<dependency>
  <groupId>your.group.id</groupId>
  <artifactId>3rdparty</artifactId>
  <version>X.Y.Z</version>
</dependency>

Це IMHO краще рішення, ніж використання systemсфери, оскільки ваша залежність буде сприйматись як хороший громадянин (наприклад, вона буде включена в збори тощо).

Тепер я маю зазначити, що "правильним способом" вирішити цю ситуацію у корпоративному середовищі (можливо, це не так) було б використовувати корпоративний репозиторій.


2
Це відмінна ідея, але в Maven 2.2.1 плагін для встановлення, здається, ігнорує localRepositoryPath...
Джейк

1
Навіщо оголошувати місцеве репо? Чому б просто не відпустити його в ~ / .m2 / з рештою.
Лейф Грюнвольдт

6
@ leif81 Оскільки тоді репо і бібліотеки перевіряються в сховище SCM -> У кожного, хто робить вихідний замовлення, є все необхідне для створення копії бібліотеки / програми.
Дарт Android

6
У мене була така ж проблема, як у @lemon, яку я вирішив, роблячи замість цього basedir/./my-local-repoсингл ..
Брайан

2
Упаковка повинна бути баночкою, тому -Dapacking = jar
Danila Piatov

127

Використання області systemзастосування. ${basedir}- це каталог вашої пом.

<dependency>
    <artifactId>..</artifactId>
    <groupId>..</groupId>
    <scope>system</scope>
    <systemPath>${basedir}/lib/dependency.jar</systemPath>
</dependency>

Однак бажано, щоб ви встановили свою банку в сховище, а не вносили її в SCM - адже саме це намагається ліквідувати Maven.


15
Систему сфери застосування слід уникати скрізь, де це можливо. Встановити JAR у сховищі - це краще рішення ...
Gandalf StormCrow

14
так, якщо можливо. він прямо сказав, що не хоче поміщати його у сховище. Я додав коментар, щоб зазначити, що це не є хорошою практикою. Але це працює.
Божо

groovy, ти рішення є найбільш прийнятним до цих пір, я думаю, я повністю перечитав питання
мураха

Так - саме питання виключає найкращу відповідь. Якщо розмістити все на своєму єдиному сервері управління джерелом, мало спільного із "побудовою поза коробкою"; скоріше, все просто треба "контролювати". Зробіть реєстрацію pom's & settings.xml (вказує на внутрішній репо) та використовуйте два сервери для свого проекту: (1) управління джерелом, (2) створений контроль артефактів. Це робить приблизно стільки ж сенсу перевірки в банках, як і перевірки в dll (мій старий корпус насправді робив реєстрацію банки & lib.a / .so / .dll. Наш сервер p4 згодом був настільки повільним, деякі таємно використовували hg протягом дня -до дня роботи. Проблема вирішена?
michael

будь-який спосіб вказати каталог, який містить банки замість цього, щоб ми не повинні додавати кожен і кожен так само, як gradle може це зробити?
Дін Гіллер

29

Це ще один метод на додаток до моєї попередньої відповіді на " Чи можна додати банки до Maven 2 build classpath без їх встановлення?"

Це дозволить подолати ліміт при використанні багатомодульних збірок, особливо якщо на завантажений JAR посилається в дочірніх проектах поза батьківським. Це також зменшує роботу з налаштування, створюючи POM і файли SHA1 як частину збірки. Він також дозволяє файлу перебувати в будь-якому місці проекту, не фіксуючи імен і не дотримуючись структури сховища Maven.

Для цього використовується плагін maven-install. Для цього вам потрібно створити мультимодульний проект і створити новий проект, що представляє збірку, щоб встановити файли в локальне сховище і переконатися, що один є першим.

У вас багатомодульний проект pom.xml виглядатиме так:

<packaging>pom</packaging>
<modules>
<!-- The repository module must be first in order to ensure
     that the local repository is populated -->
    <module>repository</module>
    <module>... other modules ...</module>
</modules>

Файл сховища / pom.xml буде містити визначення для завантаження JAR, які є частиною вашого проекту. Нижче наведено кілька фрагментів файлу pom.xml.

<artifactId>repository</artifactId>
<packaging>pom</packaging>

Упаковка з помпою перешкоджає цьому робити будь-які тести або компілювати або генерувати будь-який jar файл. М'ясо pom.xml знаходиться в розділі збірки, де використовується плагін maven-install.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <executions>
                <execution>
                        <id>com.ibm.db2:db2jcc</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <configuration>
                            <groupId>com.ibm.db2</groupId>
                            <artifactId>db2jcc</artifactId>
                            <version>9.0.0</version>
                            <packaging>jar</packaging>
                            <file>${basedir}/src/jars/db2jcc.jar</file>
                            <createChecksum>true</createChecksum>
                            <generatePom>true</generatePom>
                        </configuration>
                </execution>
                <execution>...</execution>
            </executions>
        </plugin>
    </plugins>
</build>

Щоб встановити більше одного файлу, просто додайте більше виконань.


Це єдине, що працювало на мій багатомодульний проект. Місцевий підхід <репозиторій> з невідомих причин не спрацював. Тож дякую!
Лонзак

10

Це працює на мене: Скажімо, у мене така залежність

<dependency>
    <groupId>com.company.app</groupId>
    <artifactId>my-library</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/my-library.jar</systemPath>
</dependency>

Потім додайте шлях до класу для вашої системної залежності вручну, як це

<Class-Path>libs/my-library-1.0.jar</Class-Path>

Повна конфігурація:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifestEntries>
                <Build-Jdk>${jdk.version}</Build-Jdk>
                <Implementation-Title>${project.name}</Implementation-Title>
                <Implementation-Version>${project.version}</Implementation-Version>
                <Specification-Title>${project.name} Library</Specification-Title>
                <Specification-Version>${project.version}</Specification-Version>
                <Class-Path>libs/my-library-1.0.jar</Class-Path>
            </manifestEntries>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.company.app.MainClass</mainClass>
                <classpathPrefix>libs/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/libs/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

9

Раніше я писав про шаблон для цього.

Він дуже схожий на рішення, запропоноване Паскалем, хоча він переміщує всі такі залежності у виділений модуль репозиторію, так що вам не доведеться повторювати його скрізь, якщо залежність використовується, якщо це багатомодульна збірка.


6

В основному додайте це до pom.xml:

...

<repositories>
   <repository>
       <id>lib_id</id>
       <url>file://${project.basedir}/lib</url>
   </repository>
</repositories>

...

<dependencies>
  ...
  <dependency>
      <groupId>com.mylibrary</groupId>
      <artifactId>mylibraryname</artifactId>
      <version>1.0.0</version>
  </dependency>
  ...
</dependencies>

4

ми перейшли на Gradle, і це працює набагато краще в gradle;) ми просто вказуємо папку, в яку можна перекидати банки для тимчасових ситуацій. У нас ще є більшість наших банок, визначених у розділі управління типовою залежністю (тобто такому ж, як у Maven). Це лише ще одна залежність, яку ми визначаємо.

тому в основному зараз ми можемо просто запустити будь-яку банку, яку нам захочеться, для тимчасового тестування, якщо вона десь не є в сховищі Maven.


1
Чи можете ви навести приклад, як ви це робили?
Томас

2

Одне невелике доповнення до рішення, розміщеного Паскалем

Коли я дотримувався цього маршруту, під час встановлення банку ojdbc у мене з’явилася помилка в Maven.

[INFO] --- maven-install-plugin:2.5.1:install-file (default-cli) @ validator ---
[INFO] pom.xml not found in ojdbc14.jar

Після додавання -DpomFile проблема була вирішена.

$ mvn install:install-file -Dfile=./lib/ojdbc14.jar -DgroupId=ojdbc \
   -DartifactId=ojdbc -Dversion=14 -Dpackaging=jar -DlocalRepositoryPath=./repo \
   -DpomFile=~/.m2/repository/ojdbc/ojdbc/14/ojdbc-14.pom

0

Ви можете використовувати затемнення для створення файлу Jar: Експорт / Виконання Jar


Не впевнений, що це відповідає на питання. У нього вже є файл як баночка.
Йоганнес Яндер

Eclipse підтримує uberjar або затінену банку, тому її рішення, але не для maven
Alex Lehmann
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.