Modularisation
- Modularisation
- Execution
- Stage Two - Factoring Code Into Modules
- Module Planning Proposals
- Understanding The Modular Build
- Unresolved Issues
- First Cut User Components
Why Modularize?
Improved separation of concerns
Learning code less steep for developers interested in a subset of the total functionality
Enables different modules to depend on different versions of Java
Allows development of experimental modules on trunk. This:
Encourages alternative implementations
Enables branching per module
Simplifies multiple deployment targets
Modules Types
Dependencies between modules will be layered in the obvious way. For example:
Build Modules
Contains code for James modular build
Deployment Modules
Contains code required to deploy James in various container environments
Function Modules
Factors out function from container specific implementations
Library Modules
Factor out common library code reused by functional modules into library modules
API Module
Single module containing the core James API
Execution
Stage One - Prerequisites And Preparation
Before code can be moved out from the phoenix deployment, some prerequisites need to be completed. This will allow the code moves to be planned whilst these are executed. Space needs to be created in the subversion tree by pushing the existing code base down a level. A lightweight ant build framework will be needed to allow efficient creation of modules.
[COMPLETE] Phase 1
Make space for modules within james server trunk
server/trunk -> server/trunk/phoenix-deployment
[COMPLETE] Phase 2
Top level build
create build.xml which delegates to phoenix-deployment/build.xml
[COMPLETE] Phase 3
Upgrade build:
upgrade to ant 1.7 (the new features are *really* good)
create stage subdirectory which is local only
create buildtasks module to host build macros and ant tasks for
module builds
Phase 4
Create empty base module top to contain API interfaces
create macros and tasks to support modular build
create build-modules.xml to support common structure
base builds copies artifacts into stage subdirectory
phoenix build copies artifacts locally from stage
create macros to allow easy generation of new modules
Stage Two - Factoring Code Into Modules
TBD
Recommendations:
Try to avoid splitting packages between modules (good design and also plays well with modern packaging systems)
This may mean that some repackaging is needed. Recommend that this is done in existing code (phoenix) before moving the code out into a module (easier to track code changes).
Phoenix coupling should be factored out in the existing code (phoenix) before moving code out into a module (easier to track code changes)
Module Planning Proposals
Deployment
phoenix-deployment: contains what we currently have in phoenix-bin and the necessary ant task to build our current binary distribution.
spring-deployment
Function
smtpserver
pop3server
fetchmail
remotemanager
nntpserver
imapserver
transport (maybe to be named spoolmanager)
mailetcontainer: to contain the James.java and some of the transport/*loader* stuff.
Library
usersrepository
mailrepository
mailboxmanager
dnsserver
vut
domain
management
API
Need to think about timing of mailet API move
Understanding The Modular Build
Master Build
Adopting some standard naming conventions allows the master build to automatically pick up all modules of a particular type. Subant can then be used to call the same target to all module build files of a particular type. This allows the modular build to automatically maintain the correct build order within needing to know about detailed relationships between modules.
Suggested conventions:
Deployment modules - *deployment for example phoenix-deployment
Function modules - *function for example smtp-function
Library modules - *library for example user-repository-library
API modules = *api for example james-core-api
Module Builds
Minimal Requirements
Deployment Modules
The minimum requirement is for modules to provide an ant build file which:
provides standard targets:
clean
lite
dist
everything
Other Modules
The minimum requirement is for modules to provide an ant build file which:
provides standard targets:
dist
clean
creates artifacts in standard relative position
Standard Module Builds
To reduce maintenance, standard builds will be provided for modules that want to adopt a standard module layout.
Unresolved Issues
Logging
JAMES uses the Avalon framework for logging via AbstractLogEnabled. This introduces a deep coupling between the container and components running in the container that requires resolution.
First Cut User Components
user-api:
User
domain-api:
user-library:
JamesMBean
VirtualUserTableManagementMBean
UserManagementMBean
XMLResources
UsersLDAPRepository
avalon-user-function:
AvalonUsersStore.java
AbstractAvalonStore.java
jdbc-user-function:
JDBCVirtualUserTable