前提知识:JPA,是J2EE的一个规范,JVM提供了接口,Hibernater等ORM框架提供了具体的实现,这个类似于JDBC和JMS的情况。在JBPM5中使用Hibernate作为持久JPA的实现。JPA有两个重要的配置文件:persistence.xml和orm.xml文件,这个两个文件放在某个jar包的META-INF文件夹下。其中关于和Hibernate的配置文件都写在persistence.xml文件中。orm.xml文件中可以写很多查询语句,以一个字符串命名,JPA框架可以根据这个名字拿到HQL语句,然后完成相应的查询,这个类似于IBatis框架。
解决问题环境:JBPM5、Felix1.4.1、Bundel打包的思路,参照我的一篇博文:http://blog.csdn.net/achilles12345/article/details/7163122
1、No Persistence provider for EntityManager named org.jbpm.task
在Persistence这个类中,有这样一句话:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Enumeration<URL> resources =
loader.getResources("META-INF/services/" + PersistenceProvider.class.getName());
很显然程序要寻找的位置是所有资源的META-INF/services/PersistenceProvicer这个文件,经过分析报错就是因为这个文件找不到。在Felix环境下当前的现成上下文类加载器是当前应用的类加载器,也就是说是Felix自己环境运行的类加载器。而我们要找的这个文件是在我们自己JBPM5服务端的实现了JPA的Hibernater的hibernate-entitymanager-3.4.0.GA.jar包中,我们这个jar包的类加载器是:org.apache.felix.framework.BundleWiringImpl类型的对象,和Felix的类加载器不是同一个,因此,只要我们将线程上下文类加载器替换成我们自己jar包的类加载器就行了。
2、、Named query not found: UnescalatedDeadlines错误的分析和解决:
通过从报错出进入源码,从bug处为出发点,反向跟踪和从业务代码中开始正向跟踪,发现是因为UnescalatedDeadlines这个查询语句找不到,这个语句应该是在orm.xml中的。而这个查询语句来自于Configuration这个对象,这个对象又是解析persistence.xml文件的 <mapping-file>节点得到orm.xml文件的没有配置。将orm.xml文件放在和persistence.xml文件同目录的位置,问题就解决了。
其实还有很多问题,但是都和这个类加载器多少有关系,这个思路突破后,其他的问题基本上都是迎刃而解。
总结:OSGI不同平台的类加载器机制都不太相同,类加载器的问题是我们解决所有OSGI问题首先要排除的核心问题。
现在说的时候很简单,但是真正追踪这个问题是很复杂的一个过程。在调试问题时,要注意以下几点:
1)首先从报错的地方找起,先确定是什么问题引起的这个错误,然后追这个错误,一直到其源头。
2)每次调试一定要问清楚这次追踪的目的是什么,要得出的结论是什么。
3)调试的时候应该是反向追踪和正向追踪配合使用。
4)大胆设想,但是一定是要有根据地设想,不要胡思乱想。
5)只要有源码,就大胆去调试,直到追到问题的发出点,如果越不过这个心理障碍,永远搞不清问题。
先总结这点东西吧,如果遇到问题可以和我本人交流。