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

종속성의 아티팩트는 <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>
...



답변

몇 가지 아이디어 :

  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로 되돌릴 수 있습니다 (위의 종속성을 선택 사항 으로 표시하지 않은 이유는 무엇입니까?!).

답변

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>


답변

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

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

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

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

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


답변

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


답변

원하는 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>


답변

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

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

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


답변

패키지를 호출했지만 종속성 중 일부를 원하지 않을 때 다음과 같은 작업을 수행 할 수 있습니다 (이 경우 최신 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을 처음 사용하므로 최적이 아닐 수 있습니다.