JAMES-2363 Use MimeMessageWrapper usages to ensure MessageID is not overridden


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/d4a75754
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/d4a75754
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/d4a75754

Branch: refs/heads/master
Commit: d4a75754906200fdc586b2bfb3c3caacc33da74e
Parents: 3d8724e
Author: benwa <[email protected]>
Authored: Mon Mar 26 15:37:36 2018 +0700
Committer: benwa <[email protected]>
Committed: Thu Mar 29 16:43:03 2018 +0700

----------------------------------------------------------------------
 .../james/core/builder/MimeMessageBuilder.java  | 23 ++++-
 .../james/core/builder/MimeMessageWrapper.java  | 70 ++++++++++++++++
 .../core/builder/MimeMessageWrapperTest.java    | 88 ++++++++++++++++++++
 .../src/main/java/org/apache/mailet/Mail.java   |  2 +-
 .../james/transport/mailets/LogMessageTest.java | 13 ++-
 .../transport/mailets/ReplaceContentTest.java   |  9 +-
 .../transport/mailets/StripAttachmentTest.java  | 13 +--
 .../org/apache/james/server/core/MailImpl.java  | 14 ++--
 .../core/MimeMessageCopyOnWriteProxy.java       |  2 +-
 .../server/core/MimeMessageWrapperTest.java     | 18 ++++
 .../mailrepository/file/MBoxMailRepository.java |  4 +-
 11 files changed, 232 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/core/src/main/java/org/apache/james/core/builder/MimeMessageBuilder.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/james/core/builder/MimeMessageBuilder.java 
b/core/src/main/java/org/apache/james/core/builder/MimeMessageBuilder.java
index 7cf181d..303743e 100644
--- a/core/src/main/java/org/apache/james/core/builder/MimeMessageBuilder.java
+++ b/core/src/main/java/org/apache/james/core/builder/MimeMessageBuilder.java
@@ -25,6 +25,7 @@ import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Properties;
 
@@ -60,6 +61,22 @@ public class MimeMessageBuilder {
             this.name = name;
             this.value = value;
         }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof Header) {
+                Header header = (Header) o;
+
+                return Objects.equals(this.name, header.name)
+                    && Objects.equals(this.value, header.value);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(name, value);
+        }
     }
 
     public static class MultipartBuilder {
@@ -380,8 +397,10 @@ public class MimeMessageBuilder {
         for (Header header: headerList) {
             mimeMessage.addHeader(header.name, header.value);
         }
-        mimeMessage.saveChanges();
-        return mimeMessage;
+
+        MimeMessage wrappedMessage = MimeMessageWrapper.wrap(mimeMessage);
+        wrappedMessage.saveChanges();
+        return wrappedMessage;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/core/src/main/java/org/apache/james/core/builder/MimeMessageWrapper.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/james/core/builder/MimeMessageWrapper.java 
b/core/src/main/java/org/apache/james/core/builder/MimeMessageWrapper.java
new file mode 100644
index 0000000..8e66bec
--- /dev/null
+++ b/core/src/main/java/org/apache/james/core/builder/MimeMessageWrapper.java
@@ -0,0 +1,70 @@
+/****************************************************************
+ * 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.core.builder;
+
+import java.util.Collections;
+import java.util.Properties;
+
+import javax.mail.Header;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.MimeMessage;
+
+import com.github.fge.lambdas.Throwing;
+import com.github.fge.lambdas.consumers.ThrowingConsumer;
+
+public class MimeMessageWrapper extends MimeMessage {
+
+    public static MimeMessageWrapper wrap(MimeMessage mimeMessage) throws 
MessagingException {
+        try {
+            return new MimeMessageWrapper(mimeMessage);
+        } catch (MessagingException e) {
+            // Copying a mime message fails when the body is empty
+            // Copying manually the headers is the best alternative...
+
+            MimeMessageWrapper result = new MimeMessageWrapper();
+            ThrowingConsumer<Header> consumer = header -> 
result.addHeader(header.getName(), header.getValue());
+            Collections.list(mimeMessage.getAllHeaders())
+                .forEach(Throwing.consumer(consumer).sneakyThrow());
+            return result;
+        }
+    }
+
+    private MimeMessageWrapper() {
+        super(Session.getDefaultInstance(new Properties()));
+    }
+
+    private MimeMessageWrapper(MimeMessage mimeMessage) throws 
MessagingException {
+        super(mimeMessage);
+    }
+
+    /**
+     * Overrides default javamail behaviour by not altering the Message-ID by
+     * default, see <a 
href="https://issues.apache.org/jira/browse/JAMES-875";>JAMES-875</a> and
+     * <a 
href="https://issues.apache.org/jira/browse/JAMES-1010";>JAMES-1010</a>
+     */
+    @Override
+    protected void updateMessageID() throws MessagingException {
+        if (getMessageID() == null) {
+            super.updateMessageID();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/core/src/test/java/org/apache/james/core/builder/MimeMessageWrapperTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/james/core/builder/MimeMessageWrapperTest.java 
b/core/src/test/java/org/apache/james/core/builder/MimeMessageWrapperTest.java
new file mode 100644
index 0000000..230763c
--- /dev/null
+++ 
b/core/src/test/java/org/apache/james/core/builder/MimeMessageWrapperTest.java
@@ -0,0 +1,88 @@
+/****************************************************************
+ * 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.core.builder;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Properties;
+
+import javax.mail.Session;
+import javax.mail.internet.MimeMessage;
+
+import org.junit.Test;
+
+public class MimeMessageWrapperTest {
+
+    @Test
+    public void saveChangesShouldPreserveMessageId() throws Exception {
+        String messageId = "<[email protected]>";
+        String messageText = "Message-ID: " + messageId + "\r\n" +
+            "Subject: test\r\n" +
+            "\r\n" +
+            "Content!";
+        InputStream inputStream = new 
ByteArrayInputStream(messageText.getBytes(StandardCharsets.UTF_8));
+        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new 
Properties()), inputStream);
+        MimeMessageWrapper mimeMessageWrapper = 
MimeMessageWrapper.wrap(message);
+
+        mimeMessageWrapper.saveChanges();
+
+        assertThat(mimeMessageWrapper.getMessageID())
+            .isEqualTo(messageId);
+    }
+
+    @Test
+    public void wrapShouldPreserveBody() throws Exception {
+        String messageAsText = "header1: <[email protected]>\r\n" +
+            "Subject: test\r\n" +
+            "\r\n" +
+            "Content!";
+        InputStream inputStream = new 
ByteArrayInputStream(messageAsText.getBytes(StandardCharsets.UTF_8));
+        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new 
Properties()), inputStream);
+        MimeMessageWrapper mimeMessageWrapper = 
MimeMessageWrapper.wrap(message);
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+        mimeMessageWrapper.writeTo(outputStream);
+
+        assertThat(new String(outputStream.toByteArray(), 
StandardCharsets.UTF_8))
+            .isEqualTo(messageAsText);
+    }
+
+    @Test
+    public void wrapShouldNotThrowWhenNoBody() throws Exception {
+        MimeMessage originalMessage = new 
MimeMessage(Session.getDefaultInstance(new Properties()));
+        originalMessage.addHeader("header1", "value1");
+        originalMessage.addHeader("header2", "value2");
+        originalMessage.addHeader("header2", "value3");
+        MimeMessageWrapper mimeMessageWrapper = 
MimeMessageWrapper.wrap(originalMessage);
+
+        assertThat(Collections.list(mimeMessageWrapper.getAllHeaders()))
+            .extracting(javaxHeader -> new 
MimeMessageBuilder.Header(javaxHeader.getName(), javaxHeader.getValue()))
+            .contains(new MimeMessageBuilder.Header("header1", "value1"),
+                new MimeMessageBuilder.Header("header2", "value2"),
+                new MimeMessageBuilder.Header("header2", "value3"));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/mailet/api/src/main/java/org/apache/mailet/Mail.java
----------------------------------------------------------------------
diff --git a/mailet/api/src/main/java/org/apache/mailet/Mail.java 
b/mailet/api/src/main/java/org/apache/mailet/Mail.java
index 3ffcaa4..23a0918 100644
--- a/mailet/api/src/main/java/org/apache/mailet/Mail.java
+++ b/mailet/api/src/main/java/org/apache/mailet/Mail.java
@@ -165,7 +165,7 @@ public interface Mail extends Serializable, Cloneable {
      *
      * @param message the new message that this Mail instance will wrap
      */
-    void setMessage(MimeMessage message);
+    void setMessage(MimeMessage message) throws MessagingException;
     
     /**
      * Sets the state of this message.

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/mailet/standard/src/test/java/org/apache/james/transport/mailets/LogMessageTest.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/LogMessageTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/LogMessageTest.java
index ef03a8f..033231e 100644
--- 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/LogMessageTest.java
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/LogMessageTest.java
@@ -28,7 +28,10 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import java.util.Properties;
+
 import javax.mail.MessagingException;
+import javax.mail.Session;
 import javax.mail.internet.MimeMessage;
 
 import org.apache.james.core.builder.MimeMessageBuilder;
@@ -81,11 +84,13 @@ class LogMessageTest {
                 .build();
         mailet.init(mailetConfig);
 
+        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new 
Properties()));
+        message.addHeader("Date", "Tue, 16 Jan 2018 10:23:03 +0100");
+        message.setSubject("subject");
+        message.setText("This is a fake mail");
+
         mailet.service(FakeMail.builder()
-                .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .addHeader("Date", "Tue, 16 Jan 2018 10:23:03 +0100")
-                    .setSubject("subject")
-                    .setText("This is a fake mail"))
+                .mimeMessage(message)
                 .build());
 
         verify(logger).info("Logging mail {}", (Object) null);

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/mailet/standard/src/test/java/org/apache/james/transport/mailets/ReplaceContentTest.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/ReplaceContentTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/ReplaceContentTest.java
index 508c4c1..7631b33 100644
--- 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/ReplaceContentTest.java
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/ReplaceContentTest.java
@@ -22,7 +22,9 @@ package org.apache.james.transport.mailets;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.nio.charset.StandardCharsets;
+import java.util.Properties;
 
+import javax.mail.Session;
 import javax.mail.internet.MimeMessage;
 
 import org.apache.james.core.builder.MimeMessageBuilder;
@@ -78,10 +80,11 @@ public class ReplaceContentTest {
                 .build();
         mailet.init(mailetConfig);
 
+        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new 
Properties()));
+        message.setText("This is one simple test/ è one simple test.\n"
+            + "Blo blo blo blo.\n");
         Mail mail = FakeMail.builder()
-                .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setText("This is one simple test/ è one simple test.\n"
-                        + "Blo blo blo blo.\n"))
+                .mimeMessage(message)
                 .build();
         mailet.service(mail);
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
index 71ec927..850561c 100644
--- 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
@@ -34,6 +34,7 @@ import java.util.Map;
 import java.util.Optional;
 
 import javax.mail.MessagingException;
+import javax.mail.Multipart;
 import javax.mail.Part;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
@@ -686,19 +687,19 @@ class StripAttachmentTest {
                 .build();
         mailet.init(mci);
 
-        MimeMultipart mimeMultipart = MimeMessageBuilder.multipartBuilder()
-            .addBody(MimeMessageBuilder.bodyPartBuilder()
-                .filename("removeMe.tmp"))
-            .build();
         MimeMessage mimeMessage = MimeMessageBuilder.mimeMessageBuilder()
-            .setContent(mimeMultipart)
+            .setContent(MimeMessageBuilder.multipartBuilder()
+                .addBody(MimeMessageBuilder.bodyPartBuilder()
+                    .filename("removeMe.tmp")))
             .build();
 
         Mail mail = mock(Mail.class);
         //When
         mailet.processMultipartPartMessage(mimeMessage, mail);
         //Then
-        assertThat(mimeMultipart.getCount()).isZero();
+        assertThat(mimeMessage.getContent()).isInstanceOf(MimeMultipart.class);
+        MimeMultipart multipart = (MimeMultipart) mimeMessage.getContent();
+        assertThat(multipart.getCount()).isZero();
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java
----------------------------------------------------------------------
diff --git 
a/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java
 
b/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java
index 9521784..816c9e6 100644
--- 
a/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java
+++ 
b/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java
@@ -231,7 +231,7 @@ public class MailImpl implements Disposable, Mail {
 
         public MailImpl build() {
             MailImpl mail = new MailImpl();
-            mimeMessage.ifPresent(mail::setMessage);
+            
mimeMessage.ifPresent(Throwing.consumer(mail::setMessage).sneakyThrow());
             name.ifPresent(mail::setName);
             sender.ifPresent(mail::setSender);
             mail.setRecipients(recipients);
@@ -323,7 +323,7 @@ public class MailImpl implements Disposable, Mail {
     /**
      * The MimeMessage that holds the mail data.
      */
-    private MimeMessage message;
+    private MimeMessageCopyOnWriteProxy message;
     /**
      * The sender of this mail.
      */
@@ -437,7 +437,7 @@ public class MailImpl implements Disposable, Mail {
      * A constructor that creates a MailImpl with the specified name, sender,
      * recipients, and MimeMessage.
      */
-    public MailImpl(String name, MailAddress sender, Collection<MailAddress> 
recipients, MimeMessage message) {
+    public MailImpl(String name, MailAddress sender, Collection<MailAddress> 
recipients, MimeMessage message) throws MessagingException {
         this(name, sender, recipients);
         this.setMessage(new MimeMessageCopyOnWriteProxy(message));
     }
@@ -538,7 +538,7 @@ public class MailImpl implements Disposable, Mail {
      * @param message the new MimeMessage associated with this MailImpl
      */
     @Override
-    public void setMessage(MimeMessage message) {
+    public void setMessage(MimeMessage message) throws MessagingException {
 
         // TODO: We should use the MimeMessageCopyOnWriteProxy
         // everytime we set the MimeMessage. We should
@@ -551,7 +551,11 @@ public class MailImpl implements Disposable, Mail {
             if (this.message != null) {
                 LifecycleUtil.dispose(this.message);
             }
-            this.message = message;
+            if (message instanceof MimeMessageCopyOnWriteProxy) {
+                this.message = (MimeMessageCopyOnWriteProxy) message;
+            } else {
+                this.message = new MimeMessageCopyOnWriteProxy(message);
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/server/container/core/src/main/java/org/apache/james/server/core/MimeMessageCopyOnWriteProxy.java
----------------------------------------------------------------------
diff --git 
a/server/container/core/src/main/java/org/apache/james/server/core/MimeMessageCopyOnWriteProxy.java
 
b/server/container/core/src/main/java/org/apache/james/server/core/MimeMessageCopyOnWriteProxy.java
index 3a8ede4..cc375e9 100644
--- 
a/server/container/core/src/main/java/org/apache/james/server/core/MimeMessageCopyOnWriteProxy.java
+++ 
b/server/container/core/src/main/java/org/apache/james/server/core/MimeMessageCopyOnWriteProxy.java
@@ -91,7 +91,7 @@ public class MimeMessageCopyOnWriteProxy extends MimeMessage 
implements Disposab
 
     protected MessageReferenceTracker refCount;
 
-    public MimeMessageCopyOnWriteProxy(MimeMessage original) {
+    public MimeMessageCopyOnWriteProxy(MimeMessage original) throws 
MessagingException {
         this(original, false);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageWrapperTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageWrapperTest.java
 
b/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageWrapperTest.java
index 0385a1b..617ca4d 100644
--- 
a/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageWrapperTest.java
+++ 
b/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageWrapperTest.java
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.james.server.core;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -36,6 +37,7 @@ import javax.mail.internet.MimeMessage;
 import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.lifecycle.api.LifecycleUtil;
+import org.apache.james.util.MimeMessageUtil;
 import org.apache.mailet.base.RFC2822Headers;
 import org.junit.After;
 import org.junit.Before;
@@ -283,4 +285,20 @@ public class MimeMessageWrapperTest extends 
MimeMessageFromStreamTest {
         MimeMessageWrapper wrapper = new MimeMessageWrapper(message);
         assertEquals("\"base64\"", wrapper.getEncoding());
     }
+
+    @Test
+    public void saveChangesShouldPreserveMessageId() throws Exception {
+        String messageId = "<[email protected]>";
+        MimeMessage message = 
MimeMessageUtil.mimeMessageFromString("Message-ID: " + messageId + "\r\n" +
+            "Subject: test\r\n" +
+            "\r\n" +
+            "Content!");
+
+        MimeMessageWrapper mimeMessageWrapper = new 
MimeMessageWrapper(message);
+
+        mimeMessageWrapper.saveChanges();
+
+        assertThat(mimeMessageWrapper.getMessageID())
+            .isEqualTo(messageId);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4a75754/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/MBoxMailRepository.java
----------------------------------------------------------------------
diff --git 
a/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/MBoxMailRepository.java
 
b/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/MBoxMailRepository.java
index caed732..bcc69bb 100755
--- 
a/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/MBoxMailRepository.java
+++ 
b/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/MBoxMailRepository.java
@@ -526,7 +526,7 @@ public class MBoxMailRepository implements MailRepository, 
Configurable {
     }
 
     @Override
-    public Mail retrieve(String key) {
+    public Mail retrieve(String key) throws MessagingException {
 
         loadKeys();
         MailImpl res;
@@ -669,7 +669,7 @@ public class MBoxMailRepository implements MailRepository, 
Configurable {
     }
 
     @Override
-    public void remove(String key) {
+    public void remove(String key) throws MessagingException {
         loadKeys();
         try {
             lockMBox();


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to