Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Server-side Java: Patterns for flexible initialization, Part 2

Customizing command targets in your system initialization

  • Print
  • Feedback

Page 4 of 4

What happens in the startup method?

It is important that you place the startup method in the same class as the configuration launcher constructor. This imposes no further limitations on the system, since you may easily implement another setup and launcher class, or subclass the existing one. After changing the string entries in the configuration file, the setup and launching processes are now completely controlled by the new Startup launcher.

The only task you're required to perform in the startup method is setting the system state into normal mode. In the example loadSystem method, the application system is brought to normal mode and then immediately shut down again.

Listing 6. loadSystem() method

 /**
   * Sample launcher method that changes the operation level of the system.
   * This would be replaced with a 'go to normal operating state' 
instruction,
   * as system halts would probably be initiated by passing the JVM an 
operating
   * system signal or receiving a message on a server socket.
   */
  public void loadSystem()
  {
       // Log.
       System.out.println("[TestClass loadSystem]: Moving system into 
normal operation status level.");
       // Goto NORMAL operation state
       this.setSystemStatus(this.NORMAL);
       // All is well.
       System.out.println("[TestClass loadSystem]: System operating 
within normal parameters.");
       // Log.
       System.out.println("[TestClass loadSystem]: Bringing system to 
halted state.");
       // Goto HALT operation state
       this.setSystemStatus(this.HALT);
       // All is done.
       System.out.println("[TestClass loadSystem]: System 
halted.");
  }

When running the system using the two Test classes, the log below appears. Note that module dependencies are preserved during operation state changes; the BaseModule is always kept running at a certain operation state before starting the HighLevelModule on that same operation state. Conversely, the HighLevelModule is always shut down on a particular operation state prior to shutting down the BaseModule from that operation state.

Listing 7. System log

TestClass setupApplicationSystem]: All modules registered 
with automagic module management.
Created instance of com.jguru.initHandler.TestClass
[Instance]: TestClass(String, int) called with parameters: (A custom 
config string, 42)
Invoking method loadSystem
[TestClass loadSystem]: Moving system into normal operation status level.
 --> Module 'BaseModule' changed status to 1
 --> Module 'HighLevelModule' changed status to 1
 --> Module 'BaseModule' changed status to 2
 --> Module 'HighLevelModule' changed status to 2
[TestClass loadSystem]: System operating within normal parameters.
[TestClass loadSystem]: Bringing system to halted state.
 --> Module 'HighLevelModule' changed status to 1
 --> Module 'BaseModule' changed status to 1
 --> Module 'HighLevelModule' changed status to 0
 --> Module 'BaseModule' changed status to 0
[TestClass loadSystem]: System halted.

Tying the knot

The full JavaDoc reference and source code for the setup system are available for download in Resources. Download it, then follow the execution path through the application framework and play around with your own implementations of the various interfaces.

Conclusion

When developing a setup subsystem, strive for decoupling the application system root class and the implementation of the setup subsystem. The less tightly coupled the two are, the smaller the system maintenance cost. The reflection classes of the Java API greatly facilitate the introspection required to implement that decoupling. Use a reflective approach when designing your setup subsystem, and your overall maintenance cost of the subsystem will be dramatically reduced.

A setup subsystem must be decoupled from the application subsystems it controls. Using a unified subsystem facade API, each subsystem may be controlled in a simple fashion. Run-level systems, such as the simple one described in this article, enhance control over large systems by defining a set of fixed system states in which all subsystems should be stable.

About the author

Lennart Jorelid is a server-side Java and ecommerce content expert working for jGuru Europe. With working experience that spans projects in the United States, Canada, United Kingdom, Switzerland, Sweden, and Germany, Lennart is a recognized expert, architect, and educator in the Java technology community. Based in G�teborg, Sweden, he is currently writing a book on server-side Java patterns. Lennart is a fan of skiing, acting, and sci-fi. Learn more about Lennart at jGuru.com. JavaWorld and jGuru have formed a partnership to help the community better understand server-side Java technology. Together, JavaWorld and jGuru are jointly producing articles and free educational Web events.

Read more about Enterprise Java in JavaWorld's Enterprise Java section.

  • Print
  • Feedback