This is an automated email from the ASF dual-hosted git repository.

jhelou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new a06577193f [JAMES-4128] improves Mailet config encapsulation
a06577193f is described below

commit a06577193f2f729c040c9449040d4c9a90b824a6
Author: Matthieu Baechler <matth...@baechler-craftsmanship.fr>
AuthorDate: Tue Mar 25 16:59:01 2025 +0100

    [JAMES-4128] improves Mailet config encapsulation
    
    The mailet configuration is injected from the mailet container, exposing it 
back publicly breaks encapsulation.
    
    We propose to remove the `getMailetConfig` method ( yes this is a breaking 
api change ) and add 1 method to the interface to clarify the contract:
    
    `String getName()` returns the name of the mailet. a default implementation 
is `GenericMailet#getMailetName()` though we want to avoid repeating `Mailet` 
in the interface.
---
 CHANGELOG.md                                       |  7 +-
 .../src/main/java/org/apache/mailet/Mailet.java    | 21 ++----
 .../java/org/apache/mailet/base/GenericMailet.java |  5 +-
 .../mailet/constructor/ConstructorMailet.java      |  5 --
 .../excluded/ExcludedFromDocumentationMailet.java  |  5 --
 .../NotExcludedFromDocumentationMailet.java        |  5 --
 .../mailet/experimental/ExperimentalMailet.java    |  5 --
 .../mailet/experimental/NonExperimentalMailet.java |  5 --
 .../modules/server/MailetContainerModule.java      | 65 ++++++++++--------
 .../mailets/sub/ConstructorBoundTestMailet.java    |  4 +-
 .../apache/james/utils/GuiceMailetLoaderTest.java  |  2 +-
 .../api/mock/ExceptionThrowingMailet.java          |  4 +-
 .../james/mailetcontainer/api/mock/MockMailet.java |  4 +-
 .../mailetcontainer/impl/MailetProcessorImpl.java  |  2 +-
 .../mailetcontainer/impl/MatcherMailetPair.java    | 31 ++++++---
 .../mailetcontainer/impl/MatcherSplitter.java      |  3 +-
 .../james/mailetcontainer/impl/ProcessorImpl.java  | 29 ++++----
 .../impl/jmx/JMXStateMailetProcessorListener.java  | 14 +++-
 .../mailetcontainer/impl/jmx/MailetManagement.java | 29 ++++----
 .../lib/AbstractStateCompositeProcessor.java       | 21 +++---
 .../lib/AbstractStateMailetProcessor.java          | 11 ++-
 .../MailProcessingErrorHandlingConfiguration.java} | 79 ++++++++++------------
 .../impl/MailetProcessorImplTest.java              | 27 ++++----
 .../lib/AbstractStateMailetProcessorTest.java      | 77 ++++++++++++---------
 .../james/samples/mailets/HelloWorldMailet.java    |  8 +--
 .../samples/mailets/InstrumentationMailet.java     |  8 +--
 upgrade-instructions.md                            | 13 ++++
 27 files changed, 259 insertions(+), 230 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index dfd2fbdd80..841006b8ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,7 +10,9 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/)
  - Upgrade javax -> jakarta. See releated upgrade instructions.
  - Upgrade Java 11 -> 21. See related upgrade instructions.
  - API change: CassandraModule and all associated Cassandra*Module were 
renamed to CassandraDataDefinition and Cassandra*DataDefinition respectively.
-
+ - API change : Mailet API has been cleaned up and no longer exposes the 
mailet config, exposing only the mailet's name instead.
+ - API change : GenericMailet can have its config bound by constructor and 
this is the preferred way to initialize your mailets. `init` is still called 
but will eventually be removed in a later release. 
+ 
 ### Removals
 
  - JAMES-3946 WhiteList manager removals (#2299)
@@ -82,7 +84,8 @@ Please use RFC-8621 implementation rather than this outdated 
draft.
 - JAMES-3824 SMTP Extension for Message Transfer Priorities
 
 ### Improvements
-
+ 
+ - JAMES-4125 rework mailet api
  - JAMES-4123 Renames CassandraModule to CassandraDataDefinition
  - JAMES-4103 Allow customizing MessageParser
  - JAMES-3967 RelayLimit: add error log
diff --git a/mailet/api/src/main/java/org/apache/mailet/Mailet.java 
b/mailet/api/src/main/java/org/apache/mailet/Mailet.java
index f59fc8b9dd..b9743da23c 100644
--- a/mailet/api/src/main/java/org/apache/mailet/Mailet.java
+++ b/mailet/api/src/main/java/org/apache/mailet/Mailet.java
@@ -42,10 +42,7 @@ import com.google.common.collect.ImmutableList;
  * </ol>
  * <p>
  * In addition to the life-cycle methods, this interface provides the
- * {@link #getMailetConfig} method, which provides the Mailet with
- * its initialization parameters and a {@link MailetContext} through which
- * it can interact with the mailet container, and the {@link #getMailetInfo}
- * method, which provides basic information about the Mailet.
+ * {@link #getMailetInfo} method, which provides basic information about the 
Mailet.
  * <p>
  * Mailets are grouped by the mailet container's configuration into processors.
  * Each processor is comprised of an ordered sequence of Mailets, each with a
@@ -114,18 +111,12 @@ public interface Mailet {
     }
 
     /**
-     * Returns a MailetConfig object, which provides initialization parameters
-     * and a {@link MailetContext} through which it can interact with the
-     * mailet container.
-     * <p>
-     * Implementations of this interface are responsible for storing the
-     * MailetConfig which they receive in the {@link #init} method so
-     * that this method can return it.
-     *
-     * @return the MailetConfig that this mailet was initialized with
+     * @return mailet name
      */
-    MailetConfig getMailetConfig();
-    
+    default String getName() {
+        return this.getClass().getSimpleName();
+    }
+
     /**
      * Returns information about the mailet, such as author, version and
      * copyright.
diff --git 
a/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java 
b/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
index 3f12f4bf22..cac316e745 100644
--- a/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
+++ b/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
@@ -177,7 +177,6 @@ public abstract class GenericMailet implements Mailet, 
MailetConfig {
      *
      * @return the MailetConfig object that initialized this mailet
      */
-    @Override
     public MailetConfig getMailetConfig() {
         return config;
     }
@@ -204,6 +203,10 @@ public abstract class GenericMailet implements Mailet, 
MailetConfig {
         return config.getMailetName();
     }
 
+    @Override
+    public String getName() {
+        return getMailetName();
+    }
 
     /**
      * <p>Called by the mailet container to indicate to a mailet that the
diff --git 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/constructor/ConstructorMailet.java
 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/constructor/ConstructorMailet.java
index 905ef7b08b..9f6fcc76f1 100644
--- 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/constructor/ConstructorMailet.java
+++ 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/constructor/ConstructorMailet.java
@@ -44,11 +44,6 @@ public class ConstructorMailet implements Mailet {
     public void destroy() {
     }
 
-    @Override
-    public MailetConfig getMailetConfig() {
-        return null;
-    }
-
     @Override
     public String getMailetInfo() {
         return "info";
diff --git 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/ExcludedFromDocumentationMailet.java
 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/ExcludedFromDocumentationMailet.java
index bc69216455..a728ab0e49 100644
--- 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/ExcludedFromDocumentationMailet.java
+++ 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/ExcludedFromDocumentationMailet.java
@@ -41,11 +41,6 @@ public class ExcludedFromDocumentationMailet implements 
Mailet {
     public void destroy() {
     }
 
-    @Override
-    public MailetConfig getMailetConfig() {
-        return null;
-    }
-
     @Override
     public String getMailetInfo() {
         return null;
diff --git 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/NotExcludedFromDocumentationMailet.java
 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/NotExcludedFromDocumentationMailet.java
index 46405f0daa..7195d76b35 100644
--- 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/NotExcludedFromDocumentationMailet.java
+++ 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/NotExcludedFromDocumentationMailet.java
@@ -39,11 +39,6 @@ public class NotExcludedFromDocumentationMailet implements 
Mailet {
     public void destroy() {
     }
 
-    @Override
-    public MailetConfig getMailetConfig() {
-        return null;
-    }
-
     @Override
     public String getMailetInfo() {
         return null;
diff --git 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/ExperimentalMailet.java
 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/ExperimentalMailet.java
index 09fe15d9e1..dba296dd63 100644
--- 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/ExperimentalMailet.java
+++ 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/ExperimentalMailet.java
@@ -41,11 +41,6 @@ public class ExperimentalMailet implements Mailet {
     public void destroy() {
     }
 
-    @Override
-    public MailetConfig getMailetConfig() {
-        return null;
-    }
-
     @Override
     public String getMailetInfo() {
         return null;
diff --git 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/NonExperimentalMailet.java
 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/NonExperimentalMailet.java
index 107cfcc57a..db9fc08c74 100644
--- 
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/NonExperimentalMailet.java
+++ 
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/NonExperimentalMailet.java
@@ -39,11 +39,6 @@ public class NonExperimentalMailet implements Mailet {
     public void destroy() {
     }
 
-    @Override
-    public MailetConfig getMailetConfig() {
-        return null;
-    }
-
     @Override
     public String getMailetInfo() {
         return null;
diff --git 
a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/MailetContainerModule.java
 
b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/MailetContainerModule.java
index e6ef0a8e9b..9a7120f49b 100644
--- 
a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/MailetContainerModule.java
+++ 
b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/MailetContainerModule.java
@@ -60,6 +60,7 @@ import org.apache.mailet.Mailet;
 import org.apache.mailet.MailetContext;
 import org.apache.mailet.Matcher;
 import org.apache.mailet.base.AutomaticallySentMailDetector;
+import org.apache.mailet.base.GenericMailet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -83,11 +84,19 @@ public class MailetContainerModule extends AbstractModule {
     private static final boolean MAILET_CONTAINER_CHECK_ENABLED = 
Boolean.parseBoolean(System.getProperty("james.mailet.container.check.enabled", 
"true"));
 
     public static final ProcessorsCheck.Impl BCC_Check = new 
ProcessorsCheck.Impl(
-        "transport",
-        All.class,
-        RemoveMimeHeader.class,
-        pair -> 
Arrays.asList(pair.getMailet().getMailetConfig().getInitParameter("name").toLowerCase().split(",")).contains("bcc"),
-        "Should be configured to remove Bcc header");
+            "transport",
+            All.class,
+            RemoveMimeHeader.class,
+            pair -> {
+                if (pair.getMailet() instanceof GenericMailet genericMailet) {
+                    return Arrays
+                            
.asList(genericMailet.getMailetConfig().getInitParameter("name").toLowerCase().split(","))
+                            .contains("bcc");
+                } else {
+                    return false;
+                }
+            },
+            "Should be configured to remove Bcc header");
 
     @Override
     protected void configure() {
@@ -128,7 +137,7 @@ public class MailetContainerModule extends AbstractModule {
     private HierarchicalConfiguration<ImmutableNode> 
getJamesSpoolerConfiguration(ConfigurationProvider configurationProvider) {
         try {
             return configurationProvider.getConfiguration("mailetcontainer")
-                .configurationAt("spooler");
+                    .configurationAt("spooler");
         } catch (Exception e) {
             LOGGER.warn("Could not locate configuration for James Spooler. 
Assuming empty configuration for this component.");
             return new BaseHierarchicalConfiguration();
@@ -138,8 +147,8 @@ public class MailetContainerModule extends AbstractModule {
     @ProvidesIntoSet
     InitializationOperation initMailetContext(ConfigurationProvider 
configurationProvider, JamesMailetContext mailetContext) {
         return InitilizationOperationBuilder
-            .forClass(JamesMailetContext.class)
-            .init(() -> 
mailetContext.configure(getMailetContextConfiguration(configurationProvider)));
+                .forClass(JamesMailetContext.class)
+                .init(() -> 
mailetContext.configure(getMailetContextConfiguration(configurationProvider)));
     }
 
     @VisibleForTesting
@@ -206,19 +215,19 @@ public class MailetContainerModule extends AbstractModule 
{
 
         private void checkProcessors() throws ConfigurationException {
             ImmutableListMultimap<String, MatcherMailetPair> processors = 
Arrays.stream(compositeProcessorImpl.getProcessorStates())
-                .flatMap(state -> {
-                    MailProcessor processor = 
compositeProcessorImpl.getProcessor(state);
-                    if (processor instanceof MailetProcessorImpl) {
-                        MailetProcessorImpl camelProcessor = 
(MailetProcessorImpl) processor;
-                        return camelProcessor.getPairs().stream()
-                            .map(pair -> Pair.of(state, pair));
-                    } else {
-                        throw new RuntimeException("Can not perform checks as 
transport processor is not an instance of " + MailProcessor.class);
-                    }
-                })
-                .collect(ImmutableListMultimap.toImmutableListMultimap(
-                    Pair::getKey,
-                    Pair::getValue));
+                    .flatMap(state -> {
+                        MailProcessor processor = 
compositeProcessorImpl.getProcessor(state);
+                        if (processor instanceof MailetProcessorImpl) {
+                            MailetProcessorImpl camelProcessor = 
(MailetProcessorImpl) processor;
+                            return camelProcessor.getPairs().stream()
+                                    .map(pair -> Pair.of(state, pair));
+                        } else {
+                            throw new RuntimeException("Can not perform checks 
as transport processor is not an instance of " + MailProcessor.class);
+                        }
+                    })
+                    .collect(ImmutableListMultimap.toImmutableListMultimap(
+                            Pair::getKey,
+                            Pair::getValue));
             for (ProcessorsCheck check : processorsCheckSet) {
                 check.check(processors);
             }
@@ -283,7 +292,7 @@ public class MailetContainerModule extends AbstractModule {
                 this(processorName, matcherClass, mailetClass, 
Optional.empty(), Optional.empty());
             }
 
-            public Impl(String processorName, Class<? extends Matcher> 
matcherClass, Class<? extends Mailet> mailetClass, Predicate<? super 
MatcherMailetPair> additionalFilter, String additionalErrorMessage) {
+            public Impl(String processorName, Class<? extends Matcher> 
matcherClass, Class<? extends GenericMailet> mailetClass, Predicate<? super 
MatcherMailetPair> additionalFilter, String additionalErrorMessage) {
                 this(processorName, matcherClass, mailetClass, 
Optional.of(additionalFilter), Optional.of(additionalErrorMessage));
             }
 
@@ -303,12 +312,12 @@ public class MailetContainerModule extends AbstractModule 
{
                 }
                 Preconditions.checkNotNull(pairs);
                 pairs.stream()
-                    .filter(pair -> 
pair.getMailet().getClass().equals(mailetClass))
-                    .filter(pair -> 
pair.getMatcher().getClass().equals(matcherClass))
-                    .filter(additionalFilter.orElse(any -> true))
-                    .findAny()
-                    .orElseThrow(() -> new ConfigurationException("Missing " + 
mailetClass.getName() + " in mailets configuration (mailetcontainer -> 
processors -> " + processorName + "). " +
-                        additionalErrorMessage.orElse("")));
+                        .filter(pair -> 
pair.getMailet().getClass().equals(mailetClass))
+                        .filter(pair -> 
pair.getMatcher().getClass().equals(matcherClass))
+                        .filter(additionalFilter.orElse(any -> true))
+                        .findAny()
+                        .orElseThrow(() -> new ConfigurationException("Missing 
" + mailetClass.getName() + " in mailets configuration (mailetcontainer -> 
processors -> " + processorName + "). " +
+                                additionalErrorMessage.orElse("")));
             }
         }
     }
diff --git 
a/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
 
b/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
index ed582c04c1..a05fae1f69 100644
--- 
a/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
+++ 
b/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
@@ -40,7 +40,7 @@ public class ConstructorBoundTestMailet implements Mailet {
     }
 
     @Override
-    public MailetConfig getMailetConfig() {
-        return config;
+    public String getName() {
+        return config.getMailetName();
     }
 }
diff --git 
a/server/container/guice/mailet/src/test/java/org/apache/james/utils/GuiceMailetLoaderTest.java
 
b/server/container/guice/mailet/src/test/java/org/apache/james/utils/GuiceMailetLoaderTest.java
index 792955cd0a..b8591e2a33 100644
--- 
a/server/container/guice/mailet/src/test/java/org/apache/james/utils/GuiceMailetLoaderTest.java
+++ 
b/server/container/guice/mailet/src/test/java/org/apache/james/utils/GuiceMailetLoaderTest.java
@@ -68,7 +68,7 @@ class GuiceMailetLoaderTest {
             .build());
 
         assertThat(mailet).isInstanceOf(ConstructorBoundTestMailet.class);
-        assertThat(mailet.getMailetConfig()).isNotNull();
+        
assertThat(mailet.getName()).isEqualTo("sub.ConstructorBoundTestMailet");
     }
 
     @Test
diff --git 
a/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/ExceptionThrowingMailet.java
 
b/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/ExceptionThrowingMailet.java
index 61b98ce44d..2763c042e6 100644
--- 
a/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/ExceptionThrowingMailet.java
+++ 
b/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/ExceptionThrowingMailet.java
@@ -33,8 +33,8 @@ public class ExceptionThrowingMailet implements Mailet {
     }
 
     @Override
-    public MailetConfig getMailetConfig() {
-        return config;
+    public String getName() {
+        return config.getMailetName();
     }
 
     @Override
diff --git 
a/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/MockMailet.java
 
b/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/MockMailet.java
index 1e128f34ea..c673577831 100644
--- 
a/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/MockMailet.java
+++ 
b/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/MockMailet.java
@@ -31,8 +31,8 @@ public class MockMailet implements Mailet {
     }
 
     @Override
-    public MailetConfig getMailetConfig() {
-        return config;
+    public String getName() {
+        return config.getMailetName();
     }
 
     @Override
diff --git 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MailetProcessorImpl.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MailetProcessorImpl.java
index e1440a52ab..a76e164c43 100644
--- 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MailetProcessorImpl.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MailetProcessorImpl.java
@@ -202,7 +202,7 @@ public class MailetProcessorImpl extends 
AbstractStateMailetProcessor {
             this.pairs = pairs;
             this.pairsToBeProcessed = pairs.stream()
                 .map(pair -> Pair.of(new MatcherSplitter(metricFactory, this, 
pair),
-                    new ProcessorImpl(metricFactory, this, pair.getMailet())))
+                    new ProcessorImpl(metricFactory, pair.getMailet(), 
pair.processingErrorConfig(), this.getListeners())))
                 .collect(ImmutableMap.toImmutableMap(Pair::getKey, 
Pair::getValue));
         } catch (Exception e) {
             throw new MessagingException("Unable to setup routing for 
MailetMatcherPairs", e);
diff --git 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherMailetPair.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherMailetPair.java
index b2d1540239..1d8585ab31 100644
--- 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherMailetPair.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherMailetPair.java
@@ -18,24 +18,30 @@
  ****************************************************************/
 package org.apache.james.mailetcontainer.impl;
 
+import java.util.Optional;
+
+import 
org.apache.james.mailetcontainer.lib.MailProcessingErrorHandlingConfiguration;
 import org.apache.mailet.Mailet;
 import org.apache.mailet.Matcher;
 
+import com.google.common.annotations.VisibleForTesting;
+
 /**
  * A pair of {@link Matcher} and {@link Mailet}
  */
-public class MatcherMailetPair {
-    private final Matcher matcher;
-    private final Mailet mailet;
-
+public record MatcherMailetPair(
+        Matcher matcher,
+        Mailet mailet,
+        MailProcessingErrorHandlingConfiguration processingErrorConfig
+) {
+    @VisibleForTesting
     public MatcherMailetPair(Matcher matcher, Mailet mailet) {
-        this.matcher = matcher;
-        this.mailet = mailet;
+        this(matcher, mailet, 
MailProcessingErrorHandlingConfiguration.empty());
     }
 
     /**
      * Return the {@link Matcher} of this pair
-     * 
+     *
      * @return matcher
      */
     public Matcher getMatcher() {
@@ -44,16 +50,19 @@ public class MatcherMailetPair {
 
     /**
      * Return the {@link Mailet} of this pair
-     * 
+     *
      * @return mailet
      */
     public Mailet getMailet() {
         return mailet;
     }
 
-    public String getOnMatchException() {
-        return mailet.getMailetConfig()
-            .getInitParameter("onMatchException");
+    public Optional<String> onMatchException() {
+        return processingErrorConfig.onMatchException();
+    }
+
+    public Optional<String> onMailetException() {
+        return processingErrorConfig.onMailetException();
     }
 
 }
diff --git 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
index 84d3564a97..9e872bd675 100644
--- 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Locale;
-import java.util.Optional;
 
 import jakarta.mail.MessagingException;
 
@@ -63,7 +62,7 @@ public class MatcherSplitter {
         this.metricFactory = metricFactory;
         this.container = container;
         this.matcher = pair.getMatcher();
-        this.onMatchException = Optional.ofNullable(pair.getOnMatchException())
+        this.onMatchException = pair.onMatchException()
             .map(s -> s.trim().toLowerCase(Locale.US))
             .orElse(Mail.ERROR);
     }
diff --git 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
index 2fe5c0e80d..416f284e5a 100644
--- 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Locale;
 
 import 
org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor.MailetProcessorListener;
+import 
org.apache.james.mailetcontainer.lib.MailProcessingErrorHandlingConfiguration;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.metrics.api.TimeMetric;
 import org.apache.james.util.MDCBuilder;
@@ -30,7 +31,6 @@ import org.apache.mailet.Attribute;
 import org.apache.mailet.AttributeValue;
 import org.apache.mailet.Mail;
 import org.apache.mailet.Mailet;
-import org.apache.mailet.MailetConfig;
 import org.apache.mailet.base.MailetPipelineLogging;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,12 +44,19 @@ public class ProcessorImpl {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(ProcessorImpl.class);
 
     private final MetricFactory metricFactory;
+    private final MailProcessingErrorHandlingConfiguration 
processingErrorHandlingConfiguration;
+    private final List<MailetProcessorListener> listeners;
     private final Mailet mailet;
-    private final MailetProcessorImpl processor;
 
-    public ProcessorImpl(MetricFactory metricFactory, MailetProcessorImpl 
processor, Mailet mailet) {
+    public ProcessorImpl(
+            MetricFactory metricFactory,
+            Mailet mailet,
+            MailProcessingErrorHandlingConfiguration 
processingErrorHandlingConfiguration,
+            List<MailetProcessorListener> listeners
+    ) {
         this.metricFactory = metricFactory;
-        this.processor = processor;
+        this.processingErrorHandlingConfiguration = 
processingErrorHandlingConfiguration;
+        this.listeners = listeners;
         this.mailet = mailet;
     }
 
@@ -81,17 +88,8 @@ public class ProcessorImpl {
             mailet.service(mail);
         } catch (Throwable me) {
             ex = me;
-            String onMailetException = null;
+            String onMailetException = 
processingErrorHandlingConfiguration.onMailetException().map(value -> 
value.trim().toLowerCase(Locale.US)).orElse(Mail.ERROR);
 
-            MailetConfig mailetConfig = mailet.getMailetConfig();
-            if (mailetConfig instanceof MailetConfigImpl) {
-                onMailetException = 
mailetConfig.getInitParameter("onMailetException");
-            }
-            if (onMailetException == null) {
-                onMailetException = Mail.ERROR;
-            } else {
-                onMailetException = 
onMailetException.trim().toLowerCase(Locale.US);
-            }
             if (onMailetException.equalsIgnoreCase("ignore")) {
                 // ignore the exception and continue
                 // this option should not be used if the mail object can be
@@ -101,13 +99,12 @@ public class ProcessorImpl {
             } else if (onMailetException.equalsIgnoreCase("propagate")) {
                 throw me;
             } else {
-                ProcessorUtil.handleException(me, mail, 
mailet.getMailetConfig().getMailetName(), onMailetException, LOGGER);
+                ProcessorUtil.handleException(me, mail, mailet.getName(), 
onMailetException, LOGGER);
             }
 
         } finally {
             timeMetric.stopAndPublish();
             MailetPipelineLogging.logEndOfMailetProcess(mailet, mail);
-            List<MailetProcessorListener> listeners = processor.getListeners();
             long complete = System.currentTimeMillis() - start;
             if (mail.getRecipients().isEmpty()) {
                 mail.setState(Mail.GHOST);
diff --git 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
index bc4bdbc09f..028ea14451 100644
--- 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
@@ -25,9 +25,11 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 import javax.management.JMException;
 import javax.management.MBeanServer;
+import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectName;
 
 import org.apache.james.core.MailAddress;
@@ -36,7 +38,9 @@ import 
org.apache.james.mailetcontainer.impl.matchers.CompositeMatcher;
 import org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor;
 import 
org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor.MailetProcessorListener;
 import org.apache.mailet.Mailet;
+import org.apache.mailet.MailetConfig;
 import org.apache.mailet.Matcher;
+import org.apache.mailet.base.GenericMailet;
 
 /**
  * {@link MailetProcessorListener} implementation which register MBean's for 
all
@@ -98,7 +102,7 @@ public class JMXStateMailetProcessorListener implements 
MailetProcessorListener,
         int i = 0;
         while (mailets.hasNext()) {
             Mailet mailet = mailets.next();
-            MailetManagement mailetManagement = new 
MailetManagement(mailet.getMailetConfig());
+            MailetManagement mailetManagement = new 
MailetManagement(getOptionalMailetConfig(mailet), mailet.getName());
 
             String mailetMBeanName = parentMBeanName + 
",subtype=mailet,index=" + (i++) + ",mailetname=" + 
mailetManagement.getMailetName();
             registerMBean(mailetMBeanName, mailetManagement);
@@ -107,6 +111,14 @@ public class JMXStateMailetProcessorListener implements 
MailetProcessorListener,
 
     }
 
+    private Optional<MailetConfig> getOptionalMailetConfig(Mailet mailet) 
throws NotCompliantMBeanException {
+        if (mailet instanceof GenericMailet m) {
+            return Optional.ofNullable(m.getMailetConfig());
+        } else {
+            return Optional.empty();
+        }
+    }
+
     /**
      * Register the {@link Matcher}'s as JMX MBeans
      */
diff --git 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/MailetManagement.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/MailetManagement.java
index 5ae817124d..9b48e4b08d 100644
--- 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/MailetManagement.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/MailetManagement.java
@@ -21,6 +21,7 @@ package org.apache.james.mailetcontainer.impl.jmx;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicLong;
 
 import javax.management.NotCompliantMBeanException;
@@ -37,12 +38,13 @@ public final class MailetManagement extends StandardMBean 
implements MailetManag
     private final AtomicLong slowestProcessing = new AtomicLong(-1);
     private final AtomicLong lastProcessing = new AtomicLong(-1);
 
-    private final MailetConfig config;
+    private final Optional<MailetConfig> config;
+    private final String mailetName;
 
-    public MailetManagement(MailetConfig config) throws 
NotCompliantMBeanException {
+    public MailetManagement(Optional<MailetConfig> config, String mailetName) 
throws NotCompliantMBeanException {
         super(MailetManagementMBean.class);
         this.config = config;
-
+        this.mailetName = mailetName;
     }
 
     public void update(long processTime, boolean success) {
@@ -65,19 +67,22 @@ public final class MailetManagement extends StandardMBean 
implements MailetManag
 
     @Override
     public String getMailetName() {
-        return config.getMailetName();
+        return mailetName;
     }
 
     @Override
     public String[] getMailetParameters() {
-        List<String> parameterList = new ArrayList<>();
-        Iterator<String> iterator = config.getInitParameterNames();
-        while (iterator.hasNext()) {
-            String name = iterator.next();
-            String value = config.getInitParameter(name);
-            parameterList.add(name + "=" + value);
-        }
-        return parameterList.toArray(String[]::new);
+        return config.map(c -> {
+                    List<String> parameterList = new ArrayList<>();
+                    Iterator<String> iterator = c.getInitParameterNames();
+                    while (iterator.hasNext()) {
+                        String name = iterator.next();
+                        String value = c.getInitParameter(name);
+                        parameterList.add(name + "=" + value);
+                    }
+                    return parameterList.toArray(String[]::new);
+                }
+        ).orElse(new String[0]);
     }
 
     @Override
diff --git 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateCompositeProcessor.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateCompositeProcessor.java
index 77446cee39..a176a7b5d9 100644
--- 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateCompositeProcessor.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateCompositeProcessor.java
@@ -42,7 +42,6 @@ import 
org.apache.james.mailetcontainer.impl.MatcherMailetPair;
 import org.apache.james.mailetcontainer.impl.ProcessorImpl;
 import 
org.apache.james.mailetcontainer.impl.jmx.JMXStateCompositeProcessorListener;
 import org.apache.mailet.Mail;
-import org.apache.mailet.Mailet;
 import org.apache.mailet.ProcessingState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -137,7 +136,7 @@ public abstract class AbstractStateCompositeProcessor 
implements MailProcessor,
             .stream()
             .filter(MailetProcessorImpl.class::isInstance)
             .map(MailetProcessorImpl.class::cast)
-            .flatMap(processor -> 
processor.getPairs().stream().map(MatcherMailetPair::getMailet))
+            .flatMap(processor -> processor.getPairs().stream())
             .flatMap(this::requiredProcessorStates)
             .filter(state -> !state.equals(new ProcessingState("propagate"))
                 && !state.equals(new ProcessingState("ignore"))
@@ -151,13 +150,17 @@ public abstract class AbstractStateCompositeProcessor 
implements MailProcessor,
         }
     }
 
-    private Stream<ProcessingState> requiredProcessorStates(Mailet mailet) {
-        return Stream.concat(mailet.requiredProcessingState().stream(),
-            Stream.of(
-                    
Optional.ofNullable(mailet.getMailetConfig().getInitParameter("onMailetException")),
-                    
Optional.ofNullable(mailet.getMailetConfig().getInitParameter("onMatchException")))
-                .flatMap(Optional::stream)
-                .map(ProcessingState::new));
+    private Stream<ProcessingState> requiredProcessorStates(MatcherMailetPair 
matcherMailetPair) {
+        var mailet = matcherMailetPair.getMailet();
+
+        return Stream.concat(
+                mailet.requiredProcessingState().stream(),
+                Stream.of(
+                                matcherMailetPair.onMailetException(),
+                                matcherMailetPair.onMatchException()
+                        ).flatMap(Optional::stream)
+                        .map(ProcessingState::new)
+        );
     }
 
     @PostConstruct
diff --git 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
index c031b5e4ea..eb5b6b6c36 100644
--- 
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
@@ -319,7 +319,8 @@ public abstract class AbstractStateMailetProcessor 
implements MailProcessor, Con
                 throw new ConfigurationException("Unable to init matcher " + 
matcherName, ex);
             }
             try {
-                mailet = 
mailetLoader.getMailet(createMailetConfig(mailetClassName, c));
+                MailetConfig mailetConfig = 
createMailetConfig(mailetClassName, c);
+                mailet = mailetLoader.getMailet(mailetConfig);
                 LOGGER.info("Mailet {} instantiated.", mailetClassName);
             } catch (MessagingException ex) {
                 // **** Do better job printing out exception
@@ -331,7 +332,13 @@ public abstract class AbstractStateMailetProcessor 
implements MailProcessor, Con
             }
 
             if (matcher != null && mailet != null) {
-                pairs.add(new MatcherMailetPair(matcher, mailet));
+                var processingErrorConfig = new 
MailProcessingErrorHandlingConfiguration(
+                        Optional.ofNullable(c.getString("onMailetException")),
+                        Optional.ofNullable(c.getString("onMatchException"))
+                );
+
+
+                pairs.add(new MatcherMailetPair(matcher, mailet, 
processingErrorConfig));
             } else {
                 throw new ConfigurationException("Unable to load Mailet or 
Matcher");
             }
diff --git 
a/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/MailProcessingErrorHandlingConfiguration.java
similarity index 61%
copy from 
server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
copy to 
server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/MailProcessingErrorHandlingConfiguration.java
index ed582c04c1..75b7f1a139 100644
--- 
a/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
+++ 
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/MailProcessingErrorHandlingConfiguration.java
@@ -1,46 +1,35 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you under the Apache License, Version 2.0 (the            *
- * "License"); you may not use this file except in compliance   *
- * with the License.  You may obtain a copy of the License at   *
- *                                                              *
- *   http://www.apache.org/licenses/LICENSE-2.0                 *
- *                                                              *
- * Unless required by applicable law or agreed to in writing,   *
- * software distributed under the License is distributed on an  *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
- * KIND, either express or implied.  See the License for the    *
- * specific language governing permissions and limitations      *
- * under the License.                                           *
- ****************************************************************/
-
-package org.apache.james.transport.mailets.sub;
-
-import jakarta.inject.Inject;
-import jakarta.mail.MessagingException;
-
-import org.apache.mailet.Mail;
-import org.apache.mailet.Mailet;
-import org.apache.mailet.MailetConfig;
-
-public class ConstructorBoundTestMailet implements Mailet {
-    private final MailetConfig config;
-
-    @Inject
-    public ConstructorBoundTestMailet(MailetConfig config) {
-        this.config = config;
-    }
-
-    @Override
-    public void service(Mail mail) throws MessagingException {
-
-    }
-
-    @Override
-    public MailetConfig getMailetConfig() {
-        return config;
+/******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one                 *
+ * or more contributor license agreements.  See the NOTICE file               *
+ * distributed with this work for additional information                      *
+ * regarding copyright ownership.  The ASF licenses this file                 *
+ * to you under the Apache License, Version 2.0 (the                          *
+ * "License"); you may not use this file except in compliance                 *
+ * with the License.  You may obtain a copy of the License at                 *
+ *                                                                            *
+ *   http://www.apache.org/licenses/LICENSE-2.0                               *
+ *                                                                            *
+ * Unless required by applicable law or agreed to in writing,                 *
+ * software distributed under the License is distributed on an                *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY                     *
+ * KIND, either express or implied.  See the License for the                  *
+ * specific language governing permissions and limitations                    *
+ * under the License.                                                         *
+ 
******************************************************************************/
+
+package org.apache.james.mailetcontainer.lib;
+
+import java.util.Optional;
+
+public record MailProcessingErrorHandlingConfiguration(
+        Optional<String> onMailetException,
+        Optional<String> onMatchException
+) {
+    public static MailProcessingErrorHandlingConfiguration empty() {
+        return new MailProcessingErrorHandlingConfiguration(
+                Optional.empty(),
+                Optional.empty()
+
+        );
     }
-}
+}
\ No newline at end of file
diff --git 
a/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/impl/MailetProcessorImplTest.java
 
b/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/impl/MailetProcessorImplTest.java
index 51ba22afb0..65d18d6193 100644
--- 
a/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/impl/MailetProcessorImplTest.java
+++ 
b/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/impl/MailetProcessorImplTest.java
@@ -21,6 +21,8 @@ package org.apache.james.mailetcontainer.impl;
 
 import static org.mockito.Mockito.mock;
 
+import java.util.Collection;
+
 import org.apache.commons.configuration2.HierarchicalConfiguration;
 import org.apache.commons.configuration2.tree.ImmutableNode;
 import org.apache.james.mailetcontainer.api.MailProcessor;
@@ -34,22 +36,19 @@ import org.apache.mailet.base.test.FakeMailContext;
 public class MailetProcessorImplTest extends AbstractStateMailetProcessorTest {
 
     @Override
-    protected AbstractStateMailetProcessor 
createProcessor(HierarchicalConfiguration<ImmutableNode> configuration) throws 
Exception {
+    protected AbstractStateMailetProcessor 
createProcessor(HierarchicalConfiguration<ImmutableNode> configuration, 
Collection<AbstractStateMailetProcessor.MailetProcessorListener> listeners) 
throws Exception {
         MailetProcessorImpl processor = null;
-        try {
-            processor = new MailetProcessorImpl("anyName", new 
RecordingMetricFactory());
-            processor.setMailetContext(FakeMailContext.defaultContext());
-            processor.setMailetLoader(new MockMailetLoader());
-            processor.setMatcherLoader(new MockMatcherLoader());
-            processor.setRootMailProcessor(mock(MailProcessor.class));
-            processor.configure(configuration);
-            processor.init();
-            return processor;
-        } finally {
-            if (processor != null) {
-                processor.destroy();
-            }
+        processor = new MailetProcessorImpl("anyName", new 
RecordingMetricFactory());
+        processor.setMailetContext(FakeMailContext.defaultContext());
+        processor.setMailetLoader(new MockMailetLoader());
+        processor.setMatcherLoader(new MockMatcherLoader());
+        processor.setRootMailProcessor(mock(MailProcessor.class));
+        processor.configure(configuration);
+        for (var listener : listeners) {
+            processor.addListener(listener);
         }
+        processor.init();
+        return processor;
     }
 
 }
diff --git 
a/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
 
b/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
index 8e467d287a..29a04381b9 100644
--- 
a/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
+++ 
b/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
@@ -23,7 +23,9 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.ByteArrayInputStream;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import jakarta.mail.MessagingException;
 
@@ -47,8 +49,10 @@ import org.junit.jupiter.api.Test;
 
 public abstract class AbstractStateMailetProcessorTest {
 
-    protected abstract AbstractStateMailetProcessor 
createProcessor(HierarchicalConfiguration<ImmutableNode> configuration) throws
-            Exception;
+    protected abstract AbstractStateMailetProcessor createProcessor(
+            HierarchicalConfiguration<ImmutableNode> configuration,
+            Collection<AbstractStateMailetProcessor.MailetProcessorListener> 
listeners
+    ) throws Exception;
 
     private HierarchicalConfiguration<ImmutableNode> createConfig(Class<?> 
matcherClass, Class<?> mailetClass, int count) throws
             ConfigurationException {
@@ -69,9 +73,7 @@ public abstract class AbstractStateMailetProcessorTest {
         final CountDownLatch latch = new CountDownLatch(2);
         final MailImpl mail = newMail();
 
-        AbstractStateMailetProcessor processor = 
createProcessor(createConfig(MockMatcher.class, MockMailet.class, 1));
-        processor.addListener(new MailetProcessorListener() {
-
+        MailetProcessorListener listener = new MailetProcessorListener() {
             @Override
             public void afterMatcher(Matcher m, String mailName, 
Collection<MailAddress> recipients,
                                      Collection<MailAddress> matches, long 
processTime, Throwable e) {
@@ -96,7 +98,11 @@ public abstract class AbstractStateMailetProcessorTest {
                     latch.countDown();
                 }
             }
-        });
+        };
+        AbstractStateMailetProcessor processor = createProcessor(
+                createConfig(MockMatcher.class, MockMailet.class, 1),
+                List.of(listener)
+        );
 
         assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
         processor.service(mail);
@@ -104,7 +110,7 @@ public abstract class AbstractStateMailetProcessorTest {
 
         // the source mail should be ghosted as it reached the end of 
processor as only one recipient matched
         assertThat(mail.getState()).isEqualTo(Mail.GHOST);
-        latch.await();
+        assertThat(latch.await(3L, TimeUnit.SECONDS)).isTrue();
         processor.destroy();
 
     }
@@ -114,8 +120,7 @@ public abstract class AbstractStateMailetProcessorTest {
         final CountDownLatch latch = new CountDownLatch(2);
         final MailImpl mail = newMail();
 
-        AbstractStateMailetProcessor processor = 
createProcessor(createConfig(MockMatcher.class, MockMailet.class, 2));
-        processor.addListener(new MailetProcessorListener() {
+        MailetProcessorListener listener = new MailetProcessorListener() {
 
             @Override
             public void afterMatcher(Matcher m, String mailName, 
Collection<MailAddress> recipients,
@@ -142,7 +147,11 @@ public abstract class AbstractStateMailetProcessorTest {
                     latch.countDown();
                 }
             }
-        });
+        };
+        AbstractStateMailetProcessor processor = createProcessor(
+                createConfig(MockMatcher.class, MockMailet.class, 2),
+                List.of(listener)
+        );
 
         assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
         processor.service(mail);
@@ -150,7 +159,7 @@ public abstract class AbstractStateMailetProcessorTest {
 
         // the source mail should have the new state as it was a full match
         assertThat(mail.getState()).isEqualTo("test");
-        latch.await();
+        assertThat(latch.await(3L, TimeUnit.SECONDS)).isTrue();
         processor.destroy();
 
     }
@@ -160,9 +169,7 @@ public abstract class AbstractStateMailetProcessorTest {
         final CountDownLatch latch = new CountDownLatch(1);
         final MailImpl mail = newMail();
 
-        AbstractStateMailetProcessor processor = 
createProcessor(createConfig(ExceptionThrowingMatcher.class,
-                MockMailet.class, 0));
-        processor.addListener(new MailetProcessorListener() {
+        MailetProcessorListener listener = new MailetProcessorListener() {
 
             @Override
             public void afterMatcher(Matcher m, String mailName, 
Collection<MailAddress> recipients,
@@ -181,7 +188,11 @@ public abstract class AbstractStateMailetProcessorTest {
             public void afterMailet(Mailet m, String mailName, String state, 
long processTime, Throwable e) {
                 throw new RuntimeException("Should not call any mailet!");
             }
-        });
+        };
+        AbstractStateMailetProcessor processor = createProcessor(
+                createConfig(ExceptionThrowingMatcher.class, MockMailet.class, 
0),
+                List.of(listener)
+        );
 
         assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
 
@@ -189,7 +200,7 @@ public abstract class AbstractStateMailetProcessorTest {
 
         // the source mail should have state error as the exception was thrown
         assertThat(mail.getState()).isEqualTo(Mail.ERROR);
-        latch.await();
+        assertThat(latch.await(3L, TimeUnit.SECONDS)).isTrue();
         processor.destroy();
 
     }
@@ -199,9 +210,7 @@ public abstract class AbstractStateMailetProcessorTest {
         final CountDownLatch latch = new CountDownLatch(1);
         final MailImpl mail = newMail();
 
-        AbstractStateMailetProcessor processor = 
createProcessor(createConfig(ExceptionThrowingMatcher.class,
-                MockMailet.class, 0));
-        processor.addListener(new MailetProcessorListener() {
+        MailetProcessorListener listener = new MailetProcessorListener() {
 
             @Override
             public void afterMatcher(Matcher m, String mailName, 
Collection<MailAddress> recipients,
@@ -216,14 +225,18 @@ public abstract class AbstractStateMailetProcessorTest {
             public void afterMailet(Mailet m, String mailName, String state, 
long processTime, Throwable e) {
                 throw new RuntimeException("Should not call any mailet!");
             }
-        });
+        };
+        AbstractStateMailetProcessor processor = createProcessor(
+                createConfig(ExceptionThrowingMatcher.class, MockMailet.class, 
0),
+                List.of(listener)
+        );
 
         processor.service(mail);
 
         // the source mail should have captured the exception which was thrown
         
assertThat(mail.getAttribute(Mail.MAILET_ERROR)).hasValueSatisfying(attribute ->
                 
assertThat(attribute.getValue().value().getClass()).isEqualTo(MessagingException.class));
-        latch.await();
+        assertThat(latch.await(3L, TimeUnit.SECONDS)).isTrue();
         processor.destroy();
     }
 
@@ -232,9 +245,7 @@ public abstract class AbstractStateMailetProcessorTest {
         final CountDownLatch latch = new CountDownLatch(2);
         final MailImpl mail = newMail();
 
-        AbstractStateMailetProcessor processor = 
createProcessor(createConfig(MockMatcher.class,
-                ExceptionThrowingMailet.class, 1));
-        processor.addListener(new MailetProcessorListener() {
+        MailetProcessorListener listener = new MailetProcessorListener() {
 
             @Override
             public void afterMatcher(Matcher m, String mailName, 
Collection<MailAddress> recipients,
@@ -259,7 +270,11 @@ public abstract class AbstractStateMailetProcessorTest {
                     latch.countDown();
                 }
             }
-        });
+        };
+        AbstractStateMailetProcessor processor = createProcessor(
+                createConfig(MockMatcher.class, ExceptionThrowingMailet.class, 
1),
+                List.of(listener)
+        );
 
         assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
 
@@ -272,11 +287,11 @@ public abstract class AbstractStateMailetProcessorTest {
 
     private MailImpl newMail() throws MessagingException {
         return MailImpl.builder()
-            .name(MailImpl.getId())
-            .sender("test@localhost")
-            .addRecipient("test@localhost")
-            .addRecipient("test2@localhost")
-            .mimeMessage(MimeMessageUtil.mimeMessageFromBytes("header: 
value\r\n".getBytes(UTF_8)))
-            .build();
+                .name(MailImpl.getId())
+                .sender("test@localhost")
+                .addRecipient("test@localhost")
+                .addRecipient("test2@localhost")
+                .mimeMessage(MimeMessageUtil.mimeMessageFromBytes("header: 
value\r\n".getBytes(UTF_8)))
+                .build();
     }
 }
diff --git 
a/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/HelloWorldMailet.java
 
b/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/HelloWorldMailet.java
index 186d08756b..8dcfd2744c 100644
--- 
a/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/HelloWorldMailet.java
+++ 
b/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/HelloWorldMailet.java
@@ -38,13 +38,13 @@ public class HelloWorldMailet implements Mailet {
     }
 
     @Override
-    public String getMailetInfo() {
-        return "Example mailet";
+    public String getName() {
+        return config.getMailetName();
     }
 
     @Override
-    public MailetConfig getMailetConfig() {
-        return config;
+    public String getMailetInfo() {
+        return "Example mailet";
     }
 
     @Override
diff --git 
a/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/InstrumentationMailet.java
 
b/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/InstrumentationMailet.java
index 9523513d60..046696f917 100644
--- 
a/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/InstrumentationMailet.java
+++ 
b/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/InstrumentationMailet.java
@@ -53,13 +53,13 @@ public class InstrumentationMailet implements Mailet {
     }
 
     @Override
-    public String getMailetInfo() {
-        return "Example mailet";
+    public String getName() {
+        return config.getMailetName();
     }
 
     @Override
-    public MailetConfig getMailetConfig() {
-        return config;
+    public String getMailetInfo() {
+        return "Example mailet";
     }
 
     @Override
diff --git a/upgrade-instructions.md b/upgrade-instructions.md
index 755ef83bad..c7a01d6f8f 100644
--- a/upgrade-instructions.md
+++ b/upgrade-instructions.md
@@ -36,6 +36,19 @@ Change list:
  - [JAMES-4052 Details in quota index](#james-4052-details-in-quota-index)
  - [JAMES-1409 Change JPARecipientRewriteTable to store separate record per 
target 
address](#james-1409-change-jparecipientrewritetable-to-store-separate-record-per-target-address)
  - [JAMES-4118 Cleanup message previews](#james-4118-cleanup-message-previews)
+ - [JAMES-4128 Breaking Mailet API 
changes](#james-4128-breaking-mailet-api-changes)
+
+### JAMES-4128 Breaking Mailet API changes
+Date: 02/04/2025
+
+JIRA: https://issues.apache.org/jira/browse/JAMES-4126
+
+The Mailet API has been slightly reworked to improve mailet encapsulation and 
make implementation easier. 
+    
+- Method getMailetConfig() has been removed
+- Method getName() has been added with a default to the simple class name
+- implementers no longer have to override getMailetInfo, init or destroy
+- implementers of mailets can inject the configuration through the constructor 
when using guice. Constructor injection of the config is not compatible with 
spring applications.
 
 ### JAMES-4118 Cleanup message previews
 


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to