Search code examples
javagoogle-app-enginegwtguicegwt-gin

How to vary Constants based on deployment instance


I've been building a GWT 1.7 + GAE application using the eclipse plugin. The system constants are loaded into a MyConstants.properties file that is loaded by the singleton MyConstants class extending the ...gwt.i18n.client.Constants class.

I would like for MyConstants to load one of several files containing settings like

  • MyConstants-local.properties
  • MyConstants-alpha.properties
  • MyConstants-beta.properties
  • MyConstants-prod.properties

I've found several references to Guice's Enum Stage but this does not seem to be supported by gin. Besides, it only handles dev/prod and I definitely need a local/beta/prod solution.

Is there a way to do this using a command line arg or some other instance defined runtime parameter that will work when loaded onto GAE?


Solution

  • On the GAE server side, I was able to distinguish my dev environment from any deployed production environment with these bits of code.

    Create one interface and two class files.

    public interface MyConstants {
     public String myConstant(); 
    }
    
    public class MyConstantsDev implements MyConstants {
     public String myConstant() { return "xyzzy-dev"; };
    }
    
    public class MyConstantsProd implements MyConstants {
     public String myConstant() { return "xyzzy-prod"; };
    }
    

    Define a bit of Guice magic binding using the "user.dir" env var. The last directory within the user.dir path is either the unique Google App Engine Application Identifier or your root project development directory. Once you know this, you can determine which set of constants to use.

    public class MyServerModule extends com.google.inject.AbstractModule {
    
     String appIdentifier = new File( System.getProperty("user.dir") ).getName();
     if ( appIdentifier.equals("trunk") ) {
      // Load MyConstants-dev.properties
      bind( MyConstants.class ).to( MyConstantsDev.class ).in(Singleton.class);
     } else {
      // Load MyConstants-prod.properties
      bind( MyConstants.class ).to( MyConstantsProd.class ).in(Singleton.class);
     }
    }
    

    This allows me to inject dev/prod constants into classes like this:

    public class MyDomainClass {
    
     @Inject
     public MyDomainClass( Logger logger, MyConstants const ) { 
      logger.debug( const.myConstant() ); 
     };
    }