Sunday, December 16, 2007

Time To Run

Everybody loves re-use: no-one would like to re-invent the wheel (at least no-one worth calling a colleague). Re-use in action can be tricky, though, as the library or component you intend to leverage can come with strings attached under the form of runtime dependencies. These dependencies can take several forms, each with a different twist but all with the same promise to make your job a little more... intense!

  • Framework dependencies are often the (incestuous?) children of configuration and reflection: when the latter gets driven by the former, the incertitude concerning what concrete classes your application will actually use, grows and can reach the point when it endangers your system. As an example, consider the way JAXP's concrete classes are determined at runtime: though you program to a unified API, which allows you to re-use existing parsers and processors, you must code your application defensively to ensure the runtime dependencies will provide the features you need.

  • Data dependencies dependency will leverage your existing database, whatever its can be pulled into your application when you re-use a component that carries its own DAO layer. Provided the data layer is flexible enough to accommodate your choice of database engine, this can be managed easily. Things can get tricky if you have several applications re-using the same component on the same data source: you might well figure out the component was not designed for this particular deployment model. Things can get even trickier if several applications use different versions of this component on a shared database! A positive example here is jBPM, that you can embed in your application and which will require state persistence: thanks to Hibernate, this runtime dependency will speak the SQL dialect of your existing database, hence will not bring havoc to your application.

  • Service dependencies differ from data ones from several of their characteristics: they promote sharing logic above data, they can encourage loose coupling (but not always: think about EJB clients) and they are generally more concerned with and capable of backwards compatibility. This kind of reusable components, which are often developed in-house, must be carefully crafted to evolve well in space (different deployment environments) and time (different versions). When the grand dream of service auto-discovery and auto-wiring will be fully materialized, these dependencies will become more predictable and manageable. SCA will also play a great role in improving the usability of service dependent components.
Though modern build tools, like Maven, do a great job in dealing with software dependencies, the domain of runtime dependencies is still not yet clearly formalized and fully standardized. Figuring out beforehand these hidden catches and their potential impact on the component reuse you envision can save you some pain.