2013-11-01 5 views
0

У меня есть некоторые проблемы с использованием Джексон 2.1 в среде OSGi, когда десериализации класса, который так:Джексон десериализации пользовательских классов в среде OSGi

ObjectMapper mapper = new ObjectMapper(); 
User user = mapper.readValue(new File("user.json"), User.class); 

class User { 
    public Class clazz = org.example.MyClass.class; 
} 

Потому что Джексон находится в другой связке как мои пользовательские классы я хочу для десериализации я часто получаю java.lang.ClassNotFoundException - обычно на MyClass1 или MyClass2.

Я проследил его до класса com.fasterxml.jackson.databind.util.ClassUtil, который использует Class.forName(..) для извлечения класса для десериализации. Из-за разных классов-загрузчиков OSGI он видит только классы JRE и Jackson, но не мои пользовательские классы.

Есть ли простой способ заставить Джексон найти все необходимые пользовательские классы (у меня их десятки), например, добавив класс-загрузчик?

+0

Вы экспортируете пакет, в котором находится ваш класс? –

+0

Да, пакет экспортируется, но это не имеет значения, поскольку пакет Jackson не импортирует его ... – Robert

ответ

2

Как клиент Джексона у вас есть видимость классов, в которые вы хотите десериализовать. Хитрость состоит в том, чтобы передать эти классы в Джексон, а не заставить Джексона использовать динамическое отражение, чтобы найти классы.

Jackson documentation указывает, что метод ObjectMapper.readValue может принимать объект Class в качестве его параметра. Если вы используете этот метод, то Джексону не нужно звонить Class.forName(). Документы привести следующий пример:

ObjectMapper mapper = new ObjectMapper(); 
User user = mapper.readValue(new File("user.json"), User.class); 

Здесь User является доменным классом, который является видимым для клиента, но не Джексон. Этот вызов должен отлично работать в OSGi ... если он не, тогда я бы предложил, что у Джексона может быть ошибка.

+0

Спасибо за предложение, но я уже использую этот вариант, поскольку он является стандартом десериализации JSON в экземпляр класса. В моем случае User.class имеет несколько полей, используя другие собственные классы - как я уже писал, у меня их десятки. Для других классов Джексон всегда использует динамическое отражение :( – Robert

+0

Тогда кажется, что это должно быть сообщено как ошибка в Джексоне. Для них абсолютно нет необходимости прибегать к загрузке классов по имени. Все необходимые классы доступны из отражения с использованием «корневого» класса, который вы десериализируете. –

+0

Однако, как временное обходное решение, вы можете использовать загрузчик классов типа Thread. Попробуйте установить загрузчик контекста на значение 'this.getClass(). getClassLoader()' , где 'this' - ваш клиентский объект. –

Смежные вопросы