You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/06/01 02:36:13 UTC
[james-project] 02/03: JAMES-3197 Mailet processing should handle
NoClassDefFoundError
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 5c5c9b180cc9bbf63157bc871827a5a513592545
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri May 29 12:19:07 2020 +0700
JAMES-3197 Mailet processing should handle NoClassDefFoundError
Due to JAMES-3176, we ended up having ExtractMDNOriginalJMAPMessageId throwing NoClassDefFoundError.
This error is not handled by the mailet processor, resulting in a mailqueue nack, and generated an infinite loop on top of RabbitMQ.
This error can happen too when a user specifies a custom mailet with unsatisfied dependencies.
Thus, when a mailet, or a matcher throws a `NoClassDefFoundError` we should execute mailet error handling normally, and prevent that infinite loop.
---
.../org/apache/james/mailets/MailetErrorsTest.java | 22 +++++++++++++++
.../mailets/NoClassDefFoundErrorMailet.java | 32 ++++++++++++++++++++++
.../james/mailetcontainer/impl/ProcessorUtil.java | 4 +--
.../mailetcontainer/impl/camel/CamelProcessor.java | 4 +--
.../impl/jmx/JMXStateMailetProcessorListener.java | 2 +-
.../lib/AbstractStateMailetProcessor.java | 2 +-
.../lib/AbstractStateMailetProcessorTest.java | 10 +++----
7 files changed, 65 insertions(+), 11 deletions(-)
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/MailetErrorsTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/MailetErrorsTest.java
index c5e13dc..175b4c4 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/MailetErrorsTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/MailetErrorsTest.java
@@ -32,8 +32,10 @@ import org.apache.james.mailets.configuration.MailetContainer;
import org.apache.james.mailets.configuration.ProcessorConfiguration;
import org.apache.james.mailrepository.api.MailRepositoryUrl;
import org.apache.james.modules.protocols.SmtpGuiceProbe;
+import org.apache.james.transport.mailets.NoClassDefFoundErrorMailet;
import org.apache.james.transport.mailets.ErrorMailet;
import org.apache.james.transport.mailets.ErrorMatcher;
+import org.apache.james.transport.mailets.NoClassDefFoundErrorMatcher;
import org.apache.james.transport.mailets.NoopMailet;
import org.apache.james.transport.mailets.Null;
import org.apache.james.transport.mailets.RuntimeErrorMailet;
@@ -86,6 +88,26 @@ public class MailetErrorsTest {
}
@Test
+ public void mailetProcessingShouldHandleClassNotFoundException() throws Exception {
+ jamesServer = TemporaryJamesServer.builder()
+ .withBase(SMTP_ONLY_MODULE)
+ .withMailetContainer(MailetContainer.builder()
+ .putProcessor(CommonProcessors.deliverOnlyTransport())
+ .putProcessor(errorProcessor())
+ .putProcessor(ProcessorConfiguration.root()
+ .addMailet(MailetConfiguration.builder()
+ .matcher(All.class)
+ .mailet(NoClassDefFoundErrorMailet.class))))
+ .build(temporaryFolder.newFolder());
+ MailRepositoryProbeImpl probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
+
+ smtpMessageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort()).sendMessage(FROM, FROM);
+
+ awaitAtMostOneMinute.until(() -> probe.getRepositoryMailCount(ERROR_REPOSITORY) == 1);
+ }
+
+
+ @Test
public void mailetProcessorsShouldHandleRuntimeException() throws Exception {
jamesServer = TemporaryJamesServer.builder()
.withBase(SMTP_ONLY_MODULE)
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/NoClassDefFoundErrorMailet.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/NoClassDefFoundErrorMailet.java
new file mode 100644
index 0000000..b173183
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/NoClassDefFoundErrorMailet.java
@@ -0,0 +1,32 @@
+/****************************************************************
+ * 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;
+
+import javax.mail.MessagingException;
+
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.GenericMailet;
+
+public class NoClassDefFoundErrorMailet extends GenericMailet {
+ @Override
+ public void service(Mail mail) throws MessagingException {
+ throw new NoClassDefFoundError();
+ }
+}
diff --git a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorUtil.java b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorUtil.java
index fda19fd..787b464 100644
--- a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorUtil.java
+++ b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorUtil.java
@@ -47,13 +47,13 @@ public class ProcessorUtil {
* @param nextState
* the next state to set
*/
- public static void handleException(Exception me, Mail mail, String offendersName, String nextState, Logger logger) {
+ public static void handleException(Throwable me, Mail mail, String offendersName, String nextState, Logger logger) {
mail.setState(nextState);
StringWriter sout = new StringWriter();
PrintWriter out = new PrintWriter(sout, true);
String exceptionBuffer = "Exception calling " + offendersName + ": " + me.getMessage();
out.println(exceptionBuffer);
- Exception e = me;
+ Throwable e = me;
while (e != null) {
e.printStackTrace(out);
if (e instanceof MessagingException) {
diff --git a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/CamelProcessor.java b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/CamelProcessor.java
index 678b938..a46001a 100644
--- a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/CamelProcessor.java
+++ b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/CamelProcessor.java
@@ -61,7 +61,7 @@ public class CamelProcessor {
public void process(Mail mail) throws Exception {
long start = System.currentTimeMillis();
TimeMetric timeMetric = metricFactory.timer(mailet.getClass().getSimpleName());
- Exception ex = null;
+ Throwable ex = null;
try (Closeable closeable =
MDCBuilder.create()
.addContext(MDCBuilder.PROTOCOL, "MAILET")
@@ -75,7 +75,7 @@ public class CamelProcessor {
.build()) {
MailetPipelineLogging.logBeginOfMailetProcess(mailet, mail);
mailet.service(mail);
- } catch (Exception me) {
+ } catch (Exception | NoClassDefFoundError me) {
ex = me;
String onMailetException = null;
diff --git a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
index 38fe438..7840c4d 100644
--- a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
+++ b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
@@ -61,7 +61,7 @@ public class JMXStateMailetProcessorListener implements MailetProcessorListener,
}
@Override
- public void afterMailet(Mailet m, String mailName, String state, long processTime, Exception e) {
+ public void afterMailet(Mailet m, String mailName, String state, long processTime, Throwable e) {
MailetManagement mgmt = mailetMap.get(m);
if (mgmt != null) {
mgmt.update(processTime, e == null);
diff --git a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
index 45db8ad..0d6a399 100644
--- a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
+++ b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
@@ -404,7 +404,7 @@ public abstract class AbstractStateMailetProcessor implements MailProcessor, Con
* @param e
* or null if no Exception was thrown
*/
- void afterMailet(Mailet m, String mailName, String state, long processTime, Exception e);
+ void afterMailet(Mailet m, String mailName, String state, long processTime, Throwable e);
/**
* Get called after each {@link Matcher} call was complete
diff --git a/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java b/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
index 4894fa7..c76a019 100644
--- a/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
+++ b/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
@@ -85,7 +85,7 @@ public abstract class AbstractStateMailetProcessorTest {
}
@Override
- public void afterMailet(Mailet m, String mailName, String state, long processTime, Exception e) {
+ public void afterMailet(Mailet m, String mailName, String state, long processTime, Throwable e) {
// check for class name as the terminating mailet will kick in too
if (MockMailet.class.equals(m.getClass())) {
@@ -130,7 +130,7 @@ public abstract class AbstractStateMailetProcessorTest {
}
@Override
- public void afterMailet(Mailet m, String mailName, String state, long processTime, Exception e) {
+ public void afterMailet(Mailet m, String mailName, String state, long processTime, Throwable e) {
// check for class name as the terminating mailet will kick in too
if (MockMailet.class.equals(m.getClass())) {
@@ -177,7 +177,7 @@ public abstract class AbstractStateMailetProcessorTest {
}
@Override
- public void afterMailet(Mailet m, String mailName, String state, long processTime, Exception e) {
+ public void afterMailet(Mailet m, String mailName, String state, long processTime, Throwable e) {
throw new RuntimeException("Should not call any mailet!");
}
});
@@ -212,7 +212,7 @@ public abstract class AbstractStateMailetProcessorTest {
}
@Override
- public void afterMailet(Mailet m, String mailName, String state, long processTime, Exception e) {
+ public void afterMailet(Mailet m, String mailName, String state, long processTime, Throwable e) {
throw new RuntimeException("Should not call any mailet!");
}
});
@@ -249,7 +249,7 @@ public abstract class AbstractStateMailetProcessorTest {
}
@Override
- public void afterMailet(Mailet m, String mailName, String state, long processTime, Exception e) {
+ public void afterMailet(Mailet m, String mailName, String state, long processTime, Throwable e) {
if (ExceptionThrowingMailet.class.equals(m.getClass())) {
// the name should be not the same as we have a part match
assertThat(mail.getName()).isNotEqualTo(mailName);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org