I Winning Strategies

II Start Here

1. Ten Winning Strategies

The following strategies are essential for evolving from a large, monolithic Java class library to a coherent collection of OSGi modules.

  1. Create a large, monolithic wrapper module. Immediately provide existing Java packages to other modules. Create a large, monolithic dependency module. Immediately hide implementation packages.
  2. Move Java source code from Java project to plug-in project.
  3. Create exactly one API module. Create many implementation modules.
  4. Use Test-Driven Development. For every production module, create a corresponding test module. Create the test module first.
  5. Replace custom plug-in mechanism with the OSGi service mechanism. Instead of polling for plug-ins, let plug-ins register themselves. Replace custom class loaders with OSGi class loaders.
  6. Rewrite code incompatible with OSGi. Eliminate polling for resources. Split a package between interface (API) and implementation. Split a package between application programming interface (API) and service provider interface (SPI).
  7. Create a custom Eclipse command. Create batch programs for production and test environments.
  8. Create custom OSGi URL stream handler services.
  9. Release a coherent collection of OSGi modules.
  10. Refine collection of OSGi modules with module refactoring.

Essential strategies are both important and necessary. Without these strategies, you can introduce unnecessary delay. Let’s say that you have a perfectly adequate Java package from an existing Java project. What prevents you from using the package inside an OSGi container?

2. From Package Chaos to Control

Ten strategies help you go from chaos to control.

Package chaos is when you have Java packages in JARs, packages in a WEB-INF/classes directory, packages in JARs in a WEB-INF/lib directory. Package dependencies in your application are unknown and unknowable.

In illustrations throughout this book, a marble (sphere) represents any Java package. The color and design is not significant — except for the fact that it’s different.

Figure 1.1: Package Chaos
Figure 1.1: Package Chaos

Package control is when you move Java packages to modules, using feedback from a production application to drive refactoring. Understand and follow the rules for adding a package to a module, updating a package, dropping a package.

Please notice that I did not say class chaos. While I acknowledge the need for package refactoring, I discuss refactoring of a module, reasons for moving a package from one module to another and putting a package in a specific module. Module design should drive the need for refactoring of a package. One of the fundamental goals of this book is examining an application at a level no lower than a Java package.

3. Only one issue

This document focuses on one issue: Evolving existing software to embrace OSGi. It takes you through a long-term migration process, from having zero (0) modules to having a coherent collection of modules.

  • When I have so many Java packages, where do I start?
  • Understanding four kinds of modules: API, Dependency, Implementation and Wrapper. How many modules do I need? How many Java packages should a module provide? How many API modules do I need?
  • Understanding module refactoring, such as combining two modules and splitting a module. How do I improve module design without starting over? How do I refactor a module, while maintaining backward compatibility with a previous module design and multiple target environments?
  • Understanding how module design affects Java packages, such as splitting a package between API and implementation. How do I identify and fix defects in my existing API design?

4. Assumption

I’m making the following assumptions.

  • JDK 1.6 or higher is already installed and available on your computer. I’m not going to explain how to locate, download and install a JDK.
  • Eclipse Indigo or higher is already installed. I’m not going to help with the installation of Eclipse.
  • This book is focused on the long-term, high-level strategy and tactics of building modules. It is not a step-by-step tutorial on writing Java code so it doesn’t have the typical exercise format of other books in the Essential Training series.
  • If you’re not using Eclipse, that’s fine. I’m confident that you’ll be able to translate between the Eclipse-specific instructions and what you need for your favorite IDE.

5. Featuring CjOS Project

In this document, the primary examples come from volunteer work on the free license and open source CjOS Project (http://cjos.sourceforge.net). CjOS is a platform-independent operating system. It is a co-operating system.

6. Internet-facing production application

The pressure is on. When working on a production application, you need to be able to keep it up and running, 24x7x365. That’s twenty-four hours per day, seven days per week, three hundred and sixty-five days per year. You don’t have time to play around with the theoretical, pure application of OSGi across all of our production applications at the same time.

  • Continue to use your favorite JARs. Using these strategies you can bring a collection of your favorite JARs into the world of OSGi.
  • Continue everyday without business interruption. Using these strategies you can evolve your large, monolithic Java class library to a coherent collection of OSGi modules without business interruption.

7. Limitations

We have at least two limitations when maintaining a flagship product in production environment:

  • Existing Java code, and
  • testing.

7.0.1 Existing Java code

Since we’re talking about a large body of existing Java code, a lot depends on how well the existing Java code is compatible with the OSGi model.

  • Some Java packages are easy for a module to provide. Sometimes, it is a simple matter of adding entries to a manifest file.
  • Some Java packages are difficult, if not impossible, to use inside an OSGi container. A Java package might work outside but not inside an OSGi container.
  • A Java package may need to be refactored. When a Java package doesn’t work inside an OSGi container, it may need to be refactored. What is package refactoring? We explain in a later chapter.

7.0.2 Testing

While you’re under pressure and stress, we want to make sure that you test what needs to be tested. You need to test a feature in its old context, a classic Java application. You need to test a feature in its new context, the OSGi container. Just because a feature works in one context does not mean that it will work in the other.

As the purpose of the object-oriented infrastructure is to increase the chance of success, the purpose of using OSGi is to increase the chance of success when running software.

8. Assumptions

I’m going to assume that you have some knowledge of Java programming and you’re starting out with OSGi. Maybe you’ve read a few books on OSGi and can’t find traction to get started on a migration.

9. Are you stuck?

After reading about the benefits and opportunities of OSGi, I was sold on the idea. I have designed and written custom class loaders. I have designed and written custom plug-in mechanisms. I understand why classic JARs are bad, really bad.

So, why couldn’t I go out and start writing a bunch of new OSGi modules? I was stuck. I asked myself:

  1. Where do I start?
  2. Do I have to rewrite everything?
  3. Do I understand OSGi well enough to make meaningful modules?
  4. How many modules should I plan?
  5. How do I decide which capability goes into which module?
  6. It’s going to be embarrassing if I make a mistake on the internal details of an OSGi module for everyone to see. Am I prepared for failure?

I sit down at my computer. I stare at a blank page and nothing comes out. I do not have a working theory on how to get to where I want to go.

It is as if I have the dreaded disease called writer’s block. I am compelled to write something; but, when I sit down with a blank sheet of paper, I’ve got nothing. I have no idea how to proceed.

10. What this book is not

I don’t want to write a book about how great and wonderful OSGi can be. I don’t want to sell you on the idea of using OSGi for all of your future projects. While I’m enthusiastic about getting OSGi to work at all, I hope that you’ve already been sold on the idea of using OSGi and you want to take the next logical step: Evolving to OSGi.

On the other hand, you may have been given a directive from your boss to “OSGi-ify” some of the existing libraries for your ultra-conservative corporate organization. They want to retain their investment in the existing Java source code and take advantage of the feature of OSGi. They may not know exactly what the features are. OSGi sounds good to someone so they want you to get it to work.

In either case, there are successful and unsuccessful strategies in evolving and embracing OSGi.

What are some of the unsuccessful strategies? We’ll talk about that, too.

11. Evolution vs. Revolution

Software evolution is one way to change software; revolution is another. While they are part of the same spectrum, each has broad implications. They can be mixed together on a case-by-case basis at the macro, minor and micro levels.

Figure 1.2: Evolution
Figure 1.2: Evolution

When you walk, you take steps of a reasonable size. With lots of steps you can walk for miles.

Like human walking, evolution uses a lot of little steps, keeping a production application from interruption due to maintenance. With each iteration, the list of changes is short; the delta is small. In risk assessment, risk is often smaller than revolution.

Figure 1.3: Revolution
Figure 1.3: Revolution

On the other hand, imagine trying to leap from one part of town to another. What would it require? An enormous amount of power. Could you survive the excessive G-force?

In the same way, revolution uses one giant step, replacing a production application. The list of changes is long; the delta is huge. The typical cost is huge because it lacks feedback from real end-users.

Revolution is not always wrong; but, it’s required far less often than evolution.

In other words, you’re unlikely to tear down a house to its foundation in order to remodel a bathroom. You’re unlikely to buy a new car when a tire goes flat. And yet, the software equivalent seems more reasonable at first glance. Don’t replace an entire application to fix one small defect.