<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">

<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>

                                <td>

                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="http://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">JBoss Community</a></h1>
                                                                </td>

                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px;  -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
    Classloading of JNDI objects in ExternalActivityBehaviour impl
</h3>
<span style="margin-bottom: 10px;">
    created by <a href="http://community.jboss.org/people/jcouch">Justin Couch</a> in <i>jBPM</i> - <a href="http://community.jboss.org/message/559670#559670">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">

<div class="jive-rendered-content"><p>Classloading seems to be the eternal bane of JBPM and I've run in to another fun problem <span> :( </span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>Platform: JBPM 4.4, JBoss 5.1.0GA with JBPM as a process, JDK 1.6 u21, Win7 64bit</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>I have a custom ExternalActivityBehaviour where we reference several remote beans through JNDI. We have JBoss set up for strict classloading so that each EAR file has it's own class loader. My code for the deployment registers all the necessary classes with the JBPM deployment instance as needed:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code">
&#160;&#160;&#160;&#160;&#160;&#160;&#160; ByteArrayInputStream bis = new ByteArrayInputStream(jbpm_config.getBytes());&#160;&#160;&#160;&#160;&#160;&#160;&#160; try&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ProcessEngine jbpm_engine = getProcessEngine();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ExecutionService exec_service = jbpm_engine.getExecutionService();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RepositoryService repo_service = jbpm_engine.getRepositoryService();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NewDeployment deployment = repo_service.createDeployment();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String workflow_name = workflow.getWorkflowName();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String jpdl_name = workflow_name + ".jpdl.xml";&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; deployment.addResourceFromInputStream(jpdl_name, bis);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InputStream[] is = new InputStream[RUNTIME_CLASSES.length];&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ClassLoader cl = Thread.currentThread().getContextClassLoader();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for(int i = 0; i &lt; RUNTIME_CLASSES.length; i++)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String cls = convertClassName(RUNTIME_CLASSES[i]);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InputStream class_input = cl.getResourceAsStream(cls);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(class_input == null)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; log(...)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; is[i] = class_input;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; deployment.addResourceFromInputStream(cls, class_input);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; deployment.setName(workflow_name);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String deployment_id = deployment.deploy();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ProcessInstance process_instance =&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; exec_service.startProcessInstanceByKey(workflow_name, vars);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; close(is);&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch(JbpmException jbe)&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>where getProcessEngine() uses a JNDI lookup.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>That's fine - everything registers and puts the right sets of classes in to the DB - confirmed by manual inspection of the JBPM4_LOB table.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>My custom behaviour looks like this:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code">
public class JMSActivityBehaviour implements ExternalActivityBehaviour{&#160;&#160;&#160; private JobProcessorManagerRemote jobProcessor;&#160;&#160;&#160; public JMSActivityBehaviour()
&#160;&#160;&#160; {
&#160;&#160;&#160;&#160;&#160;&#160;&#160; ....&#160;&#160;&#160; }&#160;&#160;&#160; @Override&#160;&#160;&#160; public void signal(ActivityExecution exec,&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String signal,&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Map&lt;String, ?&gt; extVars)&#160;&#160;&#160;&#160;&#160;&#160;&#160; throws Exception&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160; exec.setVariables(extVars);&#160;&#160;&#160;&#160;&#160;&#160;&#160; exec.take(signal);&#160;&#160;&#160; }&#160;&#160;&#160; /**&#160;&#160;&#160;&#160; * @inheritDoc&#160;&#160;&#160;&#160; */&#160;&#160;&#160; @Override&#160;&#160;&#160; public void execute(ActivityExecution exec)&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Locate the message queue first, to make sure we can send the&#160;&#160;&#160;&#160;&#160;&#160;&#160; // message.&#160;&#160;&#160;&#160;&#160;&#160;&#160; String jms_queue = null;&#160;&#160;&#160;&#160;&#160;&#160;&#160; QueueSession session = null;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Queue message_queue = null;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Context ctx = null;&#160;&#160;&#160;&#160;&#160;&#160;&#160; try&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ctx = new InitialContext();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; QueueConnectionFactory fac =&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (QueueConnectionFactory)ctx.lookup("ConnectionFactory");&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; QueueConnection conn = fac.createQueueConnection();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; conn.start();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(jobProcessor == null)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Object obj = ctx.lookup("ejb/mycompany/JobProcessorManager");&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(obj != null)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; jobProcessor = (JobProcessorManagerRemote)PortableRemoteObject.narrow(obj,JobProcessorManagerRemote.class );&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }....&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (NamingException ne)
....
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>in the line where I look up the custom EJB (EJB3 SLSB), I get a ClassNotFoundException on the remote interface class. Note that the variable in the top of the class doesn't throw the CNFE on &lt;init&gt;, it is only during the JNDI lookup, from somewhere in the guts of JNDI. I've confirmed w test that that specific EJB end point can be located in JNDI in other EJBs, MBeans, and even external Junit tests, so I have narrowed it down to the way that JBPM does it's classloading specifically. Here's the important part of the stack trace:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code">
Caused by: java.lang.ClassNotFoundException: com.mycompany.server.ejb3.scheduler.JobProcessorManagerRemote from BaseClassLoader@bec2452{VFSClassLoaderPolicy@3c44899b{name=vfsfile:/D:/apps/jboss-5.1.0.GA/server/iICE/deploy/jbpm/jbpm-enterprise.jar/ domain=ClassLoaderDomain@7d858aa0{name=DefaultDomain parentPolicy=BEFORE parent=org.jboss.bootstrap.NoAnnotationURLClassLoader@2f754ad2} roots=[MemoryContextHandler@933641734[path= context=vfsmemory://3ia22z-wqetcv-gdhxpu8b-1-gdhxq6z0-2a real=vfsmemory://3ia22z-wqetcv-gdhxpu8b-1-gdhxq6z0-2a], FileHandler@53614709[path=jbpm/jbpm-enterprise.jar context=file:/D:/apps/jboss-5.1.0.GA/server/iICE/deploy/ real=file:/D:/apps/jboss-5.1.0.GA/server/iICE/deploy/jbpm/jbpm-enterprise.jar/]]&#160; delegates=null exported=[META-INF] &lt;IMPORT-ALL&gt;NON_EMPTY}}&#160;&#160;&#160; at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:448)&#160;&#160;&#160; at java.lang.ClassLoader.loadClass(Unknown Source)&#160;&#160;&#160; at org.jboss.classloading.spi.DelegatingClassLoader.loadClass(DelegatingClassLoader.java:87)&#160;&#160;&#160; at java.lang.ClassLoader.loadClass(Unknown Source)&#160;&#160;&#160; at org.jboss.util.loading.DelegatingClassLoader.loadClass(DelegatingClassLoader.java:97)&#160;&#160;&#160; at java.lang.ClassLoader.loadClass(Unknown Source)&#160;&#160;&#160; at java.lang.Class.forName0(Native Method)&#160;&#160;&#160; at java.lang.Class.forName(Unknown Source)&#160;&#160;&#160; at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.redefineProxyInTcl(ProxyObjectFactory.java:406)&#160;&#160;&#160; ... 175 more
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>In reading through past documentation and forum threads, I've noticed that there used to be an option in JBPM to turn off it's internal classloader and delegate to JBoss's&#160; classloader. With JBPM 4.3 and 4.4 that option no longer seems to exist. Anyone have ideas on places to look and other options to try. I've tried everything in the wiki, previous forum posts and such, just completely out of ideas.</p></div>

<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
    <p style="margin: 0;">Reply to this message by <a href="http://community.jboss.org/message/559670#559670">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in jBPM at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034">Community</a></p>
</div></td>
                        </tr>
                    </tbody>
                </table>


                </td>
            </tr>
        </tbody>
    </table>

</div>

</body>
</html>