Есть ли в любом случае, чтобы исключить артефакты, унаследованные от родительского POM?


артефакты из зависимостей можно исключить, объявив <exclusions> элемент внутри <dependency> но в этом случае необходимо исключить артефакт, унаследованный от родительского проекта. Ниже приводится выдержка из обсуждаемого пом:

<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.jar С ALL-DEPS существует в среде выполнения, хотя и не экспортируется, сталкивается с mail.jar который существует на родителе, который ограничен как compile.

решение может быть, чтобы избавиться от почты.jar от родительского POM, но большинство проектов, которые наследуют base, нуждаются в этом (как и транзитивная зависимость для log4j). Так что я хотел бы сделать это просто исключить родительскую библиотеку из дочернего проекта, как это можно было бы сделать, если base была зависимость, а не Родительский pom:

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

7 ответов:

некоторые идеи:

  1. может быть, вы просто не могли бы наследовать от родителя в этом случае (и объявить зависимость от base исключение). Не удобно, если у вас много вещей в Родительском пом.

  2. еще одна вещь, чтобы проверить было бы объявить mail артефакт с версией требуется ALL-DEPS под dependencyManagement в Родительском pom для принудительной конвергенции (хотя я не уверен, что это решит область видимости проблема.)

<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.14 log4j вместо еретической версии 1.2.15 (почему они не отметили вышеуказанные зависимости как дополнительно?!).

вы можете группировать свои зависимости в рамках другого проекта с помощью packaging pom как описано Sonatypes Лучшие Практики:

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

ваш Дочерний проект наследует этот родительский 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>

вы пробовали явно объявить версию почты.банку хочешь? Разрешение зависимостей 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

это может показаться экстремальным, но точно так же "ад наследования" является причиной того, что некоторые люди поворачиваются спиной к объектно-ориентированному программированию или так же хирурги поддерживают вас в живых с помощью коронарного шунтирования: удалите проблемные <parent> и блок скопировать и вставить все <dependencies> вам нужна.

предположение о том, что разделение poms на родительский и дочерний для " повторного использования "и" избегания повторного использования " следует игнорировать и вы должны сначала удовлетворить свои непосредственные потребности. Избыточность имеет свои преимущества, а именно - независимость от внешних осложнений.

это проще, чем кажется, если вы создаете эффективный pom (eclipse предоставляет его, но вы можете создать его из командной строки).

пример

Я хочу использовать logback но мой родитель пом использует log4j и я не хочу идти и толкать зависимость других детей от log4j вниз в их собственную pom.xml файлы, так что моя-свободна.

вы можете получить много от родителя, но иногда ваш родитель не знает, что хорошо для вас.

переопределите зависимость (в дочернем pom) с помощью scope система, указывающая на пустую банку:

<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

когда вы вызываете пакет, но не хотите, чтобы некоторые из его зависимостей вы можете сделать что-то вроде этого (в этом случае я не хотел, чтобы старый 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, поэтому это, возможно, не оптимально.

лучше всего сделать зависимости, которые вы не всегда хотите наследовать транзитивными.

вы можете сделать это, пометив их в Родительском POM с предусмотренной.

Если вы все еще хотите, чтобы родитель управлял версиями этих deps, вы можете использовать <dependencyManagement> тег для установки нужных версий без явного наследования их или передачи этого наследования детям.