Использование сторонней зависимости в пакете Maven OSGi

Почувствовав, что я понял, как используется OSGi, я попытался добавить стороннюю зависимость, в частности log4j2, в свое приложение, использующее apache felix и связанное с плагином maven-bundle-plugin. К сожалению, мне кажется, что я застрял в аду зависимости.

Я пробовал использовать многочисленные тактики maven-bundle, такие как Import-Package, Embed-Dependency, wrapImportPackage, Embed-Transitive, и устанавливать конкретные номера версий, чтобы назвать несколько. Вот как выглядит мой pom для этого плагина:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
    <artifactId>ParentId</artifactId>
    <groupId>ParentGroupId</groupId>
    <version>x.x.x</version>
</parent>

<groupId>ParentGroupId.ParentId</groupId>
<artifactId>thisModule</artifactId>
<packaging>bundle</packaging>

<name>thisModule</name>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>org.osgi.core</artifactId>
        <version>6.0.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>AM</artifactId>
        <version>${project.version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.12.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.12.1</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>3.5.1</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>${project.name}</Bundle-SymbolicName>
                    <Bundle-Activator>moduleActivator</Bundle-Activator>
                    <Embed-Dependency>
                        AM,
                        gson,
                        log4j-api,
                        log4j-core
                    </Embed-Dependency>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
    <finalName>${project.artifactId}</finalName>
</build>

Наибольший прогресс, который, как мне кажется, у меня был, связан с вышеупомянутым pom, где я встраиваю api и ядро ​​log4j непосредственно в пакет, но кажется, что OSGi не может загрузить и связать зависимости компиляции, которые api и ядро ​​log4j зависят от. Он успешно создается с использованием maven, но затем, когда я развертываю EAR и JAR, я получаю эту ошибку во время выполнения (когда плагин пытается загрузиться):

Caused By: org.osgi.framework.BundleException: Unresolved constraint in bundle thisModule [2]: Unable to resolve 2.0: missing requirement [2.0] package; (package=com.conversantmedia.util.concurrent)

ошибка, в которой будет указана конкретная зависимость, которая нужна log4j. Чего я НЕ хочу делать, так это включать каждую зависимость и их мать в тег Embed-Dependency.

Что я здесь делаю не так?

Также обратите внимание: из-за ограничений мой единственный вариант - использовать apache felix и OSGi.


Ниже приведены другие примеры модификаций, которые я внес в вышеуказанный POM, и их результаты:

  • Удаление log4j-api и log4j-core из Embed-Dependency и добавление тега <wrapImportPackage>;</wrapImportPackage>. Это привело к следующему выводу, который чрезвычайно распространен и случается всякий раз, когда я пытаюсь импортировать:

Caused By: org.osgi.framework.BundleException: Unresolved constraint in bundle thisModule [2]: Unable to resolve 2.0: missing requirement [2.0] package; (&(package=org.apache.logging.log4j)(version>=2.12.0)(!(version>=3.0.0)))

  • Добавление * к Embed-Dependency, а также добавление <Embed-Transitive>true</Embed-Transitive>:

Caused By: org.osgi.framework.BundleException: Unresolved constraint in bundle thisModule [2]: Unable to resolve 2.0: missing requirement [2.0] package; (package=android.dalvik)


person cjnash    schedule 15.11.2019    source источник


Ответы (1)


Встраивание библиотеки журналов - плохая идея. В конце концов, вы хотите настроить ведение журнала в центральном месте, что очень сложно, когда каждый пакет включает в себя структуру ведения журнала.

В большинстве случаев безопасная ставка - просто оставить конфигурацию maven-bundle-plugin пустой и позволить ему делать свое дело.

Лично я всегда использую slf4j для входа в OSGi. Вы просто зависите от slf4j-api. Maven-bundle-plugin автоматически создает операторы пакета импорта.

Затем во время выполнения вы просто развертываете платформу ведения журнала, которая поддерживает требуемый API ведения журнала.

Для apache karaf это уже по умолчанию. Если вы используете bndtools или собственную сборку приложения на основе простого felix, ознакомьтесь с моим примером лучших практик osgi < / а>. В нем показано, как использовать slf4j-api в ваших собственных пакетах, а также как настроить систему журналов в приложениях на основе karaf и bndtools.

person Christian Schneider    schedule 16.11.2019
comment
Я понимаю, что вы говорите о встраивании библиотек и почему это не имеет смысла. Однако, когда вы упоминаете развертывание фреймворка ведения журнала во время выполнения, говорите ли вы о создании пакета log4j2, который содержит конфигурацию и экспортирует ее содержимое? Тогда фреймворк log4j2 использует api slf4j для регистрации, не ограничиваясь только этим пакетом? Кроме того, спасибо за размещение своих лучших практик OSGi. К сожалению, apche karaf на данный момент мне не подходит, но все же было полезно просмотреть ваши примеры. - person cjnash; 18.11.2019
comment
В моем примере я использую логбэк в качестве фреймворка для логирования при работе вне karaf. См .: github.com/cschneider/osgi-best- практики / blob / master / app /. Здесь вы видите наборы и свойства фреймворка, которые нужно установить. То же самое можно сделать и с простым Феликсом. - person Christian Schneider; 18.11.2019