tags:

views:

79

answers:

4

I have a simple problem: I want to configure an object differently based on whether the object is instantiated within a servlet container, or whether it is instantiated in a stand alone app.

The object is a database connection, and I care about setting query timeouts.

The first solution that I can come up with is:

if (insideServletContainer(this.getClass().getClassLoader()) { 
  /// do some servlet specific config
}
else {
 /// do some standalone config
}

The question is, of course, can I write a reliable method of telling whether the class was loaded within a servlet container. It feels like a hack at best.

The second option is to assume that the default case is a stand alone instantiation, set defaults based on stand-alone configuration, and override them within the servlet context.

So, to sum up my question is: Do you know of a good/reliable mechanism if the class was loaded from within a servlet container? If not, I will have to take the second route.

Nick

+6  A: 

This seems like a really bad idea. Instead, why don't you allow the class to take parameters, then let the container or app configure it appropriately?

Zak
+4  A: 

An alternate way to do this sort of thing is to have the configuration injected into this class by some sort of bootstrap loader.

In a standalone version, this would be done by the main() method (or something called from it).

In a webapp version, this would be done by a listener or filter invoked configured within the web.xml.

Dependency injection is useful here as it removes the need for your application to check these sorts of things; instead the application is given what it needs.

matt b
A: 

I would recommend Dependency Injection like @matt b.

As a second option, if it is only the simple case you described and you don't want to add or learn a DI framework to support this feature. You can accomplish the same thing as your current code by using a properties file to load different value based on the environment. You can simply use a different file for each environment and supply a VM arg to indicate which environment you are running.

db_prop.dev
db_prop.stalone
dp_prop.int
db_prop.prod

Then you can load by resource

"db_prop." + System.getProperty("runtime.env")
Robin
vm args don't work well in servlets, since you are not in control of the vm startup args. You might be able to have the servlet set a system property, but only if the security policy is configured to let webapps do that. Failing that , you could default to null meaning servlet, but it's a bit loose.
mdma
DI does not solve my problem. It just inverts the decision making/control into an injected properties/settings object. So, with DI I can have a common instantiation pattern, and one of the injected objects will determine the proper configuration. Without DI I will need to instantiate, then configure in the invocation.
Nick Hristov
@mdma - I was assuming that he had access to the server to enter such arguments.
Robin
+2  A: 

Setting aside whether or not this is a good idea, I'd suggest looking up java:comp/env, which is only going to be available in an EE server:

try {
  new InitialContext().lookup("java:comp/env");
  /// do some servlet specific config
} catch (NamingException ex) {
  /// do some standalone config
}
bkail
That's kind of where I was headed. Thanks.
Nick Hristov