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

Problem in retrieving variables of Serializable objects

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • jBPM 3.2.6 GA
    • jBPM 3.3.0 GA
    • Runtime Engine
    • None

      I have encountered a serious problem working with variables whose value is a serializable object.

      The problem is that sometimes (not always!) an error like the following is given when retrieving a variable:

      java.lang.ClassCastException: org.jbpm.bytes.ByteArray$$EnhancerByCGLIB$$cc67d06e

      The code is like:
      MySerializableClass obj = (MySerializableClass) contextInstance.getVariable("myVariable");
      (of course, "myVariable" is a variable that I previously have set with a MySerializableClass object)

      Apart from the CGLIB awful problem with proxies, even if I extract the value from the proxy with the following:

      public static Object getCGLIBProxiedObject(final Object proxy)
      {
      if(proxy instanceof HibernateProxy)

      { final LazyInitializer initializer = ((HibernateProxy) proxy).getHibernateLazyInitializer(); return initializer.getImplementation(); }

      return proxy;
      }

      the problem is that the variable value is retrieved as a org.jbpm.bytes.ByteArray instead of a MyClass instance!
      I did some debugging and discovered that:

      • in org.jbpm.context.exe.VariableContainer.getVariable(String), when org.jbpm.context.exe.VariableContainer.hasVariableLocally(String) is called, Hibernate lazily retrieves a org.jbpm.context.exe.variableinstance.ByteArrayInstance instance from the database and creates it using its empty constructor
      • unfortunately, when a org.jbpm.context.exe.VariableInstance (extended by ByteArrayInstance) is constructed using its constructor, its converter instance variable remains null
      • the VariableInstance converter instance variable is set to something only when a VariableInstance is created using org.jbpm.context.exe.JbpmType.newVariableInstance(), but this is not the case when a VariableInstance is lazily loaded by Hibernate; in fact, in my case, org.jbpm.context.exe.JbpmType.newVariableInstance() is never called and the converter field of my ByteArrayInstance instance is always null!
      • this causes org.jbpm.context.exe.VariableInstance.getValue() to return the value given by org.jbpm.context.exe.variableinstance.ByteArrayInstance.getObject() without applying the necessary conversion (deserialization)

      Please note that my variable values are stored in jBPM database in JBPM_VARIABLEINSTANCE table with the CONVERTER column correctly populated with "R".

      I think this is a critical problem. By now, the only workaround I have found is to always apply the following utility method when retrieving variable values, before returning them to the client code:

      public static Object extractVariableValue(final Object rawValue)
      {
      Object result = CardinisJbpmUtilities.getCGLIBProxiedObject(rawValue);
      if(result instanceof ByteArray)
      try

      { result = new ObjectInputStream(new ByteArrayInputStream(((ByteArray) result) .getBytes())).readObject(); }

      catch(final Exception e)

      { throw new RuntimeException(e); }

      return result;
      }

              aguizar_jira Alejandro Guizar (Inactive)
              mauromol_jira Mauro Molinari (Inactive)
              Votes:
              2 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: