Author: alex.guizar(a)jboss.com
Date: 2010-11-24 23:32:36 -0500 (Wed, 24 Nov 2010)
New Revision: 6845
Modified:
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/file/def/FileDefinition.java
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java
Log:
JBPM-2918 prevent process class loading if transaction is not active
Modified:
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/file/def/FileDefinition.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/file/def/FileDefinition.java 2010-11-25
02:24:18 UTC (rev 6844)
+++
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/file/def/FileDefinition.java 2010-11-25
04:32:36 UTC (rev 6845)
@@ -35,9 +35,11 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jbpm.JbpmConfiguration;
+
+import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.bytes.ByteArray;
+import org.jbpm.configuration.ObjectFactory;
import org.jbpm.module.def.ModuleDefinition;
import org.jbpm.module.exe.ModuleInstance;
import org.jbpm.util.IoUtil;
@@ -47,8 +49,11 @@
private static final long serialVersionUID = 1L;
private static String getRootDir() {
- if (JbpmConfiguration.Configs.hasObject("jbpm.files.dir")) {
- return JbpmConfiguration.Configs.getString("jbpm.files.dir");
+ JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
+ if (jbpmContext != null) {
+ ObjectFactory objectFactory = jbpmContext.getObjectFactory();
+ if (objectFactory.hasObject("jbpm.files.dir"))
+ return (String) objectFactory.createObject("jbpm.files.dir");
}
return null;
}
Modified:
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java 2010-11-25
02:24:18 UTC (rev 6844)
+++
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java 2010-11-25
04:32:36 UTC (rev 6845)
@@ -35,6 +35,8 @@
import org.jbpm.JbpmException;
import org.jbpm.file.def.FileDefinition;
import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.persistence.db.DbPersistenceService;
+import org.jbpm.svc.Service;
public class ProcessClassLoader extends ClassLoader {
@@ -42,38 +44,44 @@
private long processDefinitionId;
private final JbpmConfiguration jbpmConfiguration;
+
private final URLStreamHandler urlStreamHandler = new URLStreamHandler() {
-
protected URLConnection openConnection(URL url) throws IOException {
- return new URLConnection(url) {
- private FileDefinition fileDefinition;
+ return new ProcessUrlConnection(url);
+ }
+ };
- public void connect() throws IOException {
- if (connected) return;
+ private final class ProcessUrlConnection extends URLConnection {
- ProcessDefinition processDefinition = getProcessDefinition();
- if (processDefinition == null) {
- throw new IOException("no active jbpm context");
- }
- fileDefinition = processDefinition.getFileDefinition();
+ ProcessUrlConnection(URL url) {
+ super(url);
+ }
- connected = true;
- }
+ public void connect() throws IOException {
+ if (!connected) connected = true;
+ }
- public InputStream getInputStream() throws IOException {
- connect();
+ public InputStream getInputStream() throws IOException {
+ connect();
+ /*
+ * ideally, the connection would fetch the process definition and assign it to a
class
+ * field on connect(); however, that strategy "leaks" a detached process
definition
+ */
+ ProcessDefinition processDefinition = getProcessDefinition();
+ if (processDefinition == null) throw new IOException("no active jbpm
context");
- String fileName = url.getFile();
- byte[] fileContent = fileDefinition.getBytes(fileName);
- if (fileContent == null) {
- throw new FileNotFoundException(fileName);
- }
+ // having established a "connection", check whether the file exists
+ String fileName = url.getPath();
+ FileDefinition fileDefinition = processDefinition.getFileDefinition();
+ if (fileDefinition == null || !fileDefinition.hasFile(fileName)) {
+ throw new FileNotFoundException(fileName);
+ }
- return new ByteArrayInputStream(fileContent);
- }
- };
+ // retrieve file content
+ byte[] fileContent = fileDefinition.getBytes(fileName);
+ return new ByteArrayInputStream(fileContent);
}
- };
+ }
public ProcessClassLoader(ClassLoader parent, ProcessDefinition processDefinition) {
this(parent, processDefinition, null);
@@ -93,9 +101,7 @@
}
else {
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
- if (jbpmContext == null) {
- throw new JbpmException("no active jbpm context");
- }
+ if (jbpmContext == null) throw new JbpmException("no active jbpm
context");
this.jbpmConfiguration = jbpmContext.getJbpmConfiguration();
}
}
@@ -110,9 +116,19 @@
if (processDefinition != null) return processDefinition;
if (jbpmConfiguration != null) {
+ // is there an active context?
JbpmContext jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
if (jbpmContext != null) {
- return jbpmContext.getGraphSession().loadProcessDefinition(processDefinitionId);
+ // is a database persistence service present?
+ Service service = jbpmContext.getServices().getPersistenceService();
+ if (service instanceof DbPersistenceService) {
+ // confirm transaction is still active before loading process definition
+ DbPersistenceService persistenceService = (DbPersistenceService) service;
+ if (persistenceService.isTransactionActive()) {
+ return persistenceService.getGraphSession()
+ .loadProcessDefinition(processDefinitionId);
+ }
+ }
}
}
@@ -125,37 +141,35 @@
if (processDefinition == null
|| (fileDefinition = processDefinition.getFileDefinition()) == null) return null;
- // we know that the leading slashes are removed in the names of the
- // file definitions, therefore we skip the leading slashes
+ // skip leading slashes
int off = 0;
for (int len = name.length(); off < len && name.charAt(off) ==
'/'; off++)
/* just increase offset */;
- // if the name of the resources is absolute (starts with one or more slashes)
+ // if the resource name is absolute, that is, starts with one or more slashes
if (off > 0) {
- // then start searching from the root of the process archive
+ // then search from the root of the process archive
name = name.substring(off);
}
else {
- // otherwise (if the resource is relative), look in the classes
- // directory of the file module definition
+ // otherwise, if the resource is relative, search from the classes directory
name = "classes/" + name;
}
if (!fileDefinition.hasFile(name)) return null;
try {
- return new URL("processresource", null, -1, name, urlStreamHandler);
+ return new URL("jbpm", null, -1, name, urlStreamHandler);
}
catch (MalformedURLException e) {
throw new JbpmException("could not create url", e);
}
}
- /** @deprecated */
+ /** @deprecated not in use anymore */
public static class BytesUrlStreamHandler extends URLStreamHandler {
- private byte[] bytes;
+ private final byte[] bytes;
public BytesUrlStreamHandler(byte[] bytes) {
this.bytes = bytes;
@@ -166,10 +180,10 @@
}
}
- /** @deprecated */
+ /** @deprecated not in use anymore */
public static class BytesUrlConnection extends URLConnection {
- private byte[] bytes;
+ private final byte[] bytes;
public BytesUrlConnection(byte[] bytes, URL u) {
super(u);
@@ -197,23 +211,16 @@
byte[] classBytes = fileDefinition.getBytes(fileName);
if (classBytes == null) throw new ClassNotFoundException(className);
- // define the package before defining the class
- // see
https://jira.jboss.org/jira/browse/JBPM-1404
+ // if the class is in a package
int packageIndex = className.lastIndexOf('.');
-
if (packageIndex != -1) {
+ // check whether this class loader (or any ancestor) defined the package already
String packageName = className.substring(0, packageIndex);
-
if (getPackage(packageName) == null) {
- Package jbpmPackage = ProcessClassLoader.class.getPackage();
- definePackage(packageName,
- null,
- null,
- null,
- jbpmPackage.getImplementationTitle(),
- jbpmPackage.getImplementationVersion(),
- jbpmPackage.getImplementationVendor(),
- null);
+ // define the package prior to defining the class
+ // see
https://jira.jboss.org/jira/browse/JBPM-1404
+ definePackage(packageName, null, null, null, processDefinition.getName(),
+ Integer.toString(processDefinition.getVersion()), null, null);
}
}
return defineClass(className, classBytes, 0, classBytes.length);