1 Reply Latest reply on Oct 12, 2009 2:24 PM by Tony Sourpuss

    Seam problem(bug?) and Jbpm 4

    Tony Sourpuss Newbie

      Hi,


      I know the current version 2.2.x does not support jbpm 4.1, but I tried to make them work together. So far so good. Most of the complicated things like transaction handling, basic workflows runs as expected.


      But if I want to use parameters (field tag) for custom activities in processdefinitions




      <custom expr="#{daoCustomHandler}" name="customCreateUsers">
          <field name="number">
            <string value="2" />
          </field>
          <transition to="end" />
      </custom>





      the parameter will not be set in the object (custom activity) at runtime. The object is a POJO Seam Bean, which is identified by {daoCustomHandler}. The name of the seam bean will be resolved by own written class SeamConfiguration:




      @Startup
      @AutoCreate
      @Scope(ScopeType.APPLICATION)
      @Name("coreWorkflow.seamConfiguration")
      public class SeamConfiguration extends JbpmConfiguration implements EnvironmentFactory, ProcessEngine {
      
          /** the serial version uid. */
          private static final long serialVersionUID = 1L;
      
          /** its logger. */
          private static final Log LOG = Log.getLog(SeamConfiguration.class);
      
          /**
           * Instantiates a new seam configuration.
           * 
           * @param jbpmConfigurationLocation
           */
          public SeamConfiguration() {
              Configuration.implementationClassNames = new HashMap<String, String>();
              Configuration.implementationClassNames.put("seam", "org.jbpm.api.SeamConfiguration");
          }
      
          /**
           * {@inheritDoc}
           */
          public EnvironmentImpl openEnvironment() {
      
              PvmEnvironment environment = new PvmEnvironment(this);
      
              if (LOG.isDebugEnabled()) {
                  LOG.debug("opening jbpm-seam" + environment);
              }
      
              environment.setContext(new SeamContext());
      
              installAuthenticatedUserId(environment);
              installProcessEngineContext(environment);
              installTransactionContext(environment);
      
              return environment;
          }
      
          @SuppressWarnings("unchecked")
          @Override
          public <T> T get(final Class<T> type) {
              T t = (T) Component.getInstance(type);
              if (t != null) {
                  return t;
              }
              return super.get(type);
          }
      
          @Override
          public Object get(final String key) {
              Object o = Component.getInstance(key);
              if (o != null) {
                  return o;
              }
              return super.get(key);
          }
      }



      and additionally the SeamContext class:




      public class SeamContext implements Context {
      
          /**
           * {@inheritDoc}
           */
          public Object get(final String key) {
              try {
                  return Component.getInstance(key);
              } catch (Exception e) {
                  return null;
              }
          }
      
          /**
           * {@inheritDoc}
           */
          @SuppressWarnings("unchecked")
          public <T> T get(final Class<T> type) {
              try {
                  return (T) Component.getInstance(type);
              } catch (Exception e) {
                  return null;
              }
          }
      
          /**
           * {@inheritDoc}
           */
          public String getName() {
              return "seam";
          }
      
          /**
           * {@inheritDoc}
           */
          public boolean has(final String key) {
              try {
                  //Component.getInstance(key, false, false)
                  return (Contexts.getApplicationContext().get(key + ".component") != null);
              } catch (Exception e) {
                  return false;
              }
          }
      
          /**
           * {@inheritDoc}
           */
          public Set<String> keys() {
              throw new UnsupportedOperationException("Not possible to get keys from seam!");
          }
      
          /**
           * {@inheritDoc}
           */
          public Object set(final String key, final Object value) {
              throw new UnsupportedOperationException("Add new seam component through jbpm not supported!");
          }
      }



      Which resolves the seam bean names.



      The parameter (field tag) is not set in the resulting object, because the seam JavaBeanInterceptor uses the intial Component instance, which is created at first call to Component.getInstance() at process deployment. At runtime it uses the initially created Component (JavaBeanInterceptor constructor bean), which does not have set the parameter number. This is only set in the JavaBeanInterceptor method proxy parameter.


      Why does the JavaBeanInterceptor uses the bean attribute from constructor and not the proxy to invoke the method?


      I don't know if this is a bug, but with this I am unable to invoke seam object from jbpm, because it always uses the fresh initialized objects instead of the changed.


      If anybody knows a solution to this problem - you welcome.


      Thanks in advance,


      tony