cancel
Showing results for 
Search instead for 
Did you mean: 

Running Activiti in Google App Engine

ekolesnikov
Champ in-the-making
Champ in-the-making
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.
7 REPLIES 7

ekolesnikov
Champ in-the-making
Champ in-the-making

jbarrez
Star Contributor
Star Contributor
I agree, the instantiation is a bit weird there … using the setter would have been better, as we do everywhere else. But for backwards compatibility, this is definitely better. Thanks!

ekolesnikov
Champ in-the-making
Champ in-the-making
Well, there IS a setter for ExpressionFactory on ExpressionManager - the problem is that you can't avoid initialisation of the default one.

jbarrez
Star Contributor
Star Contributor
@ekolesnikov: accepted. Thanks!

hellokk78
Champ in-the-making
Champ in-the-making
Hi,
   I have written the code like this
public class CustomExpressionManager extends ExpressionManager {


   public CustomExpressionManager() {
    this(new HashMap(),false);
  
   }


   public CustomExpressionManager(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
       Profile profile = null;
       Properties properties = new Properties();
       expressionFactory = new ExpressionFactoryImpl(profile,properties);
      }
   }

}
and set in spring configuration  file as below
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">

  <property name="ExpressionManager" ref="expressionManager" />

</bean>

<bean id="expressionManager" class="com.activiti.load.CustomExpressionManager"/

Getting below error when tried to execute in Google app engine
Caused by: java.security.AccessControlException: access denied ("java.io.FilePermission" "C:\Program Files\Java\jdk1.7.0_67\jre\lib\el.properties" "read")

Can you please help on this

Thanks and Regards
Kiran

jbarrez
Star Contributor
Star Contributor
Seems to be related to google app engine restrictions. Some Googling gave me this : http://stackoverflow.com/questions/12393589/jersey-linking-support-with-google-app-engine-issue. Seems to be related to Juel versions…

zedidas
Champ in-the-making
Champ in-the-making
Hi,

I am very interested in deploying activiti in Google Apps Engine. But it seems there isn't a step by step tutorial on how to achieve this deployment. I've tried to checkout the source code and build it in a Google Apps Engine project but without success. I have no clue where to start.

Would you please explain how you've set up the Google App Engine project so that you can deploy activiti? What kind of adjustments did you have to do in order for this to work.

I would really appreciate your help!

Thanks!