| = How the James code base is organised |
| :navtitle: Code base organisation |
| |
| Apache James is not a single application but a *set of components* that get assembled into one. The servers |
| documented in xref:servers:index.adoc[the servers section] are precisely such assemblies: the same mailbox, the |
| same protocol implementations and the same mailet container, wired onto different storage backends. This page maps |
| the repository so that you know where to look, and where a change belongs. |
| |
| == The three kinds of module |
| |
| Every module of the repository falls into one of three categories, and the dependency rules between them are what |
| keeps the project assemblable: |
| |
| API:: |
| Interfaces and value objects, with no implementation detail and next to no dependency. `mailet/api`, |
| `mailbox/api`, `protocols/api`, `metrics/metrics-api`, `event-bus/api` are the ones you will meet most often. An |
| API module must stay implementable by a backend that does not exist yet. |
| |
| Library:: |
| Reusable code that depends only on API modules and on third party jars, never on another library. `mailet/base` |
| and `core` are examples. A library is justified only when several functions share it. |
| |
| Function:: |
| Everything else - an implementation of an API, a protocol, a storage backend. Functions should depend on APIs and |
| libraries, and as little as possible on each other: it is code reuse that is expected between them, not direct |
| reuse of a jar. |
| |
| The practical consequence is that a new storage backend is written by implementing the API modules, without |
| touching anything else, and is then wired into an application by a Guice module. |
| |
| == The main modules |
| |
| `core`:: |
| The domain objects shared by everything: `Username`, `Domain`, `MailAddress`, `MaybeSender`, and the `Mail` |
| implementation itself. |
| |
| `mailet`:: |
| The link:https://james.apache.org/mailet/api/[Mailet API] - `Mailet`, `Matcher`, `MailetConfig` - in |
| `mailet/api`, the `GenericMailet` toolkit in `mailet/base`, and the packaged mailets and matchers in |
| `mailet/standard`, `mailet/crypto` (S/MIME), `mailet/icalendar` and `mailet/amqp`. `mailet/mailetdocs-maven-plugin` |
| extracts the javadoc of those classes into the reference lists you can read in the |
| xref:servers:distributed/configure/mailets.adoc[configuration pages]. |
| |
| `mailbox`:: |
| The storage of the emails. `mailbox/api` defines `MailboxManager`, `MessageManager` and `SubscriptionManager`; |
| `mailbox/store` holds the backend agnostic logic built on top of a set of mappers; and one module per backend |
| implements those mappers - `mailbox/cassandra`, `mailbox/postgres`, `mailbox/jpa`, `mailbox/memory`. Search is |
| pluggable the same way: `mailbox/opensearch`, `mailbox/lucene` and `mailbox/scanning-search`. |
| |
| `protocols`:: |
| The protocol implementations, kept independent of the mailbox: `protocols/smtp`, `protocols/imap`, |
| `protocols/pop3`, `protocols/lmtp`, `protocols/managesieve`, the SASL mechanisms in `protocols/sasl`, and the |
| Netty plumbing they share in `protocols/netty`. |
| |
| `server`:: |
| The server itself. `server/data` holds the users, domains, rewriting rules and mail repositories, again with one |
| module per backend; `server/mailet` the mailet container; `server/queue` the mail queue implementations; |
| `server/protocols` the glue binding the protocol implementations to the mailbox, and the WebAdmin routes; |
| `server/container` the Guice and Spring wiring; and `server/apps` the assemblies that make up the shipped |
| applications. |
| |
| `backends-common`:: |
| The low level clients of the storage dependencies - Cassandra, Postgres, OpenSearch, RabbitMQ, Redis, Pulsar - |
| along with the test resources that start them in a container. |
| |
| `event-bus`, `event-sourcing`, `json`, `metrics`, `mdn`:: |
| Cross cutting infrastructure: event distribution, event sourced aggregates, JSON serialisation, metric collection, |
| message disposition notifications. |
| |
| `mpt`:: |
| The Mail Protocols Tester, a scripted protocol testing framework used to check the IMAP and SMTP implementations |
| against recorded sessions. See xref:deployment-tests.adoc[running deployment tests]. |
| |
| `examples`:: |
| Working examples of every extension mechanism - custom mailets, matchers, SMTP hooks, mailbox listeners, WebAdmin |
| routes - each one a small maven project you can copy. The |
| xref:servers:distributed/customization/index.adoc[customization section] walks through them. |
| |
| == Standards compliance |
| |
| James implements published standards, most of them IETF RFCs, and treats them as its requirements document: what |
| each server implements is listed on its *implemented standards* page - |
| xref:servers:distributed/architecture/implemented-standards.adoc[Distributed], |
| xref:servers:postgres/architecture/implemented-standards.adoc[Postgres], |
| xref:servers:jpa/architecture/implemented-standards.adoc[JPA], |
| xref:servers:spring/architecture/implemented-standards.adoc[Spring]. |
| |
| This occasionally conflicts with what other implementations actually do. The project's position is that adhering |
| to the published standard is what makes interoperability achievable without access to undocumented behaviour, and |
| therefore: |
| |
| * a deviation from a standard, when it is needed and can be worked around safely, is *disabled by default*, |
| prominently documented as a violation, and enabled by an explicit configuration option - so that using it is a |
| conscious decision of the operator; |
| * a behaviour that no standard James claims to support covers - a de-facto convention, a draft RFC - may be |
| implemented, provided it is documented well enough that operators know what to expect. |