어쨌든 상위 POM에서 상속 된 아티팩트를 제외 할 수 있습니까?


119

종속성의 아티팩트는 <exclusions>내부에 요소 를 선언하여 제외 할 수 있지만 <dependency>이 경우 상위 프로젝트에서 상속 된 아티팩트를 제외해야합니다. 논의중인 POM의 일부는 다음과 같습니다.

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>

    <dependencies>      
        <dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>ALL-DEPS</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

base유물에 의존 javax.mail:mail-1.4.jar하고, ALL-DEPS같은 라이브러리의 다른 버전에 따라 달라집니다. mail.jarfrom ALL-DEPS이 실행 환경에 존재 한다는 사실로 인해 내보내지는 않지만 mail.jar으로 범위가 지정된 상위에 존재하는 과 충돌 합니다 compile.

해결책은 상위 POM에서 mail.jar을 제거하는 것이지만 base를 상속하는 대부분의 프로젝트는이를 필요로합니다 (log4j에 대한 전 이적 종속성). 그래서 내가하고 싶은 것은 단순히 부모 pom이 아닌 종속성 인 경우 수행 할 수있는 자식 프로젝트에서 부모의 라이브러리를 제외 하는 것입니다 base.

...
    <dependency>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
        <type>pom<type>
        <exclusions>
          <exclusion>
             <groupId>javax.mail</groupId>
             <artifactId>mail</artifactId>
          </exclusion>
        </exclusions>
    </dependency>
...

답변:


49

몇 가지 아이디어 :

  1. 이 경우 부모로부터 상속 할 수 없을 수도 있습니다 (그리고 base예외 로 종속성을 선언 ). 부모 pom에 많은 항목이 있으면 편리하지 않습니다.

  2. 테스트해야 할 또 다른 것은 수렴을 강제하기 위해 부모 pom에서 아래에 mail필요한 버전으로 아티팩트 를 선언하는 것입니다 (범위 지정 문제를 해결할 수는 없지만).ALL-DEPSdependencyManagement

<dependencyManagement>
  <dependencies>
    <dependency>    
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>???</version><!-- put the "right" version here -->
    </dependency>
  </dependencies>
</dependencyManagement>
  1. 또는 mail의존하는 기능을 사용하지 않는 경우 log4j 에서 종속성을 제외 할 수 있습니다 (그리고 이것이 제가 할 일입니다).
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.15</version>
  <scope>provided</scope>
  <exclusions>
    <exclusion>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
    </exclusion>
    <exclusion>
      <groupId>javax.jms</groupId>
      <artifactId>jms</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jdmk</groupId>
      <artifactId>jmxtools</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jmx</groupId>
      <artifactId>jmxri</artifactId>
    </exclusion>
  </exclusions>
</dependency>
  1. 또는 이단 1.2.15 버전 대신 log4j 버전 1.2.14로 되돌릴 수 있습니다 (위의 종속성을 선택 사항 으로 표시하지 않은 이유는 무엇입니까?!).

답장을 보내 주셔서 감사합니다. 유용한 정보가 많이 포함되어 있습니다. 1) 알다시피 부모 pom은 기본이 종속성으로 표시되면 전 이적으로 해결되는 종속성뿐만 아니라 회사의 모든 프로젝트에서 재사용되는 공통보고, 소스 관리 및 기타 항목을 포함하기 때문에 최적이 아닙니다. 2)와 관련하여 나는 그것을 시도했지만 제공된 것처럼 아티팩트의 범위를 지정했으며 작동했습니다 :). 처음에는 컴파일이 제공된 것보다 우선하므로 작동하지 않을 것이라고 생각했지만 다행히도 내가 틀 렸습니다 (하위 POM이 부모의 구성을 재정의 함)
Miguel

29

pomSonatypes Best Practices에 설명 된대로 패키징 을 사용 하여 다른 프로젝트 내에서 종속성을 그룹화 할 수 있습니다 .

<project>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>base-dependencies</artifactId>
    <groupId>es.uniovi.innova</groupId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <dependencies>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>
</project>

부모 -pom에서 참조하십시오 (종속성을 확인하십시오 <type>pom</type>).

<project>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>base</artifactId>
    <groupId>es.uniovi.innova</groupId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <dependencies>
        <dependency>
            <artifactId>base-dependencies</artifactId>
            <groupId>es.uniovi.innova</groupId>
            <version>1.0.0</version>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

귀하의 하위 프로젝트는 이전과 같이이 parent-pom을 상속합니다. 그러나 이제는 dependencyManagement블록 내의 하위 프로젝트에서 메일 종속성을 제외 할 수 있습니다 .

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>test</groupId>
    <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <artifactId>base-dependencies</artifactId>
                <groupId>es.uniovi.innova</groupId>
                <version>1.0.0</version>
                <exclusions>
                    <exclusion>
                        <groupId>javax.mail</groupId>
                        <artifactId>mail</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

4
+1, 하위 pom은 <dependencyManagement>가 아닌 <dependencies> 섹션을 사용해야하지만 후자는 상위 pom 내에서 종속성 버전 을 관리하기위한 것 입니다.
Matthew Wise

1
이것은 또한 :-) 재료의 법안 일명 BOM로 알려져있다
핌 Hazebroek

전이 종속성에서만 작동합니까? 내 부모 pom에는 log4j가 포함되어 있으며 내 pom의 로그 백이 제대로 작동하지 않습니다.
Sridhar Sarnobat

10

부모 pom을 사용하지 마십시오

이것은 극단적으로 들릴 수 있지만 같은 방식으로 "상속 지옥"이 일부 사람들이 객체 지향 프로그래밍 (또는 상속보다 구성 선호) 에 등을 돌리고 문제가있는 <parent>블록을 제거하고 필요한 모든 것을 복사하여 붙여 넣는 이유입니다 <dependencies>(팀이 제공하는 경우 이 자유).

"재사용"및 "중복 방지"를 위해 리딩을 부모와 자식으로 나누는 가정은 무시해야하며 즉각적인 필요를 먼저 충족시켜야합니다 (치료는 질병보다 최악 임). 게다가 중복성은 장점이 있습니다. 즉, 외부 변경의 독립성 (즉 안정성)입니다.

이것은 효과적인 pom을 생성하는 것보다 쉽습니다 (eclipse는 그것을 제공하지만를 사용하여 명령 줄에서 생성 할 수 있습니다 mvn help:effective).

logback내 slf4j 바인딩 으로 사용 하고 싶지만 부모 pom에는 log4j종속성이 포함되어 있습니다. 나는 가고 싶지 않고 다른 아이들의 log4j에 대한 의존성을 자신의 pom.xml파일 로 밀어 넣어서 내 파일이 방해받지 않도록해야합니다.


1
업데이트 된 버전의 부모 pom을 사용해야하는 경우 향후 유지 관리자가이를 다시 수행해야하므로이 내용 (및 수행 한 절차)을 매우 신중하게 문서화하십시오.
Thorbjørn Ravn Andersen

확실히 부모 pom에서 종속성을 사용하지 않는다는 의미입니까? 부모 pom은 여전히 ​​종속성 버전 및 공통 플러그인을 관리하는 데 매우 유용합니다. 그냥 의존성 삽입에 사용은 역효과를 낳을 수 있습니다 - 우리는 (microservices에 대한 부모를위한 필수 봄 부팅 스타터 세트 등)만을 가지고 있어야 종속성을 사용
아 미트 골드 스타 인

아니요, 가벼운 부모 pom을 사용한다고 말하는 것이 아닙니다. 다른 앱은 원하지 않는 부모 pom의 정크에 의존하기 때문에 팀의 다른 사람들은 부모 pom을 다듬을 수 없습니다.
Sridhar Sarnobat

8

scope시스템이 빈 jar를 가리키는 종속성 (하위 pom에서)을 재정의하십시오 .

<dependency>
    <groupId>dependency.coming</groupId>
    <artifactId>from.parent</artifactId>
    <version>0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/empty.jar</systemPath>
</dependency>

jar에는 하나의 빈 파일 만 포함될 수 있습니다.

touch empty.txt
jar cvf empty.txt

윈도우 10에서 나는 실행했다, 답변 주셔서 감사합니다 notepad empty.class다음 jar cvf empty.jar empty.class빈 항아리를 생성 할 수 있습니다.
Rov

1
나쁜 관행처럼 보이는
표트르 잭

6

원하는 mail.jar 버전을 명시 적으로 선언 해 보셨습니까? Maven의 종속성 확인은 다른 모든 버전에 대한 종속성 확인에 이것을 사용해야합니다.

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>
    <dependencies>          
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>VERSION-#</version>
            <scope>provided</scope>
        </dependency> 
        <dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>ALL-DEPS</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

1
Pascal의 해결 방법 # 2도 유효하므로 실제로 메일 종속성을 제공된대로 선언해야한다는 점도 고려했습니다. 감사합니다.
Miguel

제공된 범위가 작동하지 않았습니다. 스코프 테스트를 사용했습니다. 내 대답을 확인하십시오. stackoverflow.com/a/55970293/4587961
Yan Khonski

3

가장 좋은 방법은 항상 상속하고 싶지 않은 종속성을 자동으로 만드는 것입니다.

제공된 범위로 상위 pom에 표시하여이를 수행 할 수 있습니다.

여전히 부모가 이러한 dep의 버전을 관리하도록하려면 <dependencyManagement>태그를 사용하여 명시 적으로 상속하거나 해당 상속을 자식에게 전달하지 않고도 원하는 버전을 설정할 수 있습니다 .


1

패키지를 호출했지만 종속성 중 일부를 원하지 않을 때 다음과 같은 작업을 수행 할 수 있습니다 (이 경우 최신 log4j를 사용해야했기 때문에 이전 log4j를 추가하지 않았습니다).

<dependency>
  <groupId>package</groupId>
  <artifactId>package-pk</artifactId>
  <version>${package-pk.version}</version>

  <exclusions>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<!-- LOG4J -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.5</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-api</artifactId>
  <version>2.5</version>
</dependency>

이것은 나를 위해 작동하지만 Java / maven을 처음 사용하므로 최적이 아닐 수 있습니다.


Stack Overflow에 오신 것을 환영합니다. 제가 지속적으로 질문을 무시한 무례한 사람들이 게시물을 올리지 못하도록 방해하지 않도록하십시오.
Sridhar Sarnobat

1

이 더러운 일을 정말해야 했어요 ... 방법은 다음과 같습니다.

해당 종속성을 scope로 재정의했습니다 test. 범위 provided는 나를 위해 작동하지 않았습니다.

Spring Boot 플러그인을 사용하여 fat jar를 빌드합니다. 우리는 모듈이 일반적인 예 Springfox의 자신감-2, 공통 라이브러리를 정의합니다. 내 슈퍼 서비스 는 부모를 공유 해야합니다 (원하는 것은 아니지만 회사 규칙이 적용됩니다!).

그래서 내 부모님이나 커먼즈에는 pom이 있습니다.

<dependencyManagement>

    <!- I do not need Springfox in one child but in others ->

    <dependencies>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-bean-validators</artifactId>
            <version>${swagger.version}</version>
        </dependency>

       <!- All services need them ->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${apache.poi.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

그리고 내 슈퍼 서비스 pom.

<name>super-service</name>
<parent>
    <groupId>com.company</groupId>
    <artifactId>common</artifactId>
    <version>1</version>
</parent>

<dependencies>

    <!- I don't need them ->

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-bean-validators</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-core</artifactId>
        <version>2.8.0</version>
        <scope>test</scope>
    </dependency>

    <!- Required dependencies ->

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
     <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
    </dependency>
</dependencies>

이것은 최종 지방 인공물의 크기입니다.

82.3 MB (86,351,753 bytes) - redefined dependency with scope test
86.1 MB (90,335,466 bytes) - redefined dependency with scope provided
86.1 MB (90,335,489 bytes) - without exclusion

또한이 답변은 언급 할 가치가 있습니다-그렇게하고 싶었지만 게으르다 ... https://stackoverflow.com/a/48103554/4587961


0

부모 pom을 pom 유형의 종속성으로 추가하고 제외 할 수 있습니다. 어쨌든 부모 pom이 다운로드되기 때문입니다. 이것은 나를 위해 일했습니다.

<dependency>
  <groupId>com.abc.boot</groupId>
  <artifactId>abc-boot-starter-parent</artifactId>
  <version>2.1.5.RELEASE</version>
  <type>pom</type>
  <exclusions>
    <exclusion>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
    </exclusion>
  </exclusions>   
</dependency>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.