OSGi中Envers的Classloader问题 [英] Classloader Issues with Envers in OSGi

查看:102
本文介绍了OSGi中Envers的Classloader问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在OSGi上下文中成功启动了Hibernate,现在我想添加Envers.

I've successfully started Hibernate in an OSGi context, and now I want to add Envers.

文档声称这是可能的.我不相信了没有关于该主题的任何文档,而且似乎没有人真正完成过.而且,即使使用了Blueprint实现,我也不得不破解类加载器,以使Hibernate甚至找到Envers:

The documentation claims that's possible. I don't believe it anymore. There is no documentation of any kind for this subject and nobody seems to have actually done it. Moreover even with a Blueprint implementation I had to hack the classloader to make Hibernate even find Envers:

osgiClassLoader = new org.hibernate.osgi.OsgiClassLoader();
osgiClassLoader.addBundle(requestingBundle);
osgiClassLoader.addBundle(FrameworkUtil.getBundle(SessionFactory.class));
osgiClassLoader.addBundle(FrameworkUtil.getBundle(HibernateEntityManagerFactory.class));
osgiClassLoader.addBundle(FrameworkUtil.getBundle(EnversService.class));

Thread.currentThread().setContextClassLoader(osgiClassLoader);

((我觉得我应该问:"OSGi中的Envers可能吗?")因此,如果您对这个问题有明确的答案,请告诉我.我花了太多时间在这些问题.)

但是,实际的问题与Hibernate/Envers和OSGi无关.两者都想访问所使用的实体和枚举.尽管如此,还是有了反思.当然不能.当然,我不能添加导入包.

However the actual problem has nothing to do with Hibernate / Envers and all with OSGi. Both want to access the entities and enums used. With reflection nonetheless. Of course they can't. And of course I can't add Import-Packages.

相关的堆栈跟踪如下所示:

The relevant stack trace looks something like this:

Caused by: java.lang.ClassNotFoundException: org.acme.project.MyEnum cannot be found by org.hibernate.core_5.1.0.Final
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:461)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364)
    at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.hibernate.internal.util.ReflectHelper.classForName(ReflectHelper.java:151)
    at org.hibernate.type.EnumType.setParameterValues(EnumType.java:105)
    ... 62 more

通常,在与OSGi无关的框架中,我只会向 MANIFEST.MF 中添加类似的内容:

Normally with OSGi-agnostic frameworks I'd just add something like this to the MANIFEST.MF:

// to org.hibernate.core
Eclipse-BuddyPolicy: registered
// to org.acme.project
Eclipse-RegisterBuddy: org.hibernate.core

但是我无法在Hibernate的清单中添加任何内容.我尝试通过片段来添加行,但是那也不起作用.

However I can't add anything to Hibernate's manifest. I tried contributing the line via fragment, but that did not work either.

我什至尝试将整个Hibernate依赖项作为JAR添加到插件中以添加上述内容.这行不通.

I even tried adding the entire Hibernate dependencies as JAR into a plug-in to add the above. It won't work.

如何解决这些类加载器问题?

How to resolve these classloader issues?

推荐答案

如果您的@Audited类引用了枚举,则org.hibernate.core需要导入类包.最好的方法是注册一个片段束.

If your @Audited class references an Enum, org.hibernate.core needs to import the classes package. The best way to do this is to register a fragment bundle.

此外,确保休眠捆绑包的起始级别低于实体捆绑包的启动级别也是明智的选择.

Also, it is wise to make sure your start level for hibernate bundles is lower than the start levels for entity bundles.

这是示例Gradle脚本中的片段,用于创建片段包.确保将org.hibernate.core捆绑软件版本更改为正在使用的捆绑软件版本,并将"your.package"更新为包含您的Enum的版本.

Here is a snippet from a sample Gradle script to create a fragment bundle. Make sure your change the org.hibernate.core bundle version to the one you are using, and also update the 'your.package' to the one that contains your Enum.

/*
When using Envers, entities that reference Enum classes must be imported (Import-Package) by the org.hibernate.core bundle.
 */

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'biz.aQute.bnd:biz.aQute.bnd.gradle:3.2.0'
    }
}

apply plugin: 'biz.aQute.bnd.builder'

jar {
    manifest {
        attributes(
                'Fragment-Host': 'org.hibernate.core;' + 'bundle-version=' + '5.2.9.Final',
                'Import-Package': 'your.package'
        )
    }
}

这篇关于OSGi中Envers的Classloader问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆