Как избежать проблем с загрузкой классов с MyBatis в среде OSGI?

Я работаю над Eclipse 3.7 RCP-приложением с несколькими модулями. Модуль A представляет собой набор библиотек, включая mybatis-3.2.2.jar. Модуль B зависит от модуля A (Require-Bundle в manifest.mf) и имеет код, который использует MyBatis для доступа к данным в базе данных. Я экспортировал пакеты с классами Mapper и XML в модуле B и импортировал их в модуль A. Я создаю SqlSessionFactory в коде, и он работает нормально, если я добавляю все классы Mapper по имени, например

configuration.addMapper(MyMapper.class);

Однако, когда я пытаюсь добавить все Mappers в пакет:

configuration.addMappers(MyMapper.class.getPackage().getName());

MyBatis их не видит.

Я попытался изменить загрузчик классов по умолчанию, но это не помогло.

Resources.setDefaultClassLoader(this.getClass().getClassLoader());

Я подозреваю, что проблема связана с видимостью классов в среде OSGI. Если это так, есть ли способы исправить это в приложении?

3 ответа

Ты пытался

Resources.setDefaultClassLoader(Activator.class.getClassLoader()), Я думаю, что будет использовать загрузчик класса OSGi для пакета. Надеюсь, это поможет.

Я столкнулся с подобной проблемой в Spring Data JPA в среде Felix OSGi. В этом случае я смог переопределить класс фабрики и добавить это в методы-нарушители:

ClassLoader pre = Thread.currentThread().getContextClassLoader();
try {
    Thread.currentThread().setContextClassLoader(context.getClassLoader());
    // add mappers here or call super method
} finally {
    Thread.currentThread().setContextClassLoader(pre);
}

В этом случае "контекст" был контекстом Spring, но вы должны иметь возможность получить загрузчик классов модуля B из BundleWiring.

Bundle bundle; //get this by symbolic name if you don't have a reference
BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
bundleWiring.getClassLoader();

Надеемся, что метод addMappers не нуждается в доступе к загрузчику классов модуля A в одном вызове. Если это так, то вы не сможете сделать ничего, если не найдёте способ расширить и внедрить другой класс Configuration или MapperRegistry.

configuration.addMappers использует собственный ResolverUtil, который использует загрузчик класса контекста Thread. (По крайней мере, в mybatis3).

Лучше всего было бы написать свой собственный код сканирования и напрямую использовать addMapper. Ниже приведены мои ссылки и примеры:

http://grepcode.com/file/repo1.maven.org/maven2/org.mybatis/mybatis/3.1.1/org/apache/ibatis/session/Configuration.java?av=f#518

http://grepcode.com/file/repo1.maven.org/maven2/org.mybatis/mybatis/3.1.1/org/apache/ibatis/io/ResolverUtil.java#148

РЕДАКТИРОВАТЬ: Вот некоторые для mybatis 3.2.2

http://grepcode.com/file/repo1.maven.org/maven2/org.mybatis/mybatis/3.2.2/org/apache/ibatis/io/ResolverUtil.java#147

http://grepcode.com/file/repo1.maven.org/maven2/org.mybatis/mybatis/3.2.2/org/apache/ibatis/binding/MapperRegistry.java#86

То же самое относится, однако.

Другие вопросы по тегам