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

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

commit 3df117d440d073a04dfebd44cf3e088bd591ed7b
Author: Rémi KOWALSKI <rkowal...@linagora.com>
AuthorDate: Tue Dec 10 12:15:14 2019 +0100

    JAMES-3009 convert to scala JsonEventSerializer
---
 .../eventstore/cassandra/EventNestedTypes.java     |  20 +---
 .../eventstore/cassandra/JsonEventSerializer.java  | 109 -----------------
 .../eventstore/cassandra/JsonEventSerializer.scala |  87 ++++++++++++++
 .../apache/james/json/JsonGenericSerializer.java   |   6 +-
 .../apache/james/JsonGenericSerializerTest.java    |   6 +-
 .../org/apache/james/CassandraJamesServerMain.java |   5 +-
 .../data/CassandraDLPConfigurationStoreModule.java |   4 +-
 .../james/modules/data/CassandraJmapModule.java    |   4 +-
 .../eventstore/CassandraEventStoreModule.java      |   4 +-
 .../mailbox/CassandraQuotaMailingModule.java       |   4 +-
 .../james/modules/TaskSerializationModule.java     | 129 +++++++++++----------
 .../james/modules/rabbitmq/RabbitMQModule.java     |   4 +-
 .../distributed/TasksSerializationModule.java      |  16 +--
 .../distributed/DistributedTaskManagerTest.java    |   4 +-
 .../RabbitMQTerminationSubscriberTest.java         |   3 +-
 .../distributed/TaskEventsSerializationTest.java   |   6 +-
 .../JsonTaskAdditionalInformationSerializer.java   |   4 +-
 .../james/server/task/json/JsonTaskSerializer.java |   2 +-
 18 files changed, 199 insertions(+), 218 deletions(-)

diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
 
b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventNestedTypes.java
similarity index 62%
copy from 
server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
copy to 
event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventNestedTypes.java
index ecc2a35..30e0b94 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
+++ 
b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventNestedTypes.java
@@ -16,22 +16,8 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
+package org.apache.james.eventsourcing.eventstore.cassandra;
 
-package org.apache.james.modules.mailbox;
-
-import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
-import org.apache.james.mailbox.quota.cassandra.dto.QuotaEventDTOModules;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.TypeLiteral;
-import com.google.inject.multibindings.Multibinder;
-
-public class CassandraQuotaMailingModule extends AbstractModule {
-    @Override
-    protected void configure() {
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = 
Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
-
-        eventDTOModuleBinder.addBinding()
-            .toInstance(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE);
-    }
+public interface EventNestedTypes {
+    String EVENT_NESTED_TYPES_INJECTION_NAME = "EventNestedTypes";
 }
diff --git 
a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
 
b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
deleted file mode 100644
index b1bb6bc..0000000
--- 
a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************
- * 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.eventsourcing.eventstore.cassandra;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
-import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
-import org.apache.james.json.DTOModule;
-import org.apache.james.json.JsonGenericSerializer;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.ImmutableSet;
-
-public class JsonEventSerializer {
-
-    public static final String EVENT_NESTED_TYPES_INJECTION_NAME = 
"EventNestedTypes";
-
-    public static RequireNestedConfiguration forModules(Set<? extends 
EventDTOModule<?, ?>> modules) {
-        return nestedTypesModules -> {
-            ImmutableSet<EventDTOModule<?, ?>> dtoModules = 
ImmutableSet.copyOf(modules);
-            return new JsonEventSerializer(dtoModules, 
ImmutableSet.copyOf(nestedTypesModules));
-        };
-    }
-
-    @SafeVarargs
-    public static RequireNestedConfiguration forModules(EventDTOModule<?, 
?>... modules) {
-        return forModules(ImmutableSet.copyOf(modules));
-    }
-
-    public interface RequireNestedConfiguration {
-        JsonEventSerializer withNestedTypeModules(Set<DTOModule<?, ?>> 
modules);
-
-        default JsonEventSerializer withNestedTypeModules(DTOModule<?, ?>... 
modules) {
-            return withNestedTypeModules(ImmutableSet.copyOf(modules));
-        }
-
-        default JsonEventSerializer withNestedTypeModules(Set<DTOModule<?, 
?>>... modules) {
-            return 
withNestedTypeModules(Arrays.stream(modules).flatMap(Collection::stream).collect(Guavate.toImmutableSet()));
-        }
-
-        default JsonEventSerializer withoutNestedType() {
-            return withNestedTypeModules(ImmutableSet.of());
-        }
-    }
-
-    public static class InvalidEventException extends RuntimeException {
-        public 
InvalidEventException(JsonGenericSerializer.InvalidTypeException original) {
-            super(original);
-        }
-    }
-
-    public static class UnknownEventException extends RuntimeException {
-        public 
UnknownEventException(JsonGenericSerializer.UnknownTypeException original) {
-            super(original);
-        }
-    }
-
-    private JsonGenericSerializer<Event, EventDTO> jsonGenericSerializer;
-
-    @Inject
-    private JsonEventSerializer(Set<EventDTOModule<?, ?>> modules, 
@Named(EVENT_NESTED_TYPES_INJECTION_NAME) Set<DTOModule<?, ?>> 
nestedTypesModules) {
-        jsonGenericSerializer = 
JsonGenericSerializer.forModules(modules).withNestedTypeModules(nestedTypesModules);
-    }
-    
-    public String serialize(Event event) throws JsonProcessingException {
-        try {
-            return jsonGenericSerializer.serialize(event);
-        } catch (JsonGenericSerializer.UnknownTypeException e) {
-            throw new UnknownEventException(e);
-        }
-    }
-
-    public Event deserialize(String value) throws IOException {
-        try {
-            return jsonGenericSerializer.deserialize(value);
-        } catch (JsonGenericSerializer.UnknownTypeException e) {
-            throw new UnknownEventException(e);
-        } catch (JsonGenericSerializer.InvalidTypeException e) {
-            throw new InvalidEventException(e);
-        }
-    }
-
-}
diff --git 
a/event-sourcing/event-store-cassandra/src/main/scala/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.scala
 
b/event-sourcing/event-store-cassandra/src/main/scala/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.scala
new file mode 100644
index 0000000..fe28295
--- /dev/null
+++ 
b/event-sourcing/event-store-cassandra/src/main/scala/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.scala
@@ -0,0 +1,87 @@
+ /***************************************************************
+ * 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.eventsourcing.eventstore.cassandra
+
+import java.io.IOException
+import java.util
+
+import com.fasterxml.jackson.core.JsonProcessingException
+import com.google.common.collect.ImmutableSet
+import javax.inject.{Inject, Named}
+import org.apache.james.eventsourcing.Event
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.{EventDTO, 
EventDTOModule}
+import org.apache.james.json.{DTO, DTOModule, JsonGenericSerializer}
+
+import scala.annotation.varargs
+import scala.jdk.CollectionConverters._
+
+object JsonEventSerializer {
+
+  def forModules(modules: util.Set[_ <: EventDTOModule[_ <: Event, _ <: 
EventDTO]]): RequireNestedConfiguration =
+    (nestedTypesModules: util.Set[DTOModule[_, _ <: DTO]]) =>
+      new JsonEventSerializer(ImmutableSet.copyOf(modules), 
ImmutableSet.copyOf(nestedTypesModules))
+
+  @SafeVarargs
+  @varargs
+  def forModules(modules: EventDTOModule[_ <: Event, _ <: EventDTO]*): 
RequireNestedConfiguration = forModules(ImmutableSet.copyOf(modules.toArray))
+
+  trait RequireNestedConfiguration {
+    def withNestedTypeModules(modules: util.Set[DTOModule[_, _ <: DTO]]): 
JsonEventSerializer
+
+    def withNestedTypeModules(modules: Set[DTOModule[_, _ <: DTO]]): 
JsonEventSerializer = withNestedTypeModules(modules.asJava)
+
+    @varargs
+    def withListOfNestedTypeModules(modules: DTOModule[_, _ <: DTO]*): 
JsonEventSerializer = 
withNestedTypeModules(ImmutableSet.copyOf(modules.toArray))
+
+    @varargs
+    def withNestedTypeModules(modules: util.Set[DTOModule[_, _ <: DTO]]*): 
JsonEventSerializer = 
withNestedTypeModules(modules.toList.flatMap(_.asScala).toSet)
+
+    def withoutNestedType: JsonEventSerializer = 
withNestedTypeModules(Set[DTOModule[_, _ <: DTO]]())
+  }
+
+  class InvalidEventException(original: 
JsonGenericSerializer.InvalidTypeException) extends RuntimeException(original)
+
+  class UnknownEventException(original: 
JsonGenericSerializer.UnknownTypeException) extends RuntimeException(original)
+
+}
+
+class JsonEventSerializer @Inject()private(modules: util.Set[EventDTOModule[_ 
<: Event, _ <: EventDTO]],
+                                            
@Named(EventNestedTypes.EVENT_NESTED_TYPES_INJECTION_NAME)
+                                            nestedTypesModules: 
util.Set[DTOModule[_, _ <: DTO]]) {
+
+  private val jsonGenericSerializer: JsonGenericSerializer[Event, EventDTO] = 
JsonGenericSerializer
+    .forModules(modules)
+    .withNestedTypeModules(nestedTypesModules)
+
+  @throws[JsonProcessingException]
+  def serialize(event: Event): String = try 
jsonGenericSerializer.serialize(event)
+  catch {
+    case e: JsonGenericSerializer.UnknownTypeException =>
+      throw new JsonEventSerializer.UnknownEventException(e)
+  }
+
+  @throws[IOException]
+  def deserialize(value: String): Event = try 
jsonGenericSerializer.deserialize(value)
+  catch {
+    case e: JsonGenericSerializer.UnknownTypeException =>
+      throw new JsonEventSerializer.UnknownEventException(e)
+    case e: JsonGenericSerializer.InvalidTypeException =>
+      throw new JsonEventSerializer.InvalidEventException(e)
+  }
+}
\ No newline at end of file
diff --git 
a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java 
b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
index 371e887..6c05ebf 100644
--- a/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
+++ b/json/src/main/java/org/apache/james/json/JsonGenericSerializer.java
@@ -44,7 +44,7 @@ import com.google.common.collect.Sets;
 
 public class JsonGenericSerializer<T, U extends DTO> {
 
-    public static <T, U extends DTO> RequireNestedConfiguration<T, U> 
forModules(java.util.Set<? extends DTOModule<? extends T, ? extends U>> 
modules) {
+    public static <T, U extends DTO> RequireNestedConfiguration<T, U> 
forModules(Set<? extends DTOModule<? extends T, ? extends U>> modules) {
         return nestedTypesModules -> {
             ImmutableSet<DTOModule<? extends T, ? extends U>> dtoModules = 
ImmutableSet.copyOf(modules);
             return new JsonGenericSerializer<>(dtoModules, 
ImmutableSet.copyOf(nestedTypesModules), new DTOConverter<>(dtoModules));
@@ -59,11 +59,11 @@ public class JsonGenericSerializer<T, U extends DTO> {
     public interface RequireNestedConfiguration<T, U extends DTO> {
         JsonGenericSerializer<T, U> withNestedTypeModules(Set<DTOModule<?, ?>> 
modules);
 
-        default JsonGenericSerializer<T, U> withNestedTypeModules(DTOModule<?, 
?>... modules) {
+        default JsonGenericSerializer<T, U> 
withMultipleNestedTypeModules(DTOModule<?, ?>... modules) {
             return withNestedTypeModules(ImmutableSet.copyOf(modules));
         }
 
-        default JsonGenericSerializer<T, U> 
withNestedTypeModules(Set<DTOModule<?, ?>>... modules) {
+        default JsonGenericSerializer<T, U> 
withMultipleNestedTypeModules(Set<DTOModule<?, ?>>... modules) {
             return 
withNestedTypeModules(Arrays.stream(modules).flatMap(Collection::stream).collect(Guavate.toImmutableSet()));
         }
 
diff --git a/json/src/test/java/org/apache/james/JsonGenericSerializerTest.java 
b/json/src/test/java/org/apache/james/JsonGenericSerializerTest.java
index 14e528a..3a2c8ad 100644
--- a/json/src/test/java/org/apache/james/JsonGenericSerializerTest.java
+++ b/json/src/test/java/org/apache/james/JsonGenericSerializerTest.java
@@ -57,7 +57,7 @@ class JsonGenericSerializerTest {
     void shouldDeserializeNestedTypeWithSecond() throws Exception {
         assertThat(JsonGenericSerializer
             .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
-            .withNestedTypeModules(TestModules.FIRST_NESTED, 
TestModules.SECOND_NESTED)
+            .withMultipleNestedTypeModules(TestModules.FIRST_NESTED, 
TestModules.SECOND_NESTED)
             .deserialize(SECOND_WITH_NESTED_JSON))
             .isEqualTo(SECOND_WITH_NESTED);
     }
@@ -66,7 +66,7 @@ class JsonGenericSerializerTest {
     void shouldDeserializeNestedTypeWithFirst() throws Exception {
         assertThat(JsonGenericSerializer
             .forModules(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE)
-            .withNestedTypeModules(TestModules.FIRST_NESTED, 
TestModules.SECOND_NESTED)
+            .withMultipleNestedTypeModules(TestModules.FIRST_NESTED, 
TestModules.SECOND_NESTED)
             .deserialize(FIRST_JSON_WITH_NESTED))
             .isEqualTo(FIRST_WITH_NESTED);
     }
@@ -152,7 +152,7 @@ class JsonGenericSerializerTest {
     void shouldThrowWhenRegisteringDuplicateTypeIds() {
         assertThatThrownBy(() -> JsonGenericSerializer
             .forModules(TestModules.FIRST_NESTED)
-            .withNestedTypeModules(TestModules.FIRST_NESTED))
+            .withMultipleNestedTypeModules(TestModules.FIRST_NESTED))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
index 05e07ea..1f5cd85 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
@@ -19,10 +19,9 @@
 
 package org.apache.james;
 
-import static 
org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer.EVENT_NESTED_TYPES_INJECTION_NAME;
-
 import java.util.Set;
 
+import org.apache.james.eventsourcing.eventstore.cassandra.EventNestedTypes;
 import org.apache.james.json.DTOModule;
 import org.apache.james.modules.BlobExportMechanismModule;
 import org.apache.james.modules.MailboxModule;
@@ -116,7 +115,7 @@ public class CassandraJamesServerMain {
         new BlobExportMechanismModule());
 
     private static final Module 
CASSANDRA_EVENT_STORE_JSON_SERIALIZATION_DEFAULT_MODULE = binder ->
-        binder.bind(new TypeLiteral<Set<DTOModule<?, ?>>>() 
{}).annotatedWith(Names.named(EVENT_NESTED_TYPES_INJECTION_NAME))
+        binder.bind(new TypeLiteral<Set<DTOModule<?, ? extends 
org.apache.james.json.DTO>>>() 
{}).annotatedWith(Names.named(EventNestedTypes.EVENT_NESTED_TYPES_INJECTION_NAME))
             .toInstance(ImmutableSet.of());
 
     public static final Module CASSANDRA_SERVER_CORE_MODULE = Modules.combine(
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
index 4a97f5e..f6fb7eb 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDLPConfigurationStoreModule.java
@@ -22,6 +22,8 @@ package org.apache.james.modules.data;
 import org.apache.james.dlp.api.DLPConfigurationStore;
 import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
 import org.apache.james.dlp.eventsourcing.cassandra.DLPConfigurationModules;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 
 import com.google.inject.AbstractModule;
@@ -36,7 +38,7 @@ public class CassandraDLPConfigurationStoreModule extends 
AbstractModule {
         bind(EventSourcingDLPConfigurationStore.class).in(Scopes.SINGLETON);
         
bind(DLPConfigurationStore.class).to(EventSourcingDLPConfigurationStore.class);
 
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = 
Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder<EventDTOModule<? extends Event, ? extends EventDTO>> 
eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new 
TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
 
         
eventDTOModuleBinder.addBinding().toInstance(DLPConfigurationModules.DLP_CONFIGURATION_STORE);
         
eventDTOModuleBinder.addBinding().toInstance(DLPConfigurationModules.DLP_CONFIGURATION_CLEAR);
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
index 01408b0..fa055af 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
@@ -21,6 +21,8 @@ package org.apache.james.modules.data;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.core.healthcheck.HealthCheck;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.jmap.api.access.AccessTokenRepository;
 import org.apache.james.jmap.api.filtering.FilteringManagement;
@@ -73,7 +75,7 @@ public class CassandraJmapModule extends AbstractModule {
         
cassandraDataDefinitions.addBinding().toInstance(CassandraNotificationRegistryModule.MODULE);
         
cassandraDataDefinitions.addBinding().toInstance(CassandraMessageFastViewProjectionModule.MODULE);
 
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = 
Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder<EventDTOModule<? extends Event, ? extends EventDTO>> 
eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new 
TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
         
eventDTOModuleBinder.addBinding().toInstance(FilteringRuleSetDefineDTOModules.FILTERING_RULE_SET_DEFINED);
     }
 }
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/eventstore/CassandraEventStoreModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/eventstore/CassandraEventStoreModule.java
index aa48baf..164ccd8 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/eventstore/CassandraEventStoreModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/eventstore/CassandraEventStoreModule.java
@@ -20,8 +20,10 @@
 package org.apache.james.modules.eventstore;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStore;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 
 import com.google.inject.AbstractModule;
@@ -40,6 +42,6 @@ public class CassandraEventStoreModule extends AbstractModule 
{
             .addBinding()
             
.toInstance(org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreModule.MODULE());
 
-        Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, 
?>>() {});
+        Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<? 
extends Event, ? extends EventDTO>>() {});
     }
 }
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
index ecc2a35..2130062 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaMailingModule.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.modules.mailbox;
 
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.mailbox.quota.cassandra.dto.QuotaEventDTOModules;
 
@@ -29,7 +31,7 @@ import com.google.inject.multibindings.Multibinder;
 public class CassandraQuotaMailingModule extends AbstractModule {
     @Override
     protected void configure() {
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = 
Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder<EventDTOModule<? extends Event, ? extends EventDTO>> 
eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new 
TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
 
         eventDTOModuleBinder.addBinding()
             .toInstance(QuotaEventDTOModules.QUOTA_THRESHOLD_CHANGE);
diff --git 
a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/TaskSerializationModule.java
 
b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/TaskSerializationModule.java
index 1346bc1..30ef794 100644
--- 
a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/TaskSerializationModule.java
+++ 
b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/TaskSerializationModule.java
@@ -18,8 +18,6 @@
  ****************************************************************/
 package org.apache.james.modules;
 
-import static 
org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer.EVENT_NESTED_TYPES_INJECTION_NAME;
-
 import java.time.Clock;
 import java.util.Set;
 
@@ -28,6 +26,9 @@ import javax.inject.Named;
 import org.apache.james.backends.cassandra.migration.MigrationTask;
 import 
org.apache.james.backends.cassandra.migration.MigrationTaskAdditionalInformationDTO;
 import org.apache.james.backends.cassandra.migration.MigrationTaskDTO;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.EventNestedTypes;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.json.DTOConverter;
 import org.apache.james.json.DTOModule;
@@ -113,310 +114,310 @@ public class TaskSerializationModule extends 
AbstractModule {
 
     @Provides
     @Singleton
-    public DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> 
additionalInformationDTOConverter(Set<AdditionalInformationDTOModule<?, ?>> 
modules) {
+    public DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> 
additionalInformationDTOConverter(Set<AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends 
AdditionalInformationDTO>> modules) {
         return new DTOConverter<>(modules);
     }
 
     @Provides
     @Singleton
-    public DTOConverter<Task, TaskDTO> taskDTOConverter(Set<TaskDTOModule<?, 
?>> taskDTOModules) {
+    public DTOConverter<Task, TaskDTO> taskDTOConverter(Set<TaskDTOModule<? 
extends Task, ? extends TaskDTO>> taskDTOModules) {
         return new DTOConverter<>(taskDTOModules);
 
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCreatedSerialization(JsonTaskSerializer 
jsonTaskSerializer,
-                                                         
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
-                                                         DTOConverter<Task, 
TaskDTO> taskConverter) {
+    public EventDTOModule<? extends Event, ? extends EventDTO> 
taskCreatedSerialization(JsonTaskSerializer jsonTaskSerializer,
+                                                                               
         DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
+                                                                               
         DTOConverter<Task, TaskDTO> taskConverter) {
         return TasksSerializationModule.CREATED.create(jsonTaskSerializer, 
additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskStartedSerialization(JsonTaskSerializer 
jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> 
taskStartedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                          
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
                                                          DTOConverter<Task, 
TaskDTO> taskConverter) {
         return TasksSerializationModule.STARTED.create(jsonTaskSerializer, 
additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> 
taskCancelRequestedSerialization(JsonTaskSerializer jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> 
taskCancelRequestedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                                  
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
                                                                  
DTOConverter<Task, TaskDTO> taskConverter) {
         return 
TasksSerializationModule.CANCEL_REQUESTED.create(jsonTaskSerializer, 
additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCancelledSerialization(JsonTaskSerializer 
jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> 
taskCancelledSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                            
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
                                                            DTOConverter<Task, 
TaskDTO> taskConverter) {
         return TasksSerializationModule.CANCELLED.create(jsonTaskSerializer, 
additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskCompletedSerialization(JsonTaskSerializer 
jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> 
taskCompletedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                            
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
                                                            DTOConverter<Task, 
TaskDTO> taskConverter) {
         return TasksSerializationModule.COMPLETED.create(jsonTaskSerializer, 
additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskFailedSerialization(JsonTaskSerializer 
jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> 
taskFailedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                         
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
                                                         DTOConverter<Task, 
TaskDTO> taskConverter) {
         return TasksSerializationModule.FAILED.create(jsonTaskSerializer, 
additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public EventDTOModule<?, ?> taskUpdatedSerialization(JsonTaskSerializer 
jsonTaskSerializer,
+    public EventDTOModule<? extends Event, ? extends EventDTO> 
taskUpdatedSerialization(JsonTaskSerializer jsonTaskSerializer,
                                                         
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
                                                         DTOConverter<Task, 
TaskDTO> taskConverter) {
         return TasksSerializationModule.UPDATED.create(jsonTaskSerializer, 
additionalInformationConverter, taskConverter);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
blobStoreVaultGarbageCollectionTask(BlobStoreVaultGarbageCollectionTask.Factory 
factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
blobStoreVaultGarbageCollectionTask(BlobStoreVaultGarbageCollectionTask.Factory 
factory) {
         return BlobStoreVaultGarbageCollectionTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
cassandraMappingsSolveInconsistenciesTask(MappingsSourcesMigration migration, 
CassandraMappingsSourcesDAO dao) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
cassandraMappingsSolveInconsistenciesTask(MappingsSourcesMigration migration, 
CassandraMappingsSourcesDAO dao) {
         return CassandraMappingsSolveInconsistenciesTask.module(migration, 
dao);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> clearMailQueueTask(MailQueueFactory<? extends 
ManageableMailQueue> mailQueueFactory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
clearMailQueueTask(MailQueueFactory<? extends ManageableMailQueue> 
mailQueueFactory) {
         return ClearMailQueueTaskDTO.module(mailQueueFactory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
recomputeAllJmapPreviewsTask(MessageFastViewProjectionCorrector corrector) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
recomputeAllJmapPreviewsTask(MessageFastViewProjectionCorrector corrector) {
         return RecomputeAllFastViewProjectionItemsTask.module(corrector);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
recomputeUserJmapPreviewsTask(MessageFastViewProjectionCorrector corrector) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
recomputeUserJmapPreviewsTask(MessageFastViewProjectionCorrector corrector) {
         return RecomputeUserFastViewProjectionItemsTask.module(corrector);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
clearMailRepositoryTask(ClearMailRepositoryTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
clearMailRepositoryTask(ClearMailRepositoryTask.Factory factory) {
         return ClearMailRepositoryTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> deleteMailsFromMailQueueTask(MailQueueFactory<? 
extends ManageableMailQueue> mailQueueFactory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
deleteMailsFromMailQueueTask(MailQueueFactory<? extends ManageableMailQueue> 
mailQueueFactory) {
         return DeleteMailsFromMailQueueTaskDTO.module(mailQueueFactory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
deletedMessagesVaultDeleteTask(DeletedMessagesVaultDeleteTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
deletedMessagesVaultDeleteTask(DeletedMessagesVaultDeleteTask.Factory factory) {
         return DeletedMessagesVaultDeleteTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
deletedMessagesVaultExportTask(DeletedMessagesVaultExportTaskDTO.Factory 
factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
deletedMessagesVaultExportTask(DeletedMessagesVaultExportTaskDTO.Factory 
factory) {
         return DeletedMessagesVaultExportTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
deletedMessagesVaultRestoreTask(DeletedMessagesVaultRestoreTaskDTO.Factory 
factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
deletedMessagesVaultRestoreTask(DeletedMessagesVaultRestoreTaskDTO.Factory 
factory) {
         return DeletedMessagesVaultRestoreTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
eventDeadLettersRedeliverAllTask(EventDeadLettersRedeliverService service) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
eventDeadLettersRedeliverAllTask(EventDeadLettersRedeliverService service) {
         return EventDeadLettersRedeliverAllTaskDTO.module(service);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
eventDeadLettersRedeliverGroupTask(EventDeadLettersRedeliverService service) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
eventDeadLettersRedeliverGroupTask(EventDeadLettersRedeliverService service) {
         return EventDeadLettersRedeliverGroupTaskDTO.module(service);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
eventDeadLettersRedeliverOneTask(EventDeadLettersRedeliverService service) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
eventDeadLettersRedeliverOneTask(EventDeadLettersRedeliverService service) {
         return EventDeadLettersRedeliverOneTaskDTO.module(service);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> fullReindexTask(ReIndexerPerformer performer) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
fullReindexTask(ReIndexerPerformer performer) {
         return FullReindexingTask.module(performer);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
errorRecoveryIndexationTask(ErrorRecoveryIndexationTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
errorRecoveryIndexationTask(ErrorRecoveryIndexationTask.Factory factory) {
         return ErrorRecoveryIndexationTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> mailboxMergingTask(MailboxMergingTaskRunner 
taskRunner) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
mailboxMergingTask(MailboxMergingTaskRunner taskRunner) {
         return MailboxMergingTaskDTO.module(taskRunner);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
solveMailboxInconsistenciesTask(SolveMailboxInconsistenciesService service) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
solveMailboxInconsistenciesTask(SolveMailboxInconsistenciesService service) {
         return SolveMailboxInconsistenciesTaskDTO.module(service);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
messageIdReindexingTask(MessageIdReIndexingTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
messageIdReindexingTask(MessageIdReIndexingTask.Factory factory) {
         return MessageIdReindexingTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> migrationTask(MigrationTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
migrationTask(MigrationTask.Factory factory) {
         return MigrationTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> reprocessingAllMailsTask(ReprocessingService 
reprocessingService) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
reprocessingAllMailsTask(ReprocessingService reprocessingService) {
         return ReprocessingAllMailsTaskDTO.module(reprocessingService);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> reprocessingOneMailsTask(ReprocessingService 
reprocessingService) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
reprocessingOneMailsTask(ReprocessingService reprocessingService) {
         return ReprocessingOneMailTaskDTO.module(Clock.systemUTC(), 
reprocessingService);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
singleMailboxReindexingTask(SingleMailboxReindexingTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
singleMailboxReindexingTask(SingleMailboxReindexingTask.Factory factory) {
         return SingleMailboxReindexingTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> 
singleMessageReindexingTask(SingleMessageReindexingTask.Factory factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
singleMessageReindexingTask(SingleMessageReindexingTask.Factory factory) {
         return SingleMessageReindexingTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public TaskDTOModule<?, ?> userReindexingTask(UserReindexingTask.Factory 
factory) {
+    public TaskDTOModule<? extends Task, ? extends TaskDTO> 
userReindexingTask(UserReindexingTask.Factory factory) {
         return UserReindexingTaskDTO.module(factory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
blobStoreVaultGarbageCollectionAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
blobStoreVaultGarbageCollectionAdditionalInformation() {
         return 
BlobStoreVaultGarbageCollectionTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
cassandraMappingsSolveInconsistenciesAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
cassandraMappingsSolveInconsistenciesAdditionalInformation() {
         return 
MappingsSourcesMigrationTaskAdditionalInformationDTO.serializationModule(CassandraMappingsSolveInconsistenciesTask.TYPE);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
clearMailQueueAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> clearMailQueueAdditionalInformation() {
         return ClearMailQueueTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
clearMailRepositoryAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> clearMailRepositoryAdditionalInformation() {
         return 
ClearMailRepositoryTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
deleteMailsFromMailQueueAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> deleteMailsFromMailQueueAdditionalInformation() {
         return DeleteMailsFromMailQueueTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
deletedMessagesVaultDeleteAdditionalInformation(MessageId.Factory factory) {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
deletedMessagesVaultDeleteAdditionalInformation(MessageId.Factory factory) {
         return 
DeletedMessagesVaultDeleteTaskAdditionalInformationDTO.serializationModule(factory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
deletedMessagesVaultExportAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> deletedMessagesVaultExportAdditionalInformation() {
         return DeletedMessagesVaultExportTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
deletedMessagesVaultRestoreAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> deletedMessagesVaultRestoreAdditionalInformation() {
         return DeletedMessagesVaultRestoreTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
errorRecoveryAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> errorRecoveryAdditionalInformation(MailboxId.Factory 
mailboxIdFactory) {
         return 
ReprocessingContextInformationDTO.ReprocessingContextInformationForErrorRecoveryIndexationTask.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
eventDeadLettersRedeliveryAdditionalInformationForAll() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
eventDeadLettersRedeliveryAdditionalInformationForAll() {
         return 
EventDeadLettersRedeliveryTaskAdditionalInformationDTO.EventDeadLettersRedeliveryTaskAdditionalInformationForAll.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
eventDeadLettersRedeliveryAdditionalInformationForGroup() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
eventDeadLettersRedeliveryAdditionalInformationForGroup() {
         return 
EventDeadLettersRedeliveryTaskAdditionalInformationDTO.EventDeadLettersRedeliveryTaskAdditionalInformationForGroup.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
eventDeadLettersRedeliveryAdditionalInformationForOne() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
eventDeadLettersRedeliveryAdditionalInformationForOne() {
         return 
EventDeadLettersRedeliveryTaskAdditionalInformationDTO.EventDeadLettersRedeliveryTaskAdditionalInformationForOne.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
fullReindexAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> fullReindexAdditionalInformation(MailboxId.Factory 
mailboxIdFactory) {
         return 
ReprocessingContextInformationDTO.ReprocessingContextInformationForFullReindexingTask.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
mailboxMergingAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> mailboxMergingAdditionalInformation() {
         return MailboxMergingTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
solveMailboxInconsistenciesAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> solveMailboxInconsistenciesAdditionalInformation() {
         return SolveMailboxInconsistenciesTaskAdditionalInformationDTO.MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
messageIdReindexingAdditionalInformation(MessageId.Factory messageIdFactory) {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
messageIdReindexingAdditionalInformation(MessageId.Factory messageIdFactory) {
         return 
MessageIdReindexingTaskAdditionalInformationDTO.serializationModule(messageIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
migrationTaskAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> migrationTaskAdditionalInformation() {
         return MigrationTaskAdditionalInformationDTO.serializationModule();
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
reprocessingAllMailsAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> reprocessingAllMailsAdditionalInformation() {
         return 
ReprocessingAllMailsTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
reprocessingOneMailAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> reprocessingOneMailAdditionalInformation() {
         return 
ReprocessingOneMailTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
singleMailboxReindexingAdditionalInformation(MailboxId.Factory 
mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
singleMailboxReindexingAdditionalInformation(MailboxId.Factory 
mailboxIdFactory) {
         return 
SingleMailboxReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
singleMessageReindexingAdditionalInformation(MailboxId.Factory 
mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> 
singleMessageReindexingAdditionalInformation(MailboxId.Factory 
mailboxIdFactory) {
         return 
SingleMessageReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
userReindexingAdditionalInformation(MailboxId.Factory mailboxIdFactory) {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> userReindexingAdditionalInformation(MailboxId.Factory 
mailboxIdFactory) {
         return 
UserReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory);
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
recomputeAllJmapPreviewsAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> recomputeAllJmapPreviewsAdditionalInformation() {
         return 
RecomputeAllFastViewTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
     @ProvidesIntoSet
-    public AdditionalInformationDTOModule<?, ?> 
recomputeUserJmapPreviewsAdditionalInformation() {
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> recomputeUserJmapPreviewsAdditionalInformation() {
         return 
RecomputeUserFastViewTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
 
-    @Named(EVENT_NESTED_TYPES_INJECTION_NAME)
+    @Named(EventNestedTypes.EVENT_NESTED_TYPES_INJECTION_NAME)
     @Provides
-    public Set<DTOModule<?, ?>> 
eventNestedTypes(Set<AdditionalInformationDTOModule<?, ?>> 
additionalInformationDTOModules,
-                                                 Set<TaskDTOModule<?, ?>> 
taskDTOModules) {
+    public Set<DTOModule<?, ? extends org.apache.james.json.DTO>> 
eventNestedTypes(Set<AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO>> additionalInformationDTOModules,
+                                                                               
    Set<TaskDTOModule<? extends Task, ? extends TaskDTO>> taskDTOModules) {
         return Sets.union(additionalInformationDTOModules, taskDTOModules);
     }
 }
diff --git 
a/server/container/guice/rabbitmq/src/main/java/org/apache/james/modules/rabbitmq/RabbitMQModule.java
 
b/server/container/guice/rabbitmq/src/main/java/org/apache/james/modules/rabbitmq/RabbitMQModule.java
index e887d6a..ea8c317 100644
--- 
a/server/container/guice/rabbitmq/src/main/java/org/apache/james/modules/rabbitmq/RabbitMQModule.java
+++ 
b/server/container/guice/rabbitmq/src/main/java/org/apache/james/modules/rabbitmq/RabbitMQModule.java
@@ -30,6 +30,8 @@ import 
org.apache.james.backends.rabbitmq.RabbitMQConfiguration;
 import org.apache.james.backends.rabbitmq.RabbitMQHealthCheck;
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
 import org.apache.james.core.healthcheck.HealthCheck;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.queue.api.MailQueueFactory;
 import org.apache.james.queue.api.ManageableMailQueue;
@@ -81,7 +83,7 @@ public class RabbitMQModule extends AbstractModule {
         
cassandraModuleBinder.addBinding().toInstance(CassandraMailQueueViewModule.MODULE);
 
         bind(EventsourcingConfigurationManagement.class).in(Scopes.SINGLETON);
-        Multibinder<EventDTOModule<?, ?>> eventDTOModuleBinder = 
Multibinder.newSetBinder(binder(), new TypeLiteral<EventDTOModule<?, ?>>() {});
+        Multibinder<EventDTOModule<? extends Event, ? extends EventDTO>> 
eventDTOModuleBinder = Multibinder.newSetBinder(binder(), new 
TypeLiteral<EventDTOModule<? extends Event, ? extends EventDTO>>() {});
         
eventDTOModuleBinder.addBinding().toInstance(CassandraMailQueueViewConfigurationModule.MAIL_QUEUE_VIEW_CONFIGURATION);
 
         Multibinder.newSetBinder(binder(), 
HealthCheck.class).addBinding().to(RabbitMQHealthCheck.class);
diff --git 
a/server/task/task-distributed/src/main/java/org/apache/james/task/eventsourcing/distributed/TasksSerializationModule.java
 
b/server/task/task-distributed/src/main/java/org/apache/james/task/eventsourcing/distributed/TasksSerializationModule.java
index f158d0f..724d0a1 100644
--- 
a/server/task/task-distributed/src/main/java/org/apache/james/task/eventsourcing/distributed/TasksSerializationModule.java
+++ 
b/server/task/task-distributed/src/main/java/org/apache/james/task/eventsourcing/distributed/TasksSerializationModule.java
@@ -1,4 +1,4 @@
-/** **************************************************************
+/****************************************************************
  * 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        *
@@ -7,7 +7,7 @@
  * "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                   *
+ *   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  *
@@ -15,13 +15,15 @@
  * KIND, either express or implied.  See the License for the    *
  * specific language governing permissions and limitations      *
  * under the License.                                           *
- * ***************************************************************/
+ ****************************************************************/
 
 package org.apache.james.task.eventsourcing.distributed;
 
 import java.util.Set;
 import java.util.stream.Stream;
 
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.json.DTOConverter;
 import org.apache.james.server.task.json.JsonTaskSerializer;
@@ -42,7 +44,7 @@ import com.github.steveash.guavate.Guavate;
 public interface TasksSerializationModule {
     @FunctionalInterface
     interface TaskSerializationModuleFactory {
-        EventDTOModule<?, ?> create(JsonTaskSerializer taskSerializer,
+        EventDTOModule<? extends Event, ? extends EventDTO> 
create(JsonTaskSerializer taskSerializer,
                                     
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
                                     DTOConverter<Task, TaskDTO> dtoConverter);
     }
@@ -103,9 +105,9 @@ public interface TasksSerializationModule {
         .typeName("task-manager-updated")
         .withFactory(EventDTOModule::new);
 
-    static Set<EventDTOModule<?, ?>> list(JsonTaskSerializer 
jsonTaskSerializer,
-                                          
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
-                                          DTOConverter<Task, TaskDTO> 
dtoConverter) {
+    static Set<EventDTOModule<? extends Event, ? extends EventDTO>> 
list(JsonTaskSerializer jsonTaskSerializer,
+                                                                         
DTOConverter<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> additionalInformationConverter,
+                                                                         
DTOConverter<Task, TaskDTO> dtoConverter) {
         return Stream
             .of(CREATED, STARTED, CANCEL_REQUESTED, CANCELLED, COMPLETED, 
FAILED, UPDATED)
             .map(moduleFactory -> moduleFactory.create(jsonTaskSerializer, 
additionalInformationConverter, dtoConverter))
diff --git 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/DistributedTaskManagerTest.java
 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/DistributedTaskManagerTest.java
index 3bc1135..295d27c 100644
--- 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/DistributedTaskManagerTest.java
+++ 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/DistributedTaskManagerTest.java
@@ -35,11 +35,13 @@ import 
org.apache.james.backends.cassandra.init.CassandraZonedDateTimeModule;
 import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
 import org.apache.james.backends.rabbitmq.ReactorRabbitMQChannelPool;
+import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.EventSourcingSystem;
 import org.apache.james.eventsourcing.eventstore.EventStore;
 import 
org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreExtension;
 import 
org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreModule;
 import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.json.DTOConverter;
 import 
org.apache.james.server.task.json.JsonTaskAdditionalInformationSerializer;
@@ -138,7 +140,7 @@ class DistributedTaskManagerTest implements 
TaskManagerContract {
 
     DTOConverter<Task, TaskDTO> taskDTOConverter = new 
DTOConverter<>(taskDTOModules);
 
-    Set<EventDTOModule<?, ?>> eventDtoModule = 
TasksSerializationModule.list(taskSerializer, 
TASK_ADDITIONAL_INFORMATION_DTO_CONVERTER, taskDTOConverter);
+    Set<EventDTOModule<? extends Event, ? extends EventDTO>> eventDtoModule = 
TasksSerializationModule.list(taskSerializer, 
TASK_ADDITIONAL_INFORMATION_DTO_CONVERTER, taskDTOConverter);
 
     @RegisterExtension
     CassandraEventStoreExtension eventStoreExtension = new 
CassandraEventStoreExtension(CASSANDRA_CLUSTER,
diff --git 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQTerminationSubscriberTest.java
 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQTerminationSubscriberTest.java
index dcb5a36..3b7fa9b 100644
--- 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQTerminationSubscriberTest.java
+++ 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/RabbitMQTerminationSubscriberTest.java
@@ -30,6 +30,7 @@ import java.util.Set;
 import org.apache.james.backends.rabbitmq.RabbitMQExtension;
 import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.json.DTOConverter;
 import org.apache.james.server.task.json.JsonTaskSerializer;
@@ -43,7 +44,7 @@ import reactor.core.publisher.Flux;
 
 class RabbitMQTerminationSubscriberTest implements 
TerminationSubscriberContract {
     private static final JsonTaskSerializer TASK_SERIALIZER = 
JsonTaskSerializer.of();
-    private static final Set<EventDTOModule<?, ?>> MODULES = 
TasksSerializationModule.list(TASK_SERIALIZER, DTOConverter.of(), 
DTOConverter.of());
+    private static final Set<EventDTOModule<? extends Event, ? extends 
EventDTO>> MODULES = TasksSerializationModule.list(TASK_SERIALIZER, 
DTOConverter.of(), DTOConverter.of());
     private static final JsonEventSerializer SERIALIZER = 
JsonEventSerializer.forModules(MODULES).withoutNestedType();
 
     @RegisterExtension
diff --git 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/TaskEventsSerializationTest.java
 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/TaskEventsSerializationTest.java
index e7cb068..2444edf 100644
--- 
a/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/TaskEventsSerializationTest.java
+++ 
b/server/task/task-distributed/src/test/java/org/apache/james/task/eventsourcing/distributed/TaskEventsSerializationTest.java
@@ -23,7 +23,9 @@ import java.time.Instant;
 import java.util.Set;
 
 import org.apache.james.JsonSerializationVerifier;
+import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
 import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
 import org.apache.james.json.DTOConverter;
 import org.apache.james.json.JsonGenericSerializer;
@@ -60,7 +62,7 @@ class TaskEventsSerializationTest {
     static final Hostname HOSTNAME = new Hostname("foo");
     static final MemoryReferenceWithCounterTask.AdditionalInformation 
COUNTER_ADDITIONAL_INFORMATION = new 
MemoryReferenceWithCounterTask.AdditionalInformation(3, TIMESTAMP);
 
-    private final Set<EventDTOModule<?, ?>> list = 
TasksSerializationModule.list(
+    private final Set<EventDTOModule<? extends Event, ? extends EventDTO>> 
list = TasksSerializationModule.list(
         JsonTaskSerializer.of(
             TestTaskDTOModules.COMPLETED_TASK_MODULE,
             
TestTaskDTOModules.MEMORY_REFERENCE_WITH_COUNTER_TASK_MODULE.apply(new 
MemoryReferenceWithCounterTaskStore())),
@@ -71,7 +73,7 @@ class TaskEventsSerializationTest {
     void taskManagerEventsShouldBeSerializable() throws Exception {
         JsonSerializationVerifier.serializer(JsonGenericSerializer
             .forModules(list)
-            .withNestedTypeModules(
+            .withMultipleNestedTypeModules(
                 
MemoryReferenceWithCounterTaskAdditionalInformationDTO.SERIALIZATION_MODULE,
                 TestTaskDTOModules.COMPLETED_TASK_MODULE))
             .testCase(new Created(AGGREGATE_ID, EVENT_ID, TASK, HOSTNAME),
diff --git 
a/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskAdditionalInformationSerializer.java
 
b/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskAdditionalInformationSerializer.java
index 52c0608..8019e7a 100644
--- 
a/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskAdditionalInformationSerializer.java
+++ 
b/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskAdditionalInformationSerializer.java
@@ -33,7 +33,7 @@ import com.google.common.collect.ImmutableSet;
 
 public class JsonTaskAdditionalInformationSerializer {
 
-    public static JsonTaskAdditionalInformationSerializer 
of(AdditionalInformationDTOModule<?, ?>... modules) {
+    public static JsonTaskAdditionalInformationSerializer 
of(AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends 
AdditionalInformationDTO>... modules) {
         return new 
JsonTaskAdditionalInformationSerializer(ImmutableSet.copyOf(modules));
     }
 
@@ -52,7 +52,7 @@ public class JsonTaskAdditionalInformationSerializer {
     private JsonGenericSerializer<TaskExecutionDetails.AdditionalInformation, 
AdditionalInformationDTO> jsonGenericSerializer;
 
     @Inject
-    private 
JsonTaskAdditionalInformationSerializer(Set<AdditionalInformationDTOModule<?, 
?>> modules) {
+    private 
JsonTaskAdditionalInformationSerializer(Set<AdditionalInformationDTOModule<? 
extends TaskExecutionDetails.AdditionalInformation, ? extends 
AdditionalInformationDTO>> modules) {
         jsonGenericSerializer = 
JsonGenericSerializer.forModules(modules).withoutNestedType();
     }
 
diff --git 
a/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskSerializer.java
 
b/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskSerializer.java
index f87bcff..2c5cceb 100644
--- 
a/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskSerializer.java
+++ 
b/server/task/task-json/src/main/java/org/apache/james/server/task/json/JsonTaskSerializer.java
@@ -55,7 +55,7 @@ public class JsonTaskSerializer {
 
     @Inject
     @VisibleForTesting
-    public JsonTaskSerializer(Set<TaskDTOModule<?, ?>> modules) {
+    public JsonTaskSerializer(Set<TaskDTOModule<? extends Task, ? extends 
TaskDTO>> modules) {
         jsonGenericSerializer = 
JsonGenericSerializer.forModules(modules).withoutNestedType();
     }
 


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

Reply via email to