Setting a context classloader when calling client code

8 posts / 0 new
Last post
meyerd
Setting a context classloader when calling client code

In ReflectUtil we currently use the custom classloader (ProcessEngineConfiguration.getClassLoader()) for loading JavaDelegate-Classes.

Don't we need to set that ClassLoader as a context-classloader on the current thread when we call the clientcode?

One scenario where it is needed is when we are running in an application server and activiti is deployed as a different application than the application providing the processes and the client code.

Does anyone see a problem arising from setting the custom classloader as context classloader on the current thread (if it is avaliable) ?

Daniel

Daniel Meyer
Activiti developer

camunda services GmbH
Providing Activiti Training & Consulting:
http://www.camunda.com/activiti
Providing stable and supported distributions of Activiti:
http://www.camunda.com/fox
Our Blog: http://www.bpm-guide.de

meyerd

To clarify, I am thinking about sth like this: (org.activiti.engine.impl.bpmn.behavior.ServiceTaskJavaDelegateActivityBehavior)

public void execute(DelegateExecution execution) throws Exception {
    ClassLoader classLoaderBefore = Thread.currentThread().getContextClassLoader();
    try {
      // set the classloader which loaded the delegate as context classloader for the call to the client-code
      Thread.currentThread().setContextClassLoader(javaDelegate.getClass().getClassLoader());      
      javaDelegate.execute(execution);      
    }finally {
      Thread.currentThread().setContextClassLoader(classLoaderBefore);
    }    
  }

Daniel

Daniel Meyer
Activiti developer

camunda services GmbH
Providing Activiti Training & Consulting:
http://www.camunda.com/activiti
Providing stable and supported distributions of Activiti:
http://www.camunda.com/fox
Our Blog: http://www.bpm-guide.de

tombaeyens

Looks valid. But... I don't have a complete overview to ensure that implementing this will lead to the next problem with classloaders, security and other complex aspects. So I think this is a pandora s box. Seems reasonable, but my experience tells me there is a lot more that can be dragged in eventually.

On the other hand, this is not crucial for us and it makes our codebase more complex.

And third, users can embed that piece of code in their own delegate classes if they really want to.

So all that together makes me think it's better to stay away from this kind of features.

Other opinions?

regards, tom.

bernd.ruecker

Hi Tom.

We already have a custom classloader configurable in Activiti. Setting it correctly as context classloader is vital, otherwise that is a half baked solution. And it is exactly like it is done in every app server and like it was done in jBPM 3 as well. Without this, it is not really usable in enterprise environments or scoped deployments. Having your own delegate is only half of the solution: This delegate must be loaded by some classloader as well and when using expressions or the like, you don't even have that opportunity.

So I think we have to do that change. And I don't see anything it could break. Setting your own classloader (with the original class loader as parent) as context classloader is normal behavior and intended by the Java Platform. I don't see any risks with that, but if you have references pointing to such problems it would be interesting to see...

Cheers
Bernd

camunda services GmbH
Providing Activiti Training & Consulting: http://www.camunda.com/activiti
Providing a supported and stabilized version of Activiti: http://www.camunda.com/fox/
Our Blog: http://www.bpm-guide.de/

tombaeyens

Can you explain a bit the use case you're implementing?

Is it classloading from process archives in an ejb environment like you did in jbpm4? If this is the case, are all the pieces in the Activiti code base? Or is this use case something else?

regards, tom.

bernd.ruecker

Basically yes, it is a deployer infrastructure, in this case for JBoss 5.1. No, that is not part of the Activiti code base, since such a deployer infrastructure depends heavily on the specific server (and version). We only committed CDI (which is Java EE 6 standard) to the Activiti code base. But the custom class loader is part of Activiti core, as you may know smiley

camunda services GmbH
Providing Activiti Training & Consulting: http://www.camunda.com/activiti
Providing a supported and stabilized version of Activiti: http://www.camunda.com/fox/
Our Blog: http://www.bpm-guide.de/

tombaeyens

Soon, we'll be working out a classloading scheme incl deployments that also works on the cloud. Still to be determined how that is going to look like. So I think we should postpone this issue until that time. Ideas like deploying a jar engine-wide through our deploy mechanism is what we're thinking about. I want those ideas to settle so that we can create an implementation based on the target use cases first.

Also impact of OSGi classloading is still unclear to me. Maybe we should assemble all classloading related information into a wiki page so that we can capture all ideas and work towards a simple scheme that works for everyone.

regards, tom.

meyerd

Hi Tom,

I understand your concerns. Just out of curiosity, what exactly do you mean by "cloud"? Sth. like this:
http://aws.amazon.com/elasticbeanstalk/
?

As you suggested: http://docs.codehaus.org/display/ACT/Activiti+Classloading

Regards,
Daniel

Daniel Meyer
Activiti developer

camunda services GmbH
Providing Activiti Training & Consulting:
http://www.camunda.com/activiti
Providing stable and supported distributions of Activiti:
http://www.camunda.com/fox
Our Blog: http://www.bpm-guide.de