Maven: thêm một phụ thuộc vào một jar theo đường dẫn tương đối


232

Tôi có một bình độc quyền mà tôi muốn thêm vào pom của mình như một phần phụ thuộc.

Nhưng tôi không muốn thêm nó vào một kho lưu trữ. Lý do là tôi muốn các lệnh maven thông thường của mình như mvn compile, v.v., hoạt động tốt. (Không yêu cầu từ các nhà phát triển a để thêm nó vào một số kho lưu trữ).

Tôi muốn jar nằm trong lib của bên thứ 3 trong kiểm soát nguồn và liên kết với nó bằng đường dẫn tương đối từ tệp pom.xml.

Điều này có thể được thực hiện? Làm sao?

Câu trả lời:


343

Tôi muốn jar nằm trong lib của bên thứ 3 trong kiểm soát nguồn và liên kết với nó bằng đường dẫn tương đối từ tệp pom.xml.

Nếu bạn thực sự muốn điều này (hiểu, nếu bạn không thể sử dụng một kho lưu trữ của công ty), sau đó lời khuyên của tôi sẽ được sử dụng một "kho tập tin" địa phương để dự án và không sử dụng một systemsự phụ thuộc chỉnh phạm vi. Phạm systemvi nên tránh, các phụ thuộc như vậy không hoạt động tốt trong nhiều tình huống (ví dụ như trong lắp ráp), chúng gây ra nhiều rắc rối hơn lợi ích.

Vì vậy, thay vào đó, khai báo một kho lưu trữ cục bộ cho dự án:

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

Cài đặt lib của bên thứ ba trong đó sử dụng install:install-filevới các localRepositoryPaththông số:

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

Cập nhật: Dường như install:install-filebỏ qua localRepositoryPathkhi sử dụng phiên bản 2.2 của plugin. Tuy nhiên, nó hoạt động với phiên bản 2.3 trở lên của plugin. Vì vậy, sử dụng tên đầy đủ của plugin để chỉ định phiên bản:

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>

tài liệu maven-install-plugin

Cuối cùng, khai báo nó giống như bất kỳ phụ thuộc nào khác (nhưng không có systemphạm vi):

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

Đây là một giải pháp tốt hơn so với việc sử dụng một systemphạm vi vì sự phụ thuộc của bạn sẽ được đối xử như một công dân tốt (ví dụ: nó sẽ được bao gồm trong một hội đồng, v.v.).

Bây giờ, tôi phải đề cập rằng "cách đúng đắn" để giải quyết tình huống này trong môi trường doanh nghiệp (có thể không phải là trường hợp ở đây) sẽ là sử dụng kho lưu trữ của công ty.


2
Đây là một ý tưởng tuyệt vời, nhưng trên Maven 2.2.1, plugin cài đặt dường như đang bỏ qua localRepositoryPath...
Jake

1
Tại sao tuyên bố một repo địa phương? Tại sao không chỉ để nó đi vào ~ / .m2 / với phần còn lại.
Leif Gruenwoldt

6
@ leif81 Bởi vì sau đó repo và thư viện được kiểm tra vào kho SCM -> Bất cứ ai thực hiện kiểm tra nguồn đều có mọi thứ họ cần để xây dựng một bản sao của thư viện / ứng dụng.
Darth Android

6
Tôi đã gặp vấn đề tương tự như @lemon, mà tôi đã khắc phục bằng cách thực hiện basedir/./my-local-repovới một lần duy nhất ..
Brian

2
Bao bì phải là bình, do đó -Dpackaging = jar
Danila Piatov

127

Sử dụng systemphạm vi. ${basedir}là thư mục của pom của bạn.

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

Tuy nhiên, bạn nên cài đặt jar của mình trong kho lưu trữ và không cam kết nó với SCM - sau tất cả những gì maven cố gắng loại bỏ.


15
Hệ thống phạm vi phải được tránh ở mọi nơi có thể. Cài đặt JAR trong kho lưu trữ là một giải pháp tốt hơn ...
Gandalf StormCrow

14
vâng, nếu có thể anh nói rõ ràng rằng anh không muốn đưa nó vào kho lưu trữ. Tôi đã thêm một bình luận để chỉ ra rằng đây không phải là một thực hành tốt. Nhưng nó làm việc.
Bozho

Groovy, giải pháp của bạn là dễ chấp nhận nhất cho đến nay tôi đoán .. Tôi hoàn toàn đọc sai câu hỏi
ant

Có - câu hỏi tự loại trừ câu trả lời tốt nhất. Đưa mọi thứ vào máy chủ kiểm soát nguồn duy nhất của bạn không liên quan gì đến việc "xây dựng ra khỏi hộp"; thay vào đó, mọi thứ chỉ cần được "kiểm soát". Thực hiện đăng ký pom's & settings.xml (chỉ vào repo nội bộ ) và sử dụng hai máy chủ cho dự án của bạn: (1) kiểm soát nguồn, (2) kiểm soát tạo tác được tạo. Việc kiểm tra trong các lọ cũng có ý nghĩa nhiều như việc kiểm tra trong dll (công cụ cũ của tôi thực sự đã kiểm tra các lọ & lib.a / .so /. công việc hàng ngày. Vấn đề được giải quyết?
michael

có cách nào để chỉ định một thư mục chứa các tệp thay vì vậy chúng ta không phải thêm từng thư mục giống như lớp có thể làm được không?
Dean Hiller

29

Đây là một phương thức khác ngoài câu trả lời trước đây của tôi tại Tôi có thể thêm bình vào maven 2 build classpath mà không cần cài đặt chúng không?

Điều này sẽ vượt qua giới hạn khi sử dụng các bản dựng đa mô-đun, đặc biệt nếu JAR đã tải xuống được tham chiếu trong các dự án con bên ngoài cha mẹ. Điều này cũng làm giảm công việc thiết lập bằng cách tạo các tệp POM và SHA1 như một phần của bản dựng. Nó cũng cho phép tệp cư trú bất cứ nơi nào trong dự án mà không sửa tên hoặc theo cấu trúc kho lưu trữ maven.

Điều này sử dụng plugin maven-install-plugin. Để làm việc này, bạn cần thiết lập một dự án đa mô-đun và có một dự án mới đại diện cho bản dựng để cài đặt các tệp vào kho lưu trữ cục bộ và đảm bảo rằng đó là dự án đầu tiên.

Dự án đa mô-đun pom.xml của bạn sẽ trông như thế này:

<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>

Sau đó, tệp repository / pom.xml sẽ chứa các định nghĩa để tải lên các JAR là một phần của dự án của bạn. Sau đây là một số đoạn của tệp pom.xml.

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

Bao bì pom ngăn điều này thực hiện bất kỳ kiểm tra hoặc biên dịch hoặc tạo bất kỳ tệp jar nào. Phần mềm của pom.xml nằm trong phần xây dựng nơi sử dụng plugin maven-install-plugin.

<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>

Để cài đặt nhiều hơn một tệp, chỉ cần thêm nhiều lần thực thi.


Đây là điều duy nhất làm việc cho dự án đa mô-đun của tôi. Cách tiếp cận <repository> cục bộ vì một lý do không xác định đã không hoạt động. Vì vậy, cảm ơn!
Lonzak

10

Điều này hiệu quả với tôi: Hãy nói rằng tôi có sự phụ thuộc này

<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>

Sau đó, thêm đường dẫn lớp cho phụ thuộc hệ thống của bạn theo cách thủ công như thế này

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

Cấu hình đầy đủ:

<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

Trước đây tôi đã viết về một mô hình để làm điều này.

Nó rất giống với giải pháp do Pascal đề xuất, mặc dù nó chuyển tất cả các phụ thuộc như vậy vào một mô-đun kho lưu trữ chuyên dụng để bạn không phải lặp lại ở mọi nơi mà phụ thuộc được sử dụng nếu đó là bản dựng đa mô-đun.


6

Về cơ bản, hãy thêm phần này vào tệp 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

chúng tôi đã chuyển sang lớp và điều này hoạt động tốt hơn nhiều trong lớp;). chúng tôi chỉ xác định một thư mục mà chúng tôi có thể thả bình vào các tình huống tạm thời như thế. Chúng tôi vẫn có hầu hết các lọ được định nghĩa là phần quản lý phụ thuộc điển hình (ví dụ như maven). Đây chỉ là một phụ thuộc nữa mà chúng tôi xác định.

vì vậy về cơ bản bây giờ chúng ta có thể bỏ bất kỳ jar nào chúng ta muốn vào thư mục lib của mình để kiểm tra tạm thời nếu nó không phải là kho lưu trữ trong maven ở đâu đó.


1
Bạn có thể cho một ví dụ về cách bạn đã làm điều này?
Thomas

2

Một bổ sung nhỏ cho giải pháp được đăng bởi Pascal

Khi tôi theo lộ trình này, tôi đã gặp lỗi trong maven khi cài đặt jar ojdbc.

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

Sau khi thêm -DpomFile, vấn đề đã được giải quyết.

$ 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

Bạn có thể sử dụng nhật thực để tạo tệp Jar có thể chạy được: Xuất / Chạy tệp Jar


Không chắc chắn rằng đó là trả lời câu hỏi. Anh ấy có tập tin như một cái bình rồi.
Julian Jander

Eclipse hỗ trợ jar uberjar hoặc shaded, vì vậy đây là một giải pháp, nhưng không phải cho maven
Alex Lehmann
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.