AnsweredAssumed Answered

Running Activiti in Google App Engine

Question asked by ekolesnikov on Apr 4, 2014
Latest reply on Jan 27, 2015 by zedidas
Hi All,

I was able to successfully run Activiti in Google App Engine - however, it did require some magic around ExpressionManager/ExpressionFactory. The only issue apart from that is GAE ban on java.awt.* classes, but that could be remediated by disabling createDiagramOnDeploy on ProcessEngineConfiguration.

Would you accept my pull request for ExpressionManager class so we can continue using it without custom binaries, please?

The root of the problem is ExpressionFactoryImpl.loadDefaultProperties() method which contains the following code:

      String path = home + File.separator + "lib" + File.separator + "el.properties";
      File file = new File(path);
      if (file.exists()) { … }

Whilst this snippet is usually considered to be safe, GAE's restriction cause this part to fail with SecurityException because it prohibits file operations outside of the deployment boundaries. I was able to successfully avoid the problem by extending ExpressionManager/ExpressionFactory classes and using ExpressionFactoryImpl(Profile profile, Properties properties) constructor that does not involve loadDefaultProperties() call.

However, the biggest issue was ExpressionManager constructor chain:


  public ExpressionManager() {
    this(null);
  }
 
  public ExpressionManager(Map<Object, Object> beans) {
   super(beans, false);
    // Use the ExpressionFactoryImpl in activiti build in version of juel, with parametrised method expressions enabled
    expressionFactory = new ExpressionFactoryImpl();
    this.beans = beans;
  }


This made the whole point of extending the class useless, since I would have to call one of these anyway (or it would be diligently invoked by the JVM anyway). AOP-style bytecode magic to redefine constructor via load-time instrumentation was not an option because it itself is banned on GAE.

So what I unfortunately ended up with was the whole activiti fork I now have to support, for the sake of this miniscule change:


  public ExpressionManager() {
       this(null);
  }
 
  public ExpressionManager(boolean initFactory) {
       this(null, initFactory);
  }
 
  public ExpressionManager(Map<Object, Object> beans) {
     this(beans, true);
  }
 
  public ExpressionManager(Map<Object, Object> beans, boolean initFactory) {
       this.beans = beans;
       if(initFactory) {
          // Use the ExpressionFactoryImpl in activiti build in version of juel, with parametrised method expressions enabled
          expressionFactory = new ExpressionFactoryImpl();
       }

  }


This change allows disabling ExpressionFactoryImpl initialization so I can supply my own instance in overridden constructor. After extending ExpressionFactoryImpl and modifying initialization routine in loadDefaultProperties() I was finally able to run activiti on GAE.

Outcomes