Question

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?

Was it helpful?

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

OTHER TIPS

You should use the especially made type-safe interface to work this out...

if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production)
{
  //It's production.
}
else
{
  //It's Dev - and (SystemProperty.environment.value() == SystemProperty.Environment.Value.Development)
}

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.

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
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top