Импортированные аннотации Джексона, игнорируемые для POJO в зависимости OSGi во время выполнения - PullRequest
0 голосов
/ 12 июня 2018

Сводка

Аннотации Джексона, примененные к POJO, экспортируемым через зависимость OSGi, не работают, когда POJO сериализуется в импортирующем пакете во время выполнения.Если POJO помещается в комплект использования напрямую или тестируется в модульном тесте (в любом комплекте), все работает как положено.

Кто-нибудь знает, что может заставить игнорировать сериализацию во время выполненияаннотации Джексона во время выполнения в импортирующем OSGi-пакете?


Это очень сложный вопрос.Я попытался создать как можно более простой пример.Если что-то неясно, пожалуйста, дайте мне знать, и я постараюсь уточнить.

Содержание

  • Внутри экспортаПакет

    • POJO
    • Модульный тест (который работает)
    • Испытание во время выполнения (который работает)
  • Внутренний импортный пакет

    • Модульный тест (который работает)
    • Испытание во время выполнения (что НЕ БУДЕТ)
  • Подробности среды выполнения

  • Манифесты пакетов (упрощенно)

Упрощенный пример:

Предположим, нам нужно сериализовать простой POJO, экспортированный и импортированный через OSGi.JSON-аннотации должны работать как в пакете импорта, так и в экспорте, как во время выполнения, так и во время модульных тестов (во время импорта происходит сбой во время выполнения).


Внутри пакета экспорта:

Обе среды выполненияи модульные тесты сериализации Джексона прекрасно работают в пакете, в котором объявлен сам POJO.

POJO для сериализации

В аннотации @JsonProperty должно быть любоеСерийная версия этого POJO выглядит примерно так: {"correctSerializedName":"someName"}, а не {"javaName":"someName"}:

package exporting.osgi.bundle.models;

import com.fasterxml.jackson.annotation.JsonProperty;

public class DependencyModel {

    private String javaName;

    @JsonProperty("correctSerializedName")
    public String getJavaName() {
        return javaName;
    }

    public DependencyModel(String javaName) {
        this.javaName = javaName;
    }
}

Правильное поведение: модульный тест

import com.fasterxml.jackson.*;
import org.junit.jupiter.*;

class ExportingBundleTests {

    @Test
    void serialize_inDepdendencyProject_getsCorrectJsonName() {
        DependencyModel dependencyModel = new DependencyModel("name");

        ObjectMapper mapper = new ObjectMapper();
        String jsonString = mapper.writeValueAsString(dependencyModel);

        // Asserts True -> serialization works as expected
        assertEquals(jsonString, "{\"correctSerializedName\":\"name\"}");
    }    
}

Правильноповедение: время выполнения

public void runtimeFromDepdendency() {
    DependencyModel dependencyModel = new DependencyModel("name");

    ObjectMapper mapper = new ObjectMapper();
    String jsonString = mapper.writeValueAsString(dependencyModel);

    // jsonString = {"correctSerializedName":"name"}
}

внутри импортирующего пакета OSGi

правильное поведение: модульный тест

import exporting.osgi.bundle.models.DependencyModel;
import com.fasterxml.jackson.*;
import org.junit.jupiter.api.*;

class ImportingBundleTests {

    @Test
    void serialize_inUsingProject_getsCorrectJsonName() {

        DependencyModel dependencyModel = new DependencyModel("name");

        ObjectMapper mapper = new ObjectMapper();
        String jsonString = mapper.writeValueAsString(dependencyModel);

        // Asserts True -> serialization works as expected
        assertEquals(jsonString, "{\"correctSerializedName\":\"name\"}");
    }
}

FAILS: Runtime

import exporting.osgi.bundle.models.DependencyModel;
import com.fasterxml.jackson.*;

public Response runsFromUsingProject() throws JsonProcessingException {
    DependencyModel dependencyModel = new DependencyModel("name");

    ObjectMapper mapper = new ObjectMapper();
    String jsonString = mapper.writeValueAsString(dependencyModel);

    // jsonString = {"javaName":"name"}   <---- WHICH IS WRONG
}

Runtime environment

  • Jira 7.2.2 OSGi (на основе Apache Felix)
  • Maven 3.2.1
  • Java 1.8
  • Джексон 2.9.3

Экспорт плагина Bundle Manifest(упрощенно)

Created-By: Apache Maven Bundle Plugin
Manifest-Version: 1.0
Build-Jdk: 1.8.0_111
Bundle-ManifestVersion: 2

Export-Package:
...
exporting.osgi.bundle;version="1.0.0";
    uses:="exporting.osgi.bundle.models",
...

Originally-Created-By: Apache Maven Bundle Plugin
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Spring-Context: *
Tool: Bnd-2.4.1.201501161923

Импорт манифеста Bundle модуля (упрощенно)

Created-By: Apache Maven Bundle Plugin
Manifest-Version: 1.0
Build-Jdk: 1.8.0_111
Bundle-ManifestVersion: 2
Archiver-Version: Plexus Archiver
Bundle-ClassPath: .,META-INF/lib/gt-epsg-hsql-18.1.jar,META-INF/lib/sq
lite-jdbc-3.8.11.1.jar

Import-Package: 
...
exporting.osgi.bundle.models
...
com.fasterxml.jackson.dataformat.xml;resolution:=optional,
com.fasterxml.jackson.dataformat.xml.deser;resolution:=optional,
com.fasterxml.jackson.dataformat.xml.ser;resolution:=optional,
org.codehaus.jackson;resolution:=optional,
org.codehaus.jackson.annotate;resolution:=optional,
org.codehaus.jackson.map;resolution:=optional,
org.codehaus.jackson.map.annotate;resolution:=optional,
...

Originally-Created-By: Apache Maven Bundle Plugin
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Spring-Context: *
Tool: Bnd-2.4.1.201501161923

Как показано выше, аннотация @JsonProperty игнорируется во время выполнения вимпортирует зависимость , но все остальное работает как положено.Опять же, я не думаю, что это проблема версии Джексона, хотя я мог что-то упустить из виду.

Возможно, я пропустил какое-то фундаментальное поведение OSGi?

1 Ответ

0 голосов
/ 13 июня 2018

Исходя из моих комментариев и ваших отзывов:

Проблема в том, что ваши два пакета имеют разные экземпляры классов аннотаций Джексона.Когда среда Джексона сканирует классы на наличие аннотаций, она ищет конкретный экземпляр класса аннотаций, который она использует.Если у пакета есть собственный экземпляр того же класса, аннотация не будет распознана.(В OSGi каждый пакет имеет отдельный загрузчик классов, и каждый загрузчик классов может содержать собственный экземпляр данного класса.)

Это можно решить двумя способами:

  1. Разверните jackson2 как отдельные пакеты в вашем контейнере OSGi и убедитесь, что в вашем пакете импорта и экспорта есть Import-Package для соответствующих пакетов jackson.Самые центральные узлы: jackson-annotations, jackson-core и jackson-databind.В этом случае используйте область действия provided для зависимостей jackson2 в обоих ваших пакетах.
  2. Экспортируйте пакеты jackson2 из одного из ваших пакетов и импортируйте его в другой.Это даст вам дополнительную работу по выяснению и поддержке того, какие пакеты экспортировать.В этом случае используйте область действия compile для jackson2 в пакете экспорта и область действия provided в пакете импорта.
...