evelopers aren't issued crystal balls with their computers, which makes anticipating future changes to business rules or an application's runtime environment challenging. Fortunately, what your code knows at compile time doesn't need to limit your application's ability to react dynamically to changes in the runtime environment.
Techniques for reading initialization or properties files are well known but many developers are unfamiliar with Java's Reflection API. Reflection provides a means to significantly enhance your code's ability to respond to the runtime environment; differentiating program behavior based upon the user or server or any other runtime variable. This article will explore how the LoginContext class of the Java Authentication and Authorization Services (JAAS) leverages the Reflection API to implement a responsive security services layer by loading login modules on demand rather than at application startup. (JAAS is part of the core JDK as of Java 1.4 and is available as a separate download if you're using Java 1.3x).
The Meaning of Reflection
The Reflection API is located in the java.lang.reflect package. If you take a quick look at the Javadoc for the package you'll immediately notice that a number of the classes bear the names of fundamental Java language elements: Constructor, Field, and Method. This might give you the first hint of what the Reflection API is all aboutproviding a "reflection" of the inner workings of a class. Now, if all that we could do with this reflected view of things is get a report of a class' elements that would be interesting but not especially useful for writing dynamic code. Fortunately, not only can we query a class about its constituent parts but we can also dynamically load and instantiate a class at runtime and invoke methods on objects of that class as well.
|What You Need
| Java 1.3 or later. (1.3 has reached its "end of life" according to Sun so I recommend downloading at least 1.4x if you can.)
One of the design challenges of using Reflection is that you need to clarify what services you wish to provide at runtime that you can't (or don't want to) implement statically. The provision of reusable services that vary based upon the runtime environment is one of the reasons that frameworks such as Struts and JAAS are created. However, even small applications can face design issues that make a dynamic solution preferable over a static one. A word of caution though, over-reliance on Reflection can lead to performance issues because of the extra overhead of determining what class(es) need to be loaded.
|Author's Note: This is a good time to break out a copy of the javax.security.auth.login.LoginContext source code, which you can find as part of Sun's Java source code zip file download or download it as a separate, standalone file here.