Distributed James Server — Extending server behavior
Available extension mechanisms
The Distributed Server exposes several interfaces allowing the user to write custom extensions in order to extend the Distributed Server behavior.
Writing Mailets and Matchers allows one to supply custom components for the Mail Processing and enables to take decisions, and implement your business logic at the transport level.
Writing Mailbox listeners enables to react to your user interaction with their mailbox. This powerful tool allows build advanced features for mail delivery servers.
Writing SMTP hookd enables to add features to your SMTP server.
Writing WebAdmin routes enables to add features to the WebAdmin REST API.
Handling injections for your extensions
Injecting core components
You can very easily inject core components into your custom extensions.
All you need is to pass them via a constructor annotated via @Inject.
For instance:
public class MyMailet extends GenericMailet { private final UsersRepository usersRepository; @Inject public MyMailet(UsersRepository usersRepository) { this.usersRepository = usersRepository; } @Override public void service(Mail mail) throws MessagingException { // Do something } }
Injecting simple extension components
Furthermore, concrete implementation, that are part of your extension, can be injected as well.
Consider the following example:
public class MyService { } public class MyMailet extends GenericMailet { private final MyService myService; @Inject public MyMailet(MyService myService) { this.usersRepository = myService; } @Override public void service(Mail mail) throws MessagingException { // Do something } }
Defining custom injections for your extensions
However, to inject an interface into your extension, you will need additional injection definitions.
To to so:
-
1. Given an interface defined in a additional JAR:
public interface MyService {}
-
2. And an implementation of that interface, in another additional JAR:
public class MyServiceImpl extends MyService {}
-
3. We need to define a binding for MyService to be bound to MyServiceImpl
public class MyServiceModule extends AbstractModule { @Override protected void configure() { bind(MyServiceImpl.class).in(Scopes.SINGLETON); bind(MyService.class).to(MyServiceImpl.class); } }
Both MyService, MyServiceImpl and MyServiceModule needs to be in the extensions-jars folder (potentially different jars).
-
4. MyServiceModule needs to be registered in extensions.properties
-
5. MyService can then be used as part of your extensions
public class MyMailet extends GenericMailet { private final MyService myService; @Inject public MyMailet(MyService myService) { this.usersRepository = myService; } @Override public void service(Mail mail) throws MessagingException { // Do something } }
Note that overriding injection definitions of the Distributed Server for your injections is not supported.