views:

279

answers:

3

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?

+1  A: 

One thing that's different between the development and deployed environment is the SERVER_SOFTWARE environment variable:

if (System.getenv("SERVER_SOFTWARE").startsWith("Dev")) {
  // Load MyConstants-dev.properties
} else {
  // Load MyConstants-prod.properties
}

Maybe you can pick which Guice module to load based off of that.

a paid nerd
I tried this with a deployed java GAE application but there is no "SERVER_SOFTWARE" env var but you did lead me down the right road.
Stevko
Ah. I'm pretty sure it exists with Python. Maybe they've changed it or it isn't supported with the Java environment.
a paid nerd
+1  A: 

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() ); 
 };
}
Stevko
A: 

On the above answer for getting the GAE SERVER_SOFTWARE variable; The SERVER_SOFTWARE environment Variable is a CGI default therefore its a web server setting and isn't accessible through the System environment vars but is available from the ServletContext.

Here's the code that should get you the value your needing (No idea why its ServerInfo and not ServerSoftware...):

if (getServletContext().getServerInfo().startsWith("Dev")) {
  // Load MyConstants-dev.properties
} else {
  // Load MyConstants-prod.properties
}
gedionki