Я получаю следующее исключение, когда хочу передать один тип другому.Невозможно использовать тип типа
java.lang.ClassCastException: org.paston.certification.data.impl.BRL6000
cannot be cast to org.paston.certification.data.Certification
BRL6000 расширяет Сертификацию. Поэтому, в моем понимании, я должен был бы подвергнуть объект типа BRL6000 типу сертификации.
Это код, в котором происходит исключение.
Object certification = ch.getCertificationData(process, version);
Certification c = (Certification)certification;
Развертывание
Приложение развернуто из Eclipse, на сервере Tomcat 7. Мое приложение использует несколько JAR из среды Tomcat (например, Bonita_Server.jar).
Мое приложение (в Eclipse) - это динамические веб-проекты, которые ссылаются на другой проект (Certificationnl), который содержит классы Certification
и BRL6000
. Project Certificationnl добавляется в WAR WAR веб-проекта при развертывании приложения в Tomcat.
Классы
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;
}
getCertificationData
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:
Process: 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 is false c1.equals (c2) is false 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)
Update 2
Я пришел, чтобы понять проблему немного лучше. Bonitaserver (AccessorUtil
) делает загрузку объекта сертификации. Он где-то загружает классы из Certification.jar1620768823629427276.tmp
, которые Bonitaserver создал, когда процесс был загружен на сервер.
Кроме того, я нашел класс ReflectUtil
(link), который, вероятно, используется для загрузки этих классов.
Я пытался загрузить классы в начале doGet для этого (сервлета) как 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);
Update 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
[email protected]
org.ow2.bonita.runtime.VirtualCommonClassloader 1182018350
[email protected]
org.apache.catalina.loader.StandardClassLoader 318536939
[email protected]
sun.misc.Launcher.AppClassLoader 1667514408
[email protected]
sun.misc.Launcher.ExtClassLoader 1253061906
[email protected]
--- Test ClassLoader Certification class---
org.apache.catalina.loader.WebappClassLoader 2136824254
WebappClassLoader context: /Certification delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader: [email protected]
org.apache.catalina.loader.StandardClassLoader 318536939
[email protected]
sun.misc.Launcher.AppClassLoader 1667514408
[email protected]
sun.misc.Launcher.ExtClassLoader 1253061906
[email protected]
Просьба показать определения ваших классов 'BRL6000' и' Certification' и код, который вызывает исключение. – AlexR
Вы уверены, что наследуете/литье на правильный тип сертификации? Возможно, вы случайно импортировали другой тип сертификации. –
Это меня озадачивает, как люди ожидают помощи, не публикуя сломанный код. – jn1kk