当我想将一种类型转换为另一种类型时,出现以下异常。
java.lang.ClassCastException: org.paston.certification.data.impl.BRL6000
cannot be cast to org.paston.certification.data.Certification
BRL6000 扩展了认证。因此,据我了解,我应该能够将 BRL6000 类型的对象转换为 Certification 类型。
这是发生异常的代码。
Object certification = ch.getCertificationData(process, version);
Certification c = (Certification)certification;
部署
该应用程序从 Eclipse 部署到 Tomcat 7 服务器。我的应用程序使用了 Tomcat 环境中的一些 JAR(例如 Bonita_Server.jar)。
我的应用程序(在 Eclipse 中)是一个动态 Web 项目,它引用了另一个项目(Certificationnl),其中包含类Certification
和BRL6000
. 当我将应用程序部署到 Tomcat 时,项目 Certificationnl 被添加到 webproject 的 WAR 中。
课程
BRL6000 等级
package org.paston.certification.data.impl;
import org.paston.certification.data.Certification;
import org.paston.certification.data.CertificationStep;
public class BRL6000 extends Certification{
/**
*
*/
public static final long serialVersionUID = -8215555386637513536L;
public static final String processName = "BRL6000";
}
认证等级
package org.paston.certification.data;
import java.util.ArrayList;
import java.util.List;
import org.ow2.bonita.facade.runtime.impl.AttachmentInstanceImpl;
public class Certification implements java.io.Serializable{
public enum Section{
ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN
}
/**
* SerializationVersionUID
*/
private static final long serialVersionUID = -5158236308772958478L;
}
获取认证数据
public Object getCertificationData(String process, String version) {
if (loginContext == null)
login();
System.out.println("Process: "+ process + " Version: "+ version);
ProcessDefinitionUUID pdu = new ProcessDefinitionUUID(process, version);
QueryRuntimeAPI queryRuntimeAPI = AccessorUtil
.getQueryRuntimeAPI();
try {
Set<ProcessInstance> processInstances = queryRuntimeAPI
.getProcessInstances(pdu);
if (processInstances.size() != 1)
System.out.println("Best number of instances is 1. Found: "
+ processInstances.size());
for (ProcessInstance processInstance : processInstances) {
Map<String, Object> variables = processInstance
.getLastKnownVariableValues();
if (((Boolean) variables.get("active")) == true) {
return variables.get("certification");
}
}
} catch (ProcessNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
将代码更新为 Servlet
package org.paston.certification.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.paston.certification.CertificationHandler;
import org.paston.certification.data.Certification;
import org.paston.certification.data.CertificationI;
/**
* Servlet implementation class SomeServlet
*/
public class SomeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public SomeServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
CertificationHandler ch = new CertificationHandler();
String process = request.getParameter("p");
String version = request.getParameter("v");
Object certification = ch.getCertificationData(process, version);
Class<?> clazz = certification.getClass();
while (clazz != null) {
System.out.println(clazz.getName());
clazz = clazz.getSuperclass();
}
Class c1 = certification.getClass().getSuperclass();
Class c2 = Certification.class;
System.out.println("c1 is " + c1 + ", c2 is " + c2);
System.out.println("c1 == c2 is " + (c1 == c2));
System.out.println("c1.equals(c2) is " + c1.equals(c2));
System.out.println("c1.getName().equals(c2.getName()) is "
+ c1.getName().equals(c2.getName()));
System.out.println("c1.getClassLoader() == c2.getClassLoader() is "
+ (c1.getClassLoader() == c2.getClassLoader()));
CertificationI c = (CertificationI) certification;
PrintWriter out = response.getWriter();
out.println("Hello World");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
Servlet 的控制台输出:
流程:BRL6000 版本:1.0 org.paston.certification.data.impl.BRL6000 org.paston.certification.data.Certification java.lang.Object c1 是类 org.paston.certification.data.Certification,c2 是类 org.paston .certification.data.Certification c1 == c2 为假 c1.equals(c2) 为假 c1.getName().equals(c2.getName()) 为真 c1.getClassLoader() == c2.getClassLoader() 为假
还有另一个问题可能暗示了这个问题。每隔 10 秒,我会在控制台中看到以下异常:
May 07, 2013 2:09:45 PM org.apache.catalina.loader.WebappClassLoader loadClass
INFO: Illegal access: this web application instance has been stopped already. Could not load org.ow2.bonita.runtime.tx.StandardTransaction. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1566)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
at org.ow2.bonita.util.ReflectUtil.loadClass(ReflectUtil.java:68)
at org.ow2.bonita.env.descriptor.ObjectDescriptor.construct(ObjectDescriptor.java:195)
at org.ow2.bonita.env.WireContext.construct(WireContext.java:521)
at org.ow2.bonita.env.WireContext.create(WireContext.java:498)
at org.ow2.bonita.env.WireContext.create(WireContext.java:484)
at org.ow2.bonita.env.WireContext.get(WireContext.java:456)
at org.ow2.bonita.env.WireContext.get(WireContext.java:343)
at org.ow2.bonita.env.WireContext.get(WireContext.java:746)
at org.ow2.bonita.env.BasicEnvironment.get(BasicEnvironment.java:151)
at org.ow2.bonita.env.BasicEnvironment.get(BasicEnvironment.java:142)
at org.ow2.bonita.util.EnvTool.getEnvClass(EnvTool.java:175)
at org.ow2.bonita.util.EnvTool.getTransaction(EnvTool.java:84)
at org.ow2.bonita.runtime.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:42)
at org.ow2.bonita.services.impl.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
at org.ow2.bonita.services.impl.RetryInterceptor.execute(RetryInterceptor.java:59)
at org.ow2.bonita.runtime.event.EventExecutorThread.run(EventExecutorThread.java:61)
更新 2
我对这个问题有了更好的理解。Bonitaserver ( AccessorUtil
)也会加载认证对象。它在某处加载了Certification.jar1620768823629427276.tmp
在将进程上传到服务器时 Bonitaserver 创建的类。
另外,我发现了一个可能用于加载这些类的类ReflectUtil
(链接)。
我尝试的是在 doGet 开始时为这两个(servlet)加载类ClassLoader
作为AccessorUtil
. 两者都具有相同的旧结果。
ArrayList<String> classesNames = new ArrayList<String>();
classesNames.add("org.paston.certification.data.Certification");
classesNames.add("org.paston.certification.data.CertificationI");
classesNames.add("org.paston.certification.data.impl.BRL6000");
ClassLoader cl = this.getClass().getClassLoader();
Class<?>[] classes = ReflectUtil.loadClasses(cl, classesNames);
更新 3
@GaborSch 提出的以下代码的结果。我使用它的代码:
System.out.println("--- Test ClassLoader certification object---");
ClassLoader cl1 = certification.getClass().getSuperclass().getClassLoader();
while (cl1 != null) {
System.out.println(cl1.getClass().getCanonicalName() + " " + cl1.hashCode() + " " + cl1);
cl1 = cl1.getParent();
}
System.out.println("--- Test ClassLoader Certification class---");
ClassLoader cl2 = Certification.class.getClassLoader();
while (cl2 != null) {
System.out.println(cl2.getClass().getCanonicalName() + " " + cl2.hashCode() + " " + cl2);
cl2 = cl2.getParent();
}
代码结果:
--- Test ClassLoader certification object---
org.ow2.bonita.runtime.ProcessClassLoader 451656
org.ow2.bonita.runtime.ProcessClassLoader@6e448
org.ow2.bonita.runtime.VirtualCommonClassloader 1182018350
org.ow2.bonita.runtime.VirtualCommonClassloader@46742b2e
org.apache.catalina.loader.StandardClassLoader 318536939
org.apache.catalina.loader.StandardClassLoader@12fc7ceb
sun.misc.Launcher.AppClassLoader 1667514408
sun.misc.Launcher$AppClassLoader@63644028
sun.misc.Launcher.ExtClassLoader 1253061906
sun.misc.Launcher$ExtClassLoader@4ab03512
--- Test ClassLoader Certification class---
org.apache.catalina.loader.WebappClassLoader 2136824254
WebappClassLoader context: /Certification delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader: org.apache.catalina.loader.StandardClassLoader@12fc7ceb
org.apache.catalina.loader.StandardClassLoader 318536939
org.apache.catalina.loader.StandardClassLoader@12fc7ceb
sun.misc.Launcher.AppClassLoader 1667514408
sun.misc.Launcher$AppClassLoader@63644028
sun.misc.Launcher.ExtClassLoader 1253061906
sun.misc.Launcher$ExtClassLoader@4ab03512