Saltar al contenido

Frasco sombreado de Maven utilizado como dependencia del proyecto externo

Solución:

El escenario clásico es:

  • Un proyecto que produce un uber-jar tiene sus propias dependencias (dependency elementos en su pom.xml file) que luego se empaquetan juntos en un uber-jar como artefacto Maven
  • Al usar este uber-jar como dependencia (dependency elemento) de otro proyecto, Maven inspeccionaría entonces su <artifact>-<version>.pom archivo (publicado junto con el artefacto final en el repositorio de Maven), que es básicamente una copia renombrada de su original pom.xml archivo, donde las dependencias (dependency element) fueron declarados (exactamente las dependencias empaquetadas en el uber-jar).
  • Como ya los tiene empaquetados, le gustaría ignorar los .pom archivo (y su dependencies elemento), para eso necesitas agregar exclusions como sigue:

    <dependency>
        <groupId>com.sample</groupId>
        <artifactId>something-uber</artifactId>
        <version>some-version</version>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

Nota: la función anterior solo está disponible desde Maven 3.2.1.

Como tal, le está dejando en claro a Maven que no desea ninguna dependencia transitiva y que la mediación de dependencia de Maven no las activará.


Como nota al margen: esta no es una buena práctica tener un uber-jar como dependencia de un proyecto: solo hará que el mantenimiento sea más difícil ya que no puede controlar las dependencias transitivas a través de dependencyManagement o dependencies orden del proyecto dependiente. Como tal, siempre necesitará volver a empaquetar el uber jar cada vez que una dependencia (una de sus transitivas) necesite mantenimiento (cambiar de versión, etc.) y tenga mucho menos control sobre el proyecto dependiente (nuevamente, un mantenimiento más difícil).


Como el pom.xml en su proyecto fuente que produce el uber jar declara dependencias transitivas, si lo incluye como dependencia en un proyecto externo entonces Maven intentará obtenerlos (incluso si ya están incluidos en el tarro de uber).

Comparto una solución que le permite evitar excluir explícitamente todas las dependencias transitivas, incluyéndola en un proyecto externo como lo explica @A_DiMatteo en su solución (también estoy de acuerdo con él sobre evitar usar uber jar como dependencia si no es estrictamente necesario hacerlo por alguna razón). Como resultado, debería poder incluir su dependencia de uber jar sin uso exclusiones elemento de la siguiente manera:

<dependency>
  <groupId>com.sample</groupId>
  <artifactId>something-uber</artifactId>
  <version>some-version</version>
</dependency>

Premisa: mi objetivo era proporcionar tanto uber (sin dependencia transitiva declarada en pom) y delgada jarras en mi repositorio. Entonces, mi solución “A” se basa en este escenario y actualmente tiene el límite de que el frasco sombreado se cargue 2 veces en el repositorio.

  • Para proporcionar solo el uber jar ver la solución “B” a continuación
  • Para una posible solución para el límite “A”, consulte el ACTUALIZAR sección al final

A) Proporcione frascos finos y uber en el repositorio

1- En tu proyecto fuente configurar en su alguna cosa módulo pom.xml lo siguiente complemento de sombra de maven de la siguiente manera:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.2</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <finalName>something-uber-${project.version}</finalName>
      </configuration>
    </execution>
  </executions>
</plugin>

Entonces usa el build-helper-maven-plugin complemento para adjuntar el nuevo artefacto con el clasificador “uber” en el módulo:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.2</version>
  <executions>
    <execution>
      <id>attach-artifacts</id>
      <phase>package</phase>
      <goals>
        <goal>attach-artifact</goal>
      </goals>
      <configuration>
        <artifacts>
          <artifact>
            <file>
              ${project.build.directory}/something-uber-${project.version}.jar
            </file>
            <classifier>uber</classifier>
          </artifact>
        </artifacts>
      </configuration>
    </execution>
  </executions>
</plugin>

Esto generará como resultado de la fase de instalación de maven los siguientes dos frascos en objetivo/ directorio:

40K something-0.1.0.jar
7M  something-uber-0.1.0.jar

ADVERTIR: Ejecutando luego la fase de implementación de maven ¡Ambos frascos se cargarán en el repositorio! El objetivo aquí debería ser cargar solo el tarro fino omitiendo el despliegue para tarro sombreado para dejarlo como un artefacto local (Ver el ACTUALIZAR sección al final para una posible solución)

2- Crea luego otro módulo en tu proyecto fuente llamado algo-súper agregando las siguientes dependencias y complementos:

<dependencies>
    <dependency>
        <groupId>com.sample</groupId>
        <artifactId>something</artifactId>
        <version>${project.version}</version>
        <classifier>uber</classifier>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.2</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Tenga en cuenta lo siguiente sobre la inclusión de la dependencia:

  • el clasificador debe ser igual a uber (el que ha especificado adjuntando un nuevo artefacto usando build-helper-maven-plugin en el primer módulo)
  • los exclusiones se especifican.

Al ejecutar al final de la fase de implementación de maven en este módulo, el jar sombreado se cargará en el repositorio y podremos agregarlo como dependencia en un proyecto externo de la siguiente manera:

<dependency>
 <groupId>com.sample</groupId>
 <artifactId>something-uber</artifactId>
 <version>0.1.0</version>
</dependency>

B) Proporcione solo uber jar en el repositorio

A partir de la solución “A” si desea evitar proporcionar el tarro fino en el repositorio debe evitar en el punto 1 para especificar finalName en la configuración del plugin de sombra de maven y así evitar también el build-helper-maven-plugin plugin ya que no hay un nuevo artefacto para adjuntar. Al hacer esto, al implementar el módulo, solo tendrá el uber jar en el objetivo / como predeterminado (sin clasificador):

7M  something-0.1.0.jar

También debe omitir la carga, de lo contrario, también tendrá aquí dos frascos gordos cargados ( algo-0.1.0.jar Y algo-uber-0.1.0.jar ). Para hacer esto, agregue el siguiente complemento en el mismo módulo:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-deploy-plugin</artifactId>
    <version>2.8.2</version>
    <configuration>
        <skip>true</skip>
    </configuration>
</plugin>

Al final del punto 2, evite especificar el clasificador al agregar la dependencia de la siguiente manera:

<dependencies>
 <dependency>
    <groupId>com.sample</groupId>
    <artifactId>something</artifactId>
    <version>${project.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>*</artifactId>
            <groupId>*</groupId>
        </exclusion>
    </exclusions>
 </dependency>
</dependencies>

ACTUALIZACIÓN: omita la primera carga de jar sombreado en la solución A)

Después de buscar una solución durante un tiempo sin éxito, decidí bifurcar el maven-deploy-plugin plugin de GitHub y trabajar para una nueva función para omitir el jar sombreado creado en el primer módulo agregando el complemento configurado de la siguiente manera:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-deploy-plugin</artifactId>
  <version>3.0.0-SNAPSHOT</version>
  <configuration>
    <skipAttachedArtifacts>
      <artifact>
        <groupId>com.sample</groupId>
        <artifactId>something</artifactId>
        <version>${project.version}</version>
        <packaging>jar</packaging>
        <classifier>uber</classifier>
      </artifact>
    </skipAttachedArtifacts>
  </configuration>
</plugin>

Actualmente usando el maven-deploy-plugin plugin todos los artefactos están excluidos de la implementación, mientras que el objetivo aquí es excluir solo uno específico. En mi bifurcación, introduje el parámetro de configuración “skipAttachedArtifacts” para especificar los artefactos adjuntos para excluirlos de la implementación.

Aquí está el enlace de mi proyecto bifurcado en GitHub: https://github.com/gregorycallea/maven-deploy-plugin

Aquí el enlace en su lugar a la solicitud de extracción que envié en el proyecto de complemento de apache: https://github.com/apache/maven-deploy-plugin/pull/3

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *