Использование maven-bundle-plugin с плагином maven-shade

Я использую плагин maven-shade для переноса некоторых пакетов во время фазы пакета моей сборки. Я также использую maven-bundle-plugin для создания манифеста. Проблема заключается в том, что плагин bundle запускается перед плагином тени (во время фазы процессов) и не включает какие-либо из моих заштрихованных пакетов в сгенерированном экспорте манифеста.

Как я могу заставить эти два плагина хорошо играть друг с другом, чтобы мои перемещенные пакеты обрабатывались как любой другой пакет плагином bundle?

-

По запросу секции Shade и bundle моего POM:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <filters>
        <filter>
          <artifact>cglib:cglib</artifact>
          <includes>
            <include>net/sf/cglib/core/**</include>
            <include>net/sf/cglib/proxy/**</include>
          </includes>
        </filter>
      </filters>
      <relocations>
        <relocation>
          <pattern>net.sf.cglib</pattern>
          <shadedPattern>org.modelmapper.internal.cglib</shadedPattern>
        </relocation>
        <relocation>
          <pattern>org.objectweb.asm</pattern>
          <shadedPattern>org.modelmapper.internal.asm</shadedPattern>
        </relocation>
      </relocations>
    </configuration>
  </plugin>

  <plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>2.3.7</version>
    <executions>
      <execution>
        <id>bundle-manifest</id>
        <phase>process-classes</phase>
        <goals>
          <goal>manifest</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <instructions>
        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
        <Export-Package>
          org.modelmapper,
          org.modelmapper.builder,
          org.modelmapper.config,
          org.modelmapper.convention,
          org.modelmapper.spi
        </Export-Package>
        <Private-Package>
          org.modelmapper.internal.**
        </Private-Package>
        <Import-Package>
          *
        </Import-Package>
        <Include-Resource>
          {maven-resources},
          {maven-dependencies}
        </Include-Resource>
      </instructions>
    </configuration>
  </plugin>

Взято отсюда

Ответ 1

Другой вариант - полностью скомпилировать плагин maven bundle и использовать Maven Shade Plugin ManifestResourceTransformer, чтобы добавить в манифест желаемые метаданные OSGI.

Посмотрите xbean-asm-shaded/pom.xml для примера.

<transformers>
  <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
    <manifestEntries>
      <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
      <Export-Package>
        org.apache.xbean.asm;org.modelmapper.builder; ...
      </Export-Package>
      <Import-Package>*</Import-Package>
      <Private-Package>org.modelmapper.internal ...</Private-Package>
   </manifestEntries>
</transformer>

Ответ 2

Я предполагаю, что после фазы compile вы хотите:

  • Переместите некоторые классы с плагином тени.
  • создать манифест с плагином bundle
  • упакуйте все с помощью плагина jar

Проблема заключается в том, что плагин bundle запускается перед плагином тени

Плагин bundle привязан к фазе process-classes, которая приходит перед фазой package, к которой привязан плагин.

Я предлагаю вам привязать плагин для тени к фазе process-classes. Измените конфигурацию плагина тени следующим образом:

<phase>process-classes</phase>

Так как определение плагина тени происходит до определения плагина пакета в файле pom, плагин тени будет работать до плагина пакета во время фазы process-classes.

Ответ 3

Решение очень простое. Вы все равно можете использовать maven-bundle-plugin и maven-shade-plugin одновременно. Вам просто нужно запомнить о заказе. Если вы используете пакетную упаковку, плагин maven bundle будет выполняться во время фазы пакета до maven-shade. Но это не так.

Вот сделка.

  • Использовать Private-Package: pkg.name.before.shading
  • Сделать maven-shade-plugin с одним <include> null: null </include> - это предотвратит создание плагином теневого плагина
  • использовать maven-shade-plugin relocations - от pkg.name.before.shading до other.pkg.

Вы можете увидеть этот трюк, работающий в FasterXML jackson-module-paranamer

Ответ 4

Существует аккуратная transformer реализация этой функции только из Hazelcast - HazelcastManifestTransformer (версия 3.9). То, что он делает, задумчиво объединяет атрибуты Import-Package и Export-Package, позволяя пользователю исключать возможность расширения/уменьшения объединенного результата по умолчанию.

Как использовать его в pom.xml:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.1.0</version>
  <dependencies>
    <dependency>
      <groupId>com.hazelcast</groupId>
      <artifactId>hazelcast-build-utils</artifactId>
      <version>3.9</version>
    </dependency>
  </dependencies>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <transformers>
          <transformer implementation="com.hazelcast.buildutils.HazelcastManifestTransformer">
            <mainClass>...</mainClass>
            <!-- the tag below is required due to a missing null-check it seems -->
            <overrideInstructions></overrideInstructions>
      </configuration>
    </executions>
</plugin>

Команды переопределения (Export/Import-Package) представляют собой имена пакетов с разделителями-запятыми, которым предшествует восклицательный знак всякий раз, когда мы хотим исключить из списка те из них.

Надеюсь, это поможет! Я понимаю, что старый вопрос, но, похоже, трансформатор Hazelcast не получает широкой рекламы.