Uploaded image for project: 'jBPM'
  1. jBPM
  2. JBPM-4033

ContentMarshallerHelper not being passed ClassLoader or Environment in many cases

XMLWordPrintable

      org.jbpm.services.task.utils.ContentMarshallerHelper provides overloaded methods for marshalling and unmarshalling data, notably being used to store and receive content associated with tasks.

      These methods can take an Environment, where one can specify a custom ObjectMarshallingStrategy, and/or they can take a ClassLoader, which can provide visibility into user-application classes that are quite possibly not available to the ClassLoader that originally loaded the jbpm classes.

      Unfortunately, in many cases, the proper overloaded methods are not used, or null is simply being passed in for the Environment and/or ClassLoader. What this means is that the default serialization strategy is used: http://goo.gl/Uu5GI
      , and only the ClassLoader which loaded the ContentMarshallerHelper class itself is used: http://goo.gl/qKlYZ

      Here (in TaskServiceEntryPointImpl) is just one example where null is being passed in: http://goo.gl/2Xb7p
      In Eclipse, if you can do a search for all calls to the marshall and, more importantly, the unmarshall methods. From there you can see all the places that pass in null for the Environment and/or ClassLoader.

      A case slightly different, but related, is here, in the ExernalTaskEventListener: http://goo.gl/KCJAz
      In this case, a ClassLoader is attempted to be found in a Map, whose keys are ksession id's. This map gets populated by the addClassLoader method: http://goo.gl/lZZzw
      , however, this method is never called in a very key place - the getHTWorkItemHandler method of DefaultRegisterableItemsFactory: http://goo.gl/4S6io
      You can see that the setRuntimeManager method is called on the ExernalTaskEventListener, but addClassLoader is never called.

      The end effect of all this is that deserialization fails with a ClassNotFoundException or NoClassDefFoundError in cases where persisted task content is comprised of user-application classes, where those classes are not visible from the same ClassLoader that loaded the jbpm classes.

      One example of this (which was found in the SwitchYard project), is where the jbpm classes are loaded using JBoss AS7 modules, but the user-application classes are loaded from WEB-INF/classes/. The AS7 module won't have visibility to those types. In SwitchYard, I got around this by sometimes extending+overriding, or duplicating with fixes, jbpm code inside SwitchYard code. In other cases, I had to resort to reflection to hack into jbpm classes to make sure the right ClassLoader was available.

      My proposed fix is for someone to find all the places that call the ContentMarshallerHelper's marshall or unmarshall methods, and make sure that whenever possible, the Environment used to build up the ksession is passed in, as well as an API to pass in a user-application ClassLoader. This might mean adding accessor methods which take a ClassLoader, or some other mechanism.

      Thank you!

              swiderski.maciej Maciej Swiderski (Inactive)
              dward-se-jboss David Ward
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: