cancel
Showing results for 
Search instead for 
Did you mean: 

Custom ClassLoader failing with BeanInfo & BeanCustomizer for ProcessParam

zoikks1
Champ in-the-making
Champ in-the-making
Good afternoon,

I have built a framework for running workflows that uses Activiti 5.16.3, MySql 5.6.  The framework is written using EJB 3.1 technology and executes on WebLogic 12.1.1.  Although this is an EJB project, I have used Spring to inject the ProcessEngine into the base EJBs.

My framework is designed to allow for running many different processes.  I have attempted to write my own custom class loader that reads a directory external to the framework and classloads the necessary objects on-the-fly.  I wanted to be able to swap out an individual jar specific to a process without directly modifying any other code or rebuild the EAR (downing the server to replace a jar isn't critical at this point)

I have read some of the posting about what to watch out for while writing your own classloader (granted, I probably haven't found all the posting on classloaders yet).   I used the  setClassLoader in the ProcessEngineConfiguration to set the custom classloader and this appeared to be working properly with what I wanted to do. 

The problem I'm facing is that I have a pojo (ie org.zoikks.MyObject) that gets created in a delegate and put into the workflow.  As this happens and the workflow moves on, I see the an exception about trying to find a "BeanInfo" for the pojo (ie java.lang.ClassNotFoundException org.zoikks.MyObjectBeanInfo) and a second exception about trying to find a "Customizer" for the pojo (ie java.lang.ClassNotFoundException org.zoikks.MyObjectCustomizer)

I have traced through the code and found the call to the Introspector where  it tries to call getExplicitBeanInfo(Class<?> cls).  Immediately, it calls into my custom class loader looking for org.zoikks.MyObjectBeanInfo and org.zoikks.MyObjectCustomizer - neither of which exists in my classloader.

I have two questions:

1 - What is the purpose of the Introspector trying to get BeanInfo for a pojo?  (I assume it is for caching purposes - if so, is there a way to disable this?)

2 - Is there a way to point the Introspector to a different classloader or include the generated BeanInfos in my own classloader?

Many thanks,

- Joe
5 REPLIES 5

jbarrez
Star Contributor
Star Contributor
Not sure where the code is you are talking about. What class are we talking about there? The code doesn't ring a bell for me … but that doesn't mean a thing Smiley Tongue

zoikks1
Champ in-the-making
Champ in-the-making
The following is the stacktrace.  From this stacktrace, pinpointing what code is being called should be self-evident.

        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:274)
        at com.sun.beans.finder.ClassFinder.findClass(ClassFinder.java:103)
        at com.sun.beans.finder.InstanceFinder.instantiate(InstanceFinder.java:93)
        at com.sun.beans.finder.InstanceFinder.find(InstanceFinder.java:66)
        at java.beans.Introspector.findExplicitBeanInfo(Introspector.java:438)
        at java.beans.Introspector.<init>(Introspector.java:388)
        at java.beans.Introspector.getBeanInfo(Introspector.java:163)
        at org.activiti.engine.impl.javax.el.BeanELResolver$BeanProperties.<init>(BeanELResolver.java:54)
        at org.activiti.engine.impl.javax.el.BeanELResolver.toBeanProperty(BeanELResolver.java:619)
        at org.activiti.engine.impl.javax.el.BeanELResolver.getValue(BeanELResolver.java:298)
        at org.activiti.engine.impl.javax.el.CompositeELResolver.getValue(CompositeELResolver.java:231)
        at org.activiti.engine.impl.juel.AstProperty.eval(AstProperty.java:61)
        at org.activiti.engine.impl.juel.AstBinary$SimpleOperator.eval(AstBinary.java:27)
        at org.activiti.engine.impl.juel.AstBinary.eval(AstBinary.java:106)
        at org.activiti.engine.impl.juel.AstEval.eval(AstEval.java:50)
        at org.activiti.engine.impl.juel.AstNode.getValue(AstNode.java:26)
        at org.activiti.engine.impl.juel.TreeValueExpression.getValue(TreeValueExpression.java:114)
        at org.activiti.engine.impl.delegate.ExpressionGetInvocation.invoke(ExpressionGetInvocation.java:33)
        at org.activiti.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:37)
        at org.activiti.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterc
eptor.java:25)
        at org.activiti.engine.impl.el.JuelExpression.getValue(JuelExpression.java:48)
        at org.activiti.engine.impl.el.UelExpressionCondition.evaluate(UelExpressionCondition.java:37)
        at org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActiv
ityBehavior.java:63)
        at org.activiti.engine.impl.bpmn.behavior.FlowNodeActivityBehavior.execute(FlowNodeActivityBehavior.ja
va:36)

It is within this code that the org.zoikks.MyObjectBeanInfo is being generated and the custom classloader is unable to find it.

Please let me know if you would like additional information.

Thanks,

- Joe

jbarrez
Star Contributor
Star Contributor
I'm not following here ..  the at java.beans.Introspector.getBeanInfo(Introspector.java:163) is clearly a JDK code. It gets called in the stacktrace when executing a custom expression in Activiti.

zoikks1
Champ in-the-making
Champ in-the-making
Back to the original questions…

1 - What is the purpose of the Introspector call to begin with (in relation to the Activiti functionality)?  Is there a way to disable this?

2 - Is there a way to point the Introspector to a different classloader or include the generated BeanInfos in my own classloader?

Thanks.

- Joe

jbarrez
Star Contributor
Star Contributor
1. No, this is totally not Activiti, but JDK. It is a class in the JDK used when a new instance of a class needs to be created. We cannot circumvent that
2. I would hope the JDK classes are smart enough to know about your custom classloader … I have not enough classloader knowledge (they ALWAYS bite you back) to know what is actually going on here :s
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.