Author: swiderski.maciej
Date: 2010-05-11 15:30:47 -0400 (Tue, 11 May 2010)
New Revision: 6311
Added:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/DeploymentObjectInputStream.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/DeserializeVariableTest.java
jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/variables/
jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/variables/DeserializeTaskTest.jpdl.xml
Modified:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java
Log:
JBPM-2703: Deserialization fails to work using custom Classloader
Added:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/DeploymentObjectInputStream.java
===================================================================
---
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/DeploymentObjectInputStream.java
(rev 0)
+++
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/DeploymentObjectInputStream.java 2010-05-11
19:30:47 UTC (rev 6311)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.repository;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+
+/**
+ * Helper class responsible for providing classes while deserializing variables.
+ *
+ * @author Maciej Swiderski swiderski.maciej(a)gmail.com
+ *
+ */
+public class DeploymentObjectInputStream extends ObjectInputStream {
+
+ private String deploymentId;
+
+ public DeploymentObjectInputStream(InputStream stream, String deploymentId) throws
IOException {
+ super(stream);
+ this.deploymentId = deploymentId;
+ }
+
+ @Override
+ protected Class< ? > resolveClass(ObjectStreamClass desc) throws IOException,
ClassNotFoundException {
+
+ try {
+ Class< ? > clazz = Class.forName(desc.getName(), true,
Thread.currentThread().getContextClassLoader());
+ return clazz;
+ } catch (ClassNotFoundException e) {
+ //trying to get it from deployment
+ DeploymentClassLoader cl = new
DeploymentClassLoader(Thread.currentThread().getContextClassLoader(), deploymentId);
+ return Class.forName(desc.getName(), true, cl);
+ }
+ }
+
+
+
+}
Modified:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java
===================================================================
---
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java 2010-05-11
00:43:15 UTC (rev 6310)
+++
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java 2010-05-11
19:30:47 UTC (rev 6311)
@@ -30,7 +30,9 @@
import org.jbpm.api.JbpmException;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
+import org.jbpm.pvm.internal.repository.DeploymentObjectInputStream;
import org.jbpm.pvm.internal.tx.DeserializedObject;
import org.jbpm.pvm.internal.tx.Transaction;
import org.jbpm.pvm.internal.type.Converter;
@@ -71,7 +73,11 @@
byte[] bytes = (byte[]) o;
try {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- ObjectInputStream ois = new ObjectInputStream(bais);
+
+ ObjectInputStream ois = null;
+
+ ois = new DeploymentObjectInputStream(bais,
scopeInstance.getExecution().getProcessDefinition().getDeploymentId());
+
Object object = ois.readObject();
Transaction transaction = EnvironmentImpl.getFromCurrent(Transaction.class,
false);
Added:
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/DeserializeVariableTest.java
===================================================================
---
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/DeserializeVariableTest.java
(rev 0)
+++
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/DeserializeVariableTest.java 2010-05-11
19:30:47 UTC (rev 6311)
@@ -0,0 +1,118 @@
+package org.jbpm.test.variables;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.util.List;
+
+import org.codehaus.janino.DebuggingInformation;
+import org.codehaus.janino.util.StringPattern;
+import org.codehaus.janino.util.enumerator.EnumeratorSet;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.task.Task;
+import org.jbpm.test.JbpmTestCase;
+
+
+public class DeserializeVariableTest extends JbpmTestCase {
+
+ String deploymentId;
+
+ protected void setUp() throws Exception {
+
+ super.setUp();
+
+ generateBeanClass();
+
+ deploymentId = repositoryService.createDeployment()
+
.addResourceFromClasspath("org/jbpm/test/variables/DeserializeTaskTest.jpdl.xml")
+ .addResourceFromInputStream("org/jbpm/test/variables/Bean.class", new
FileInputStream(new
File("target/generated/org/jbpm/test/variables/Bean.class")))
+ .deploy();
+
+ }
+
+ protected void tearDown() throws Exception {
+ repositoryService.deleteDeploymentCascade(deploymentId);
+ super.tearDown();
+ }
+
+
+ public void testDeserializeVariable() {
+ ProcessInstance processInstance =
executionService.startProcessInstanceByKey("DeserializeTaskTest");
+ String processInstanceId = processInstance.getId();
+
+ List<Task> tasks = taskService.findPersonalTasks("alex");
+
+ assertTrue(tasks.size() == 1);
+
+ Task task = tasks.get(0);
+
+ assertNotNull(taskService.getVariable(task.getId(), "bean"));
+
+ assertNotNull(executionService.getVariable(processInstanceId, "bean"));
+
+ taskService.completeTask(task.getId());
+ }
+
+ /**
+ * This method is used to generate source class that will be used within a process but
should not be
+ * on class path while executing process but retrieved from db.
+ *
+ * Uses Janinio to compile the source.
+ */
+ public void generateBeanClass() {
+
+ log.debug("Inside generateBeanClass method");
+ File directory = new File("target/generated/org/jbpm/test/variables");
+
+ if (!directory.exists()) {
+ log.debug("No generated class directory, about to create source file");
+ try {
+ directory.mkdirs();
+ File sourceFile = new File(directory, "Bean.java");
+ FileWriter writer = new FileWriter(sourceFile);
+
+ StringBuffer source = new StringBuffer();
+
+ source.append("package org.jbpm.test.variables;\n");
+ source.append("import java.io.Serializable;\n");
+ source.append("public class Bean implements Serializable {\n");
+ source.append("private static final long serialVersionUID =
-5510563444135221777L;\n");
+ source.append(" private String value;\n");
+ source.append(" public Bean getResult() {\n");
+ source.append(" this.value = \"test\";\n");
+ source.append(" return this;\n");
+ source.append(" }\n");
+ source.append("}\n");
+
+ writer.write(source.toString());
+
+ writer.close();
+ log.debug("Source file create in " + directory.getAbsolutePath());
+
+ File destinationDirectory =
org.codehaus.janino.Compiler.NO_DESTINATION_DIRECTORY;
+ File[] optionalSourcePath = null;
+ File[] classPath = { new File(".") };
+ File[] optionalExtDirs = null;
+ File[] optionalBootClassPath = null;
+ String optionalCharacterEncoding = null;
+ boolean verbose = false;
+ EnumeratorSet debuggingInformation =
DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION;
+ StringPattern[] warningHandlePatterns =
org.codehaus.janino.Compiler.DEFAULT_WARNING_HANDLE_PATTERNS;
+ boolean rebuild = false;
+
+ log.debug("About to run Janinio compiler");
+
+ org.codehaus.janino.Compiler javac = new
org.codehaus.janino.Compiler(optionalSourcePath, classPath, optionalExtDirs,
optionalBootClassPath,
+ destinationDirectory, optionalCharacterEncoding, verbose,
debuggingInformation, warningHandlePatterns, rebuild);
+ javac.compile(new File[] { sourceFile });
+
+ log.debug("Class compiled successfully");
+ } catch (Exception e) {
+
+ log.error("Error while creating additional resources", e);
+ }
+ }
+
+ }
+
+}
Added:
jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/variables/DeserializeTaskTest.jpdl.xml
===================================================================
---
jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/variables/DeserializeTaskTest.jpdl.xml
(rev 0)
+++
jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/variables/DeserializeTaskTest.jpdl.xml 2010-05-11
19:30:47 UTC (rev 6311)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process name="DeserializeTaskTest"
xmlns="http://jbpm.org/4.3/jpdl">
+
+ <start g="13,137,48,48" name="start1">
+ <transition g="-23,-17" name="to java1"
to="java1"/>
+ </start>
+ <task g="256,133,92,52" name="task1"
assignee="alex">
+ <transition g="-27,-17" name="to end1"
to="end1"/>
+ </task>
+ <end g="416,137,48,48" name="end1"/>
+ <java class="org.jbpm.test.variables.Bean" g="116,134,92,52"
method="getResult" name="java1" var="bean">
+ <transition g="-23,-17" name="to task1"
to="task1"/>
+ </java>
+</process>
\ No newline at end of file