programing

jar를 설치하지 않고 maven 2 빌드 클래스 경로에 추가 할 수 있습니까?

nasanasas 2020. 9. 30. 10:58
반응형

jar를 설치하지 않고 maven 2 빌드 클래스 경로에 추가 할 수 있습니까?


Maven2는 실험 / 개발의 빠르고 더러운 목업 단계에서 나를 미치게 만듭니다.

pom.xml사용하려는 웹 앱 프레임 워크에 대한 종속성을 정의 하는 파일이 있으며 해당 파일에서 시작 프로젝트를 빠르게 생성 할 수 있습니다. 그러나, 때로는 이미이없는 제 3 자 라이브러리에 연결할 pom.xml정의 파일을, 그래서보다는 만드는 pom.xml손으로 제 3 자 lib 디렉토리의 파일 및 설치, 내에 종속성을 추가 pom.xml, 난 그냥 싶습니다 Maven에게 "내 정의 된 종속성에 추가로 포함 된 모든 jar도 포함하십시오 /lib."

간단해야 할 것 같지만, 그렇다면 뭔가 빠진 것입니다.

이를 수행하는 방법에 대한 모든 조언은 대단히 감사합니다. 그것도 부족하면 메이븐을 /lib디렉토리 로 가리키고 pom.xml모든 동봉 된 jar를 단일 종속성에 매핑하여 쉽게 생성 할 수 있는 간단한 방법이 있다면 이름 / 설치 및 링크를 한 번에 완료하는 것도 충분합니다.


대중적인 접근의 문제

인터넷에서 찾을 수있는 대부분의 답변은 로컬 저장소에 종속성을 설치하거나 "시스템"범위를 지정하고 pom프로젝트 소스와 함께 종속성을 배포하도록 제안합니다 . 그러나이 두 솔루션 모두 실제로 결함이 있습니다.

"로컬 리포지토리에 설치"접근 방식을 적용하면 안되는 이유

로컬 저장소에 종속성을 설치하면 그대로 유지됩니다. 배포 아티팩트가이 저장소에 액세스 할 수있는 한 정상적으로 작동합니다. 문제는 대부분의 경우이 저장소가 로컬 컴퓨터에 상주하므로 다른 컴퓨터에 대한이 종속성을 해결할 방법이 없다는 것입니다. 아티팩트를 특정 기계에 의존하게 만드는 것은 일을 처리하는 방법이 아닙니다. 그렇지 않으면이 종속성은 해당 프로젝트와 함께 작동하는 모든 컴퓨터에 로컬로 설치되어야하지만 더 좋지는 않습니다.

"시스템 범위"접근 방식을 적용해서는 안되는 이유

"시스템 범위"접근 방식으로 의존하는 jar는 저장소에 설치되거나 대상 패키지에 첨부되지 않습니다. 그렇기 때문에 배포 패키지를 사용할 때 해당 종속성을 해결할 방법이 없습니다. 시스템 범위 사용이 더 이상 사용되지 않는 이유라고 생각합니다. 어쨌든 더 이상 사용되지 않는 기능에 의존하고 싶지는 않습니다.

정적 프로젝트 내 저장소 솔루션

이것을 넣은 후 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.zMaven 형식의 그룹 ID를 가진 각 아티팩트에 대해 아티팩트 검색시 프로젝트 디렉토리 내에 다음 위치가 포함됩니다.

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

이에 대해 자세히 알아 보려면 이 블로그 게시물을 읽어보십시오 .

Maven을 사용하여 프로젝트 저장소에 설치

이 구조를 직접 만드는 대신 Maven 플러그인을 사용하여 jar를 아티팩트로 설치하는 것이 좋습니다. 따라서 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>

도우미 스크립트

각 lib에 대한 설치 명령을 실행하는 것은 다소 성 가시고 오류가 발생하기 쉬우므로 폴더의 모든 jar를 프로젝트 저장소에 자동으로 설치하는 동시에 모든 메타 데이터 (groupId, artifactId 등)를 자동으로 해결 하는 유틸리티 스크립트만들었습니다 lib. 파일 이름. 스크립트는 또한 .NET Framework에 복사하여 붙여 넣을 수 있도록 종속성 xml을 인쇄합니다 pom.

대상 패키지에 종속성 포함

프로젝트 내 저장소를 만들면 소스와 함께 프로젝트의 종속성을 배포하는 문제를 해결할 수 있지만 그 이후로 프로젝트의 대상 아티팩트는 게시되지 않은 jar에 따라 달라 지므로 설치할 때 리포지토리에는 해결할 수없는 종속성이 있습니다.

이 문제를 해결하려면 이러한 종속성을 대상 패키지에 포함하는 것이 좋습니다. 이것은 어셈블리 플러그인을 사용 하거나 OneJar 플러그인을 사용하여 더 잘 할 수 있습니다 . OneJar의 공식 문서는 이해하기 쉽습니다.


폐기 코드 전용

범위 == 시스템을 설정하고 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을 사용하여 빌드 된 war에 시스템 종속성을 포함하는 방법 참조 ).


프로젝트에 로컬 저장소를 만들 수 있습니다.

예를 들어 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에서 외부 라이브러리를 추가하는 방법


참고 : 시스템 범위 ( 이 페이지에 언급 됨 )를 사용할 때 Maven에는 절대 경로가 필요합니다.

jar가 프로젝트의 루트 아래에있는 경우 systemPath 값에 $ {basedir} 접두사를 붙일 수 있습니다.


이것은 내가 한 일이며 패키지 문제를 해결하고 체크 아웃 코드와 함께 작동합니다.

을 사용하는 경우 프로젝트에 새 폴더를 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.1JAR 파일을 해당 폴더에 복사했습니다.

다운로드 한 파일 (이 단계는 선택 사항이지만 경고를 제거함)을 나타 내기 위해 다음 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>

내가 만든 두 가지 선택적 파일은 POM에 대한 SHA1 체크섬과 누락 된 체크섬 경고를 제거하기위한 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>

저장소를 통해 프레임 워크를 확보하고 종속성을 미리 식별해야합니다. 시스템 범위를 사용하는 것은 사람들이 "종속성 관리에 관심이 없기 때문에"흔히 사용하는 실수입니다. 문제는이 작업을 수행하면 정상적인 상태에서 maven을 표시하지 않는 음란 한 maven 빌드가된다는 것입니다. 당신은 같은 방법 다음 더 나을 것 .


Maven 설치 플러그인 에는 jar를 로컬 저장소에 설치하는 명령 줄 사용이 있으며 POM은 선택 사항이지만 GroupId, ArtifactId, 버전 및 패키징 (모든 POM 항목)을 지정해야합니다.


이것이 우리가 로컬 항아리를 추가하거나 설치하는 방법입니다.

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

필수이기 때문에 기본 groupId 및 artifactId를 제공했습니다. :)


<scope>system</scope>다른 사람들이 설명하는 이유로 사용하는 것은 끔찍한 생각입니다. 로컬 저장소에 파일을 수동으로 설치하면 빌드를 재현 <url>file://${project.basedir}/repo</url>할 수 없게되며 (1) 올바른 형식의 fileURL 이 아닐 수 있기 때문에 사용 하는 것도 좋은 생각이 아닙니다 (예 : 프로젝트 이 프로젝트의 POM이 다른 사람의 프로젝트에 대한 종속성으로 사용되는 경우 결과를 사용할 수 없습니다.

아티팩트를 공용 저장소에 업로드하기를 꺼린다 고 가정하면 Simeon의 도우미 모듈 제안이 작업을 수행합니다. 하지만 이제 더 쉬운 방법이 있습니다 ...

권장 사항

사용 비는-받는다는 항아리 - 받는다는 - 플러그인 . 다른 접근 방식의 단점없이 원하는대로 정확하게 수행합니다.


이 작업을 수행하는 다른 방법을 찾았 습니다 . Heroku 게시물 에서 여기를 참조하십시오.

요약하면 (일부 복사 및 붙여 넣기에 대해 죄송합니다)

  • repo루트 폴더 아래 디렉토리를 만듭니다 .
yourproject
+-pom.xml
+-src
+-저장소
  • 이것을 실행하여 로컬 저장소 디렉토리에 jar를 설치하십시오.
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>

이러한 종류의 JAR을 적절하게 패키징하는 것에 대해 CloudBees 직원들과 오랫동안 논의한 후, 그들은 솔루션에 대한 흥미로운 좋은 제안을했습니다.

소속 된 POM install : install-file 실행으로 실행되는 기본 아티팩트로 기존 JAR을 첨부하는 가짜 Maven 프로젝트 생성. 다음은 이러한 POM kinf의 예입니다.

 <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 프로젝트 (모듈)를 만들어야한다는 점을 명심해야합니다. 그리고 모든 JAR 래퍼 및 기존 메인 프로젝트 인 모든 하위 모듈을 포함하는 상위 Maven 프로젝트가 생성되어야합니다. 구조는 다음과 같을 수 있습니다.

루트 프로젝트 (부모 POM 파일에 모듈 XML 요소가있는 모든 하위 모듈 포함 ) (POM 패키징)

JAR 1 래퍼 Maven 자식 프로젝트 (POM 패키징)

JAR 2 래퍼 Maven 자식 프로젝트 (POM 패키징)

메인 기존 Maven 자식 프로젝트 (WAR, JAR, EAR .... 패키징)

mvn : install 또는 mvn : packaging을 통해 실행중인 부모가 강제로 실행되고 하위 모듈이 실행됩니다. 프로젝트 구조를 변경해야하기 때문에 마이너스로 간주 될 수 있지만 마지막에는 비 정적 솔루션을 제공합니다.


문제 systemPath는 종속성의 jar가 아티팩트와 함께 전이 종속성으로 배포되지 않는다는 것입니다. 여기에 게시 한 내용을 시도해보십시오. 프로젝트 jar 파일을 Mavenize하거나 WEB-INF / lib에 넣는 것이 가장 좋습니까?

그런 다음 평소와 같이 종속성을 선언하십시오.

그리고 꼬리말을 읽으십시오.


빠르고 더러운 솔루션을 원한다면 다음을 수행 할 수 있습니다 (테스트 프로젝트를 제외하고는 이것을 권장하지 않지만 maven은 이것이 적절하지 않다고 불평 할 것입니다).

필요한 각 jar 파일에 대한 종속성 항목을 가급적 펄 스크립트 또는 이와 유사한 것으로 추가하고 pom 파일에 복사 / 붙여 넣기하십시오.

#! /usr/bin/perl

foreach my $n (@ARGV) {

    $n=~s@.*/@@;

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

나에게 가장 간단한 것은 사용자 정의 jar를 포함하도록 maven-compiler-plugin을 구성하는 것입니다. 이 예제는 lib 디렉토리에있는 모든 jar 파일을로드합니다.

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

빠른 & 더티 (알렉스의 답변에 따라) 배치 솔루션 :

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해당 컨텐츠를 종속성으로 열고 복사하십시오.

제 경우에는 코드를 컴파일하는 데 라이브러리 만 필요했고이 솔루션은 그 목적에 가장 적합했습니다.


내가 찾은 이상한 해결책 :

Eclipse 사용

  • 간단한 (비 메이븐) 자바 프로젝트 생성
  • Main 클래스 추가
  • 모든 병을 클래스 경로에 추가하십시오.
  • Runnable JAR 내보내기 (여기에 다른 방법이 없기 때문에 중요합니다)
  • select Extract required libraries into generated JAR
  • decide the licence issues
  • tadammm...install the generated jar to your m2repo
  • add this single dependency to your other projects.

cheers, Balint


Even though it does not exactly fit to your problem, I'll drop this here. My requirements were:

  1. Jars that can not be found in an online maven repository should be in the SVN.
  2. If one developer adds another library, the other developers should not be bothered with manually installing them.
  3. The IDE (NetBeans in my case) should be able find the sources and javadocs to provide autocompletion and help.

Let's talk about (3) first: Just having the jars in a folder and somehow merging them into the final jar will not work for here, since the IDE will not understand this. This means all libraries have to be installed properly. However, I dont want to have everyone installing it using "mvn install-file".

In my project I needed metawidget. Here we go:

  1. Create a new maven project (name it "shared-libs" or something like that).
  2. Download metawidget and extract the zip into src/main/lib.
  3. The folder doc/api contains the javadocs. Create a zip of the content (doc/api/api.zip).
  4. Modify the pom like this
  5. Build the project and the library will be installed.
  6. Add the library as a dependency to your project, or (if you added the dependency in the shared-libs project) add shared-libs as dependency to get all libraries at once.

Every time you have a new library, just add a new execution and tell everyone to build the project again (you can improve this process with project hierachies).


To install the 3rd party jar which is not in maven repository use maven-install-plugin.

Below are steps:

  1. Download the jar file manually from the source (website)
  2. Create a folder and place your jar file in it
  3. Run the below command to install the 3rd party jar in your local maven repository

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

Below is the e.g one I used it for simonsite log4j

mvn install:install-file -Dfile=/Users/athanka/git/MyProject/repo/log4j-rolling-appender.jar -DgroupId=uk.org.simonsite -DartifactId=log4j-rolling-appender -Dversion=20150607-2059 -Dpackaging=jar

  1. In the pom.xml include the dependency as below

      <dependency> 
            <groupId>uk.org.simonsite</groupId>
            <artifactId>log4j-rolling-appender</artifactId>
            <version>20150607-2059</version> 
      </dependency>
    
  2. Run the mvn clean install command to create your packaging

Below is the reference link:

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


For those that didn't find a good answer here, this is what we are doing to get a jar with all the necessary dependencies in it. This answer (https://stackoverflow.com/a/7623805/1084306) mentions to use the Maven Assembly plugin but doesn't actually give an example in the answer. And if you don't read all the way to the end of the answer (it's pretty lengthy), you may miss it. Adding the below to your pom.xml will generate 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>

This doesn't answer how to add them to your POM, and may be a no brainer, but would just adding the lib dir to your classpath work? I know that is what I do when I need an external jar that I don't want to add to my Maven repos.

Hope this helps.


What works in our project is what Archimedes Trajano wrote, but we had in our .m2/settings.xml something like this:

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

and the * should be changed to central. So if his answer doesn't work for you, you should check your settings.xml


I alluded to some python code in a comment to the answer from @alex lehmann's , so am posting it here.

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

I just wanted a quick and dirty workaround... I couldn't run the script from Nikita Volkov: syntax error + it requires a strict format for the jar names.

I made this Perl script which works with whatever format for the jar file names, and it generates the dependencies in an xml so it can be copy pasted directly in a pom.

If you want to use it, make sure you understand what the script is doing, you may need to change the lib folder and the value for the groupId or 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;

참고URL : https://stackoverflow.com/questions/364114/can-i-add-jars-to-maven-2-build-classpath-without-installing-them

반응형