How to modularize a (large) Java App?
Maven is painful to migrate to for an existing system. However it can cope with 100+ module projects without much difficulty.
I had a similar experience in a small code base (40 kloc). There are no °rules":
- compiled with and without a "module" in order to see it's usage
- I started from "leaf modules", modules without other dependencies
- I handled cyclic dependencies (this is a very error-prone task)
- with maven there is a great deal with documentation (reports) that can be deployed in your CI process
- with maven you can always see what uses what both in the site both in netbeans (with a
very nice directed graph) - with maven you can import library code in your codebase, apply source patches and compile with your products (sometimes this is very easy sometimes it is very difficult)
Check also Dependency Analyzer:
(source: javalobby.org)
Netbeans:
(source: zimmer428.net)
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.
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 ;)