2011년 12월 12일 월요일

[DeveloperWorks] Developing enterprise OSGi applications for WebSphere Application Server

Developing enterprise OSGi applications for WebSphere Application Server


Summary:
Creating modular, extensible Web applications using standard Java™ EE deployment has its challenges, but can generally be accomplished with good design practices and discipline. Where it gets really hard, though, is when you want to separate out common modules to share between multiple enterprise applications, or use multiple versions of common libraries at the same time. OSGi is a Java modularity technology that has been used internally in IBM® WebSphere® Application Server and the Eclipse platform for many years, and was designed to enable the development and execution of dynamic, modular, extensible applications. The WebSphere Application Server V7 Feature Pack for OSGi Applications and JPA 2.0 enables modular enterprise applications to use OSGi directly to dramatically simplify their development, assembly, and deployment. The feature pack also provides an infrastructure in which modular design is no longer just a best practice but is the only practice. This content is part of the IBM WebSphere Developer Technical Journal.


The vast majority of the cost associated with software development is not related to the initial design, development, and test of a new application -- although these can be expensive -- but to the maintenance and evolution of the application thereafter.
Designing and building applications and suites of applications from coherent, versioned, reusable modules accessed only through well-defined interfaces reduces complexity and provides the greatest flexibility to maintain and evolve the software after its first release. A modular design, in which the modules offer well-defined services and interfaces, enables large-scale projects to be divided between teams who can focus on their own tasks without having to understand the details of the other teams' code beyond the agreed externals, reducing the breadth of complexity for each team and improving the time to delivery. In addition, the cost of application maintenance is reduced by minimizing the scope of the impact of any changes to the application -- assuming that scope can be determined. If a change to a module affects only its internals, with no impact to its external contract, then maintenance can be applied to a single isolated module and testing can be better targeted. This should all be self-evident, but we could benefit from some active help from our development tools and run time infrastructure to support such a modular design approach. For example, wouldn't it be nice to have an easier way to deploy and maintain common code that is used by multiple EARs?
First of all, what makes a good module?
  • A module should provide a coherent logical function and should be sufficiently self-contained that it represents a practical "unit of reuse."
  • A module should be loosely-coupled to other modules through well-defined external interfaces and dependencies.
  • A module should isolate its internals from other modules so that changes to the internal behavior of a module have no impact on any other modules
Java classes are typically too fine-grained to form a logical unit of re-use between applications, their isolation focus being primarily limited to the encapsulation of instance data. Classes are usually packaged inside a JAR file that represents a coherent function. As the unit of deployment (and as the artifact that exists in the file system), the JAR is a very practical unit of reuse but it lacks some of the other characteristics of a good module.
Consider visibility: if you have a method in a class in package foo.bar that needs to be available to a class in package bar.foo, then you need to declare that method with a public access modifier. You have no way to indicate whether this method should or should not also be available to classes outside the JAR. You can apply conventions and best practices. You can organize your interfaces into external and internal packages using a package-naming convention. For example, WebSphere Application Server interfaces intended for use by applications are contained in sub-packages of com.ibm.websphere or com.ibm.wsspi, whereas internal interfaces not intended for application use are mostly in sub-packages of com.ibm.ws. If different teams working on different modules within a project are disciplined about the definition and use of module externals, then these modules will remain coupled only through the defined externals. Of course, there's always that little bit of plus-plus function in your module that you couldn't live without, but isn't part of the module interface. So when another team finds out how much this will make their lives better too, what’s the harm in letting them go ahead and use it? After all, you all work on the same overall project and the methods they'd use all have public Java accessibility, so it wouldn't need code changes to agree to let them use it -- if they bothered to ask. And now, without meaning to, you've broken the desired loose-coupling between bundles. The "scope of impact" of a change to your bundle's internals might now extend beyond your bundle, which makes it harder to figure out what might be affected and, therefore, what needs to be tested.

댓글 없음:

댓글 쓰기