如何在OSGI环境中避免MyBatis的类加载问题?

时间:2013-10-02 15:19:26

标签: java eclipse osgi mybatis

我正在开发一个基于Eclipse 3.7 RCP的应用程序,它有多个模块。模块A是一堆库,包括mybatis-3.2.2.jar。模块B依赖于模块A(manifest.mf中的Require-Bundle),并且具有使用MyBatis访问数据库中数据的代码。我已经在模块B中导出了带有映射器类和XML的包,并将它们导入到模块A中。我在代码中构建了SqlSessionFactory,如果我按名称添加所有Mapper类,它可以正常工作,例如

configuration.addMapper(MyMapper.class);

然而,当我尝试在包中添加所有Mappers时:

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

MyBatis没有看到它们。

我尝试更改默认的类加载器,但这没有帮助。

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

我怀疑这个问题与OSGI环境中类的可见性有关。如果是这种情况,有没有办法在应用程序中修复它?

3 个答案:

答案 0 :(得分:2)

你试过吗

Resources.setDefaultClassLoader(Activator.class.getClassLoader())。我认为这将使用OSGi类加载器。希望这会有所帮助。

答案 1 :(得分:1)

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

但同样适用。

答案 2 :(得分:1)

我在Felix OSGi环境中遇到了与Spring Data JPA类似的问题。在这种情况下,我能够覆盖工厂类并将其添加到违规方法中:

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

在这种情况下" context"是一个Spring上下文,但你应该能够从BundleWiring获得Module B的类加载器。

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类的方法,否则你无法做到这一点。