【发布时间】:2018-05-31 14:51:24
【问题描述】:
我是 OSGi 环境的新手,也许我错过了一些东西。我无法加载包含在 OSGI 包中的 JPA 实体 (ClassNotFoundException)。
我正在使用 Apache Felix 和 Hibernate。我没有使用蓝图。
这是我的架构:
应用 A:通用接口。没什么好说的。
应用程序 B:是一个 WebApp。它在启动主机包的启动时启动 felix 框架。主机主机包安装包含在特定文件夹中的所有包的 jar 并跟踪服务(在应用程序 C 中实现的服务)。它具有应用程序 A 作为依赖项。
应用程序 C:它是客户端捆绑包。它实现 Application A 接口并注册它(它具有 App A 作为依赖项)。它还包含我在这个包中需要的所有 JPA 模型。
我遇到的问题在于应用程序 C 实现:它配置运行时 org.hibernate.cfg.Configuration 并加载自己的 JPA 模型(cfg.addAnnotatedClass(EntityTest.class))。 此时我得到了这个异常:
org.hibernate.AssertionFailure: PersistentClass 名称不能 转换成一个类 在 org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId(BinderHelper.java:877) 在 org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2179) 在 org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:925) ...
那是因为
原因:org.hibernate.annotations.common.reflection.ClassLoadingException:无法加载类 [com.osgi.bundle1.model.EntityTest] 在 org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:60) 在 org.hibernate.boot.internal.MetadataBuilderImpl$MetadataBuildingOptionsImpl$4.classForName(MetadataBuilderImpl.java:758) 在 org.hibernate.annotations.common.reflection.java.JavaReflectionManager.classForName(JavaReflectionManager.java:144) 在 org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId(BinderHelper.java:874) ...省略了58个常用框架 引起:java.lang.ClassNotFoundException:com.osgi.bundle1.model.EntityTest 在 org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1333) 在 org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167) 在 java.lang.Class.forName0(本机方法) 在 java.lang.Class.forName(Class.java:348) 在 org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:57) ...省略了61个常用框架
应用程序 C 已经导出模型,我使用了https://docs.gradle.org/current/userguide/osgi_plugin.html。
编辑:添加了更多细节。
应用程序 B 是使用 Jersey 构建的 web 应用程序。它有一个启动 felix 的 ServletContextListener:
@WebListener
public class Felixbootstrap implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
OsgiHost.initialize();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
public class OsgiHost {
public static void initialize() {
OsgiHost host = new OsgiHost();
host.start();
}
private void start() {
Map<String, Object> config = new HashMap<>();
config.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, Arrays.asList(
, new HostBundle()//Activator that starts bundles of the project
));
config.put(FelixConstants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
//package to export
String felixPackageExportConfiguration =
//common api
"com.osgi.test.api"
+ ",com.osgi.test.dto"
//hibernate
+ ",javax.persistence;version=2.1.0"
+ ",org.hibernate"
+ ",org.hibernate.cfg"
+ ",javassist.util.proxy"
+ ",org.hibernate.proxy"
+ ",org.hibernate.query"
;
config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, felixPackageExportConfiguration);
Felix felix = new Felix(config);
try {
felix.start();
} catch (BundleException e) {
e.printStackTrace();
}
}
}
应用程序 C 有一个由应用程序 B 上的端点调用的方法(通过公共接口)。当它被调用时,这个类被初始化(总是在应用程序 C 中):
public class HibernateUtil {
private SessionFactory sf;
private static HibernateUtil instance = null;
public static HibernateUtil getInstance() {
if (instance == null) {
instance = new HibernateUtil();
}
return instance;
}
private HibernateUtil() {
}
public Session getSession() {
return getSessionFactory().openSession();
}
private SessionFactory getSessionFactory() {
if (sf == null) {
Configuration cfg = new Configuration();
cfg.addAnnotatedClass(EntityTest.class);
cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL94Dialect")
.setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/jdbcname")
.setProperty("hibernate.ejb.naming_strategy", "org.hibernate.cfg.DefaultNamingStrategy")
.setProperty("hibernate.archive.autodetection", "class")
.setProperty("hibernate.hbm2ddl.auto", "update")
;
sf = cfg.buildSessionFactory();
}
return sf;
}
}
【问题讨论】:
-
我有一个小的 working example(在 Karaf 和 OpenJPA 上),但问题看起来非常相似,恕我直言,您应该尝试将实体类作为片段注入 Hibernate 包主机以被识别/找到
标签: hibernate jpa osgi apache-felix