Client Aware Java

We’re going to talk about making Java Jangles (available on GitHub) aware of its current environment, whether it is running in a console application, a web app, servicing an Android application, or in some other client environment.

Making Java environment-aware gives us the ability to perform tasks dynamically, like loading configuration and log4k properties files from client-specific locations.

We see the Jangles Project with the core functionality we want to re-use in multiple clients.

For today’s purposes we’re going to determine one of three current environments, if Jangles is running

  • At the Console
  • In a Web Application in Development Mode
  • In a Web Application in Production

We start with a simple JangleEnvironment enumerator which you’ll see used elsewhere.

The core of the logic in determining the current environment is shown in JangleGlobals below. We test for the existence of Tomcat (1) and if not present we default to a Console environment. We’ve configured Eclipse to use its own instance of Tomcat, so we can determine if we’re running the web app in development (2) or in production (3).

What we’re doing, in other words, is testing for unique properties of each client environment that will be using Jangles.

To distinguish between web development and production we configure Eclipse to use workspace metadata for Tomcat. This gives us a .metadata pathway property we can use to know we’re in development mode.

Environment Awareness In Action

Here’s an example of using our new environment smarts. We’re using Apache Log4k and want to use custom log4k.properties files for each environment.

public static Log getLog() {

	JangleEnvironment _jangleEnvironment = JangleGlobals.Get().CurrentEnvironment;
	String root = JangleGlobals.Get().RootDirectory;
	Log logger = LogFactory.getLog("Jangles");
	File propertiesFile = null;
	switch (_jangleEnvironment) {
	case CONSOLE:
		propertiesFile = new File(root, "/log4j.properties");
		break;
	case WEBDEVELOPMENT:
		propertiesFile = new File(root, "/conf/logdev4j.properties");
		break;
	case WEBPRODUCTION:
		propertiesFile = new File(root, "/conf/logproduction4j.properties");
		break;
	default:
		break;
	}
	PropertyConfigurator.configure(propertiesFile.toString());

	return logger;
}

Now that we know what environment we’re in we can reuse our code by providing client-specific functionality while leveraging our core logic.