views:

755

answers:

7

I have a rather large (several MLOC) application at hand that I'd like to split up into more maintainable separate parts. Currently the product is comprised of about 40 Eclipse projects, many of them having inter-dependencies. This alone makes a continuous build system unfeasible, because it would have to rebuild very much with each checkin.

Is there a "best practice" way of how to

  • identify parts that can immediately be separated
  • document inter-dependencies visually
  • untangle the existing code
  • handle "patches" we need to apply to libraries (currently handled by putting them in the classpath before the actual library)

If there are (free/open) tools to support this, I'd appreciate pointers.

Even though I do not have any experience with Maven it seems like it forces a very modular design. I wonder now whether this is something that can be retrofitted iteratively or if a project that was to use it would have to be layouted with modularity in mind right from the start.

Edit 2009-07-10

We are in the process of splitting out some core modules using Apache Ant/Ivy. Really helpful and well designed tool, not imposing as much on you as maven does.

I wrote down some more general details and personal opinion about why we are doing that on my blog - too long to post here and maybe not interesting to everyone, so follow at your own discretion: www.danielschneller.com

A: 

I wouldn't recommend Maven for a legacy source code base. It could give you many headaches just trying to adapt everything to work with it.

I suppose what you need is to do an architectural layout of your project. A tool might help, but the most important part is to organize a logical view of the modules.

kgiannakakis
+5  A: 

Using OSGi could be a good fit for you. It would allow to create modules out of the application. You can also organize dependencies in a better way. If you define your interfaces between the different modules correctly, then you can use continuous integration as you only have to rebuild the module that you affected on check-in.

The mechanisms provided by OSGi will help you untangle the existing code. Because of the way the classloading works, it also helps you handle the patches in an easier way.

Some concepts of OSGi that seem to be a good match for you, as shown from wikipedia:

The framework is conceptually divided into the following areas:

  • Bundles - Bundles are normal jar components with extra manifest headers.
  • Services - The services layer connects bundles in a dynamic way by offering a publish-find-bind model for plain old Java objects(POJO).
  • Services Registry - The API for management services (ServiceRegistration, ServiceTracker and ServiceReference).
  • Life-Cycle - The API for life cycle management (install, start, stop, update, and uninstall bundles).
  • Modules - The layer that defines encapsulation and declaration of dependencies (how a bundle can import and export code).
  • Security - The layer that handles the security aspects by limiting bundle functionality to pre-defined capabilities.
Mario Ortegón
I have used OSGi for a different project already, but right from the start. In the long run this is probably the way I'll try to go. However changing the runtime to an OSGi framework is not something easily done with an app of this magnitude. However taking the necessary steps (MANIFEST.MF) is definitely something that adds value at low cost.
Daniel Schneller
+4  A: 

First: good luck & good coffee. You'll need both.

I once had a similiar problem. Legacy code with awful circular dependencies, even between classes from different packages like org.example.pkg1.A depends on org.example.pk2.B and vice versa.

I started with maven2 and fresh eclipse projects. First I tried to identify the most common functionalities (logging layer, common interfaces, common services) and created maven projects. Each time I was happy with a part, I deployed the library to the central nexus repository so that it was almost immediately available for other projects.

So I slowly worked up through the layers. maven2 handled the dependencies and the m2eclipse plugin provided a helpful dependency view. BTW - it's usually not too difficult to convert an eclipse project into a maven project. m2eclipse can do it for you and you just have to create a few new folders (like src/main/java) and adjust the build path for source folders. Takes just a minute or two. But expect more difficulties, if your project is an eclipse plugin or rcp application and you want maven not only to manage artifacts but also to build and deploy the application.

To opinion, eclipse, maven and nexus (or any other maven repository manager) are a good basis to start. You're lucky, if you have a good documentation of the system architecture and this architecture is really implemented ;)

Andreas_D
+2  A: 
dfa
A: 

Maven is painful to migrate to for an existing system. However it can cope with 100+ module projects without much difficulty.

Peter Lawrey
+1  A: 

The first thing you need to decide is what infra-structure you will move to. Should it be a lot of independently maintained modules (which translates to individual Eclipse projects) or will you consider it a single chunk of code which is versioned and deployed as a whole. The first is well suited for migrating to a Maven like build environment - the latter for having all the source code in at once.

In any case you WILL need a continuous integration system running. Your first task is to make the code base build automatically, so you can let your CI system watch over your source repository and rebuild it whenyou change things. I decided for a non-Maven approach here, and we focus on having an easy Eclipse environment so I created a build enviornment using ant4eclipse and Team ProjectSet files (which we use anyway).

The next step would be getting rid of the circular dependencies - this will make your build simpler, get rid of Eclipse warnings, and eventually allow you to get to the "checkout, compile once, run" stage. This might take a while :-( When you migrate methods and classes, do not MOVE them, but extract or delegate them and leave their old name lying around and mark them deprecated. This will separate your untangeling with your refactoring, and allow code "outside" your project to still work with the code inside your project.

You WILL benefit from a source repository which allows for moving files, and keeping history. CVS is very weak in this regard.

Thorbjørn Ravn Andersen
A: 

It's not free but Structure101 will give you as good as you will get in terms of tool support for hitting all your bullet points. But for the record I'm biased, so you might want to check out SonarJ and Lattix too. ;-)

pth