Hi Eric,

As suggested, JIRA filed as MAILBOX-199.

FYI, the Draft-flag problem I mentioned turned out to be a red herring, the client simply doesn't respect that flag.

The new challenge is a failure when trying to upload a large corpus of mail (and dir hierarchy) from another server, but I'm still looking into this - it may be another illegal-char issue, or in name generation at high frequency (not enough uniqueness)? I'll post more when I know more.

Robin Bankhead

Quoting Eric Charles <e...@apache.org>:

Hi Robin, Thx for the follow-up.

Explicitly calling System.gc can bring global bad performance, so it should be called only in case of windows platform.

The best is to create a JIRA (if not already existing) and attach there your patch.

On 18/09/13 22:00, Robin Bankhead wrote:
Hi,

An update and another patch.  I've found that doing GC before attempting
the file move/rename operation allows it to succeed in every permutation
I've tried so far.  The patch implements this in
MaildirMessageMapper.updateFlags(), giving it 5 tries (this may be
excessive, I dunno; next time I'll check how many tries it takes).

NB: I switched from FileUtils.moveFile() to File.renameTo() just for the
sake of constructing a quick test since it has a boolean return value; I
did already try just drop-in replacing it (without the loop), and it
also failed.

I *think* this means there's an unreleased File{In,Out}putStream lurking
somewhere that needs to be found but, from what I've read, I'm still not
sure that I can rule out Windows itself holding the lock even when
release() has been explicitly called, which some commentators on the
subject seem convinced of.

It's still reporting all messages as Draft, so I shall busy myself
investigating that in the meantime.

Regards,
Robin Bankhead

PS - yes, the test classes were also hackishly adjusted for semicolons
instead of colons. I don't see much point doing this elegantly
unless/until this issue goes somewhere, plus I'm not sure how best to do
so :/


# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to:
C:\srv\apache-james-mailbox-trunk\trunk\maildir
# This patch can be applied using context Tools: Patch action on
respective folder.
# It uses platform neutral UTF-8 encoding and \n newlines.
# Above lines and this line are ignored by the patching process.
Index:
src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java

---
src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
Base (BASE)
+++
src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
Locally Modified (Based On LOCAL)
@@ -216,7 +216,14 @@
                     // if the flags don't have change we should not
try to move
                     // the file
                     if (newMessageFile.equals(messageFile) == false) {
-                        FileUtils.moveFile(messageFile, newMessageFile);
+                        byte tries = 0;
+                        while (!messageFile.renameTo(newMessageFile)) {
+                            if(++tries >= 5) {
+                                throw new IOException("Failed renaming
'" + messageFile +
+                                 "' to '" + newMessageFile + "' :(");
+                            }
+                            System.gc();
+                        }
                         modSeq = newMessageFile.lastModified();

                     } else {
Index: src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java
--- src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java
Base (BASE)
+++ src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java
Locally Modified (Based On LOCAL)
@@ -729,7 +729,7 @@
     public static String stripMetaFromName(String fileName) {
         int end = fileName.indexOf(",S="); // the size
         if (end == -1)
-            end = fileName.indexOf(":2,"); // the flags
+            end = fileName.indexOf(MaildirMessageName.FLAG_PREFIX +
"2,"); // the flags
         if (end == -1)
             return fileName; // there is no meta data to strip
         return fileName.substring(0, end);
Index:
src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java
---
src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java
Base (BASE)
+++
src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java
Locally Modified (Based On LOCAL)
@@ -41,20 +41,25 @@
     public static final String FLAG_SEEN = "S";
     public static final String FLAG_DELETED = "T";

+    // Character used instead of ":" for Windows filesystems.
+    // Using java.io.File.pathSeparator which = ":" on *NIX
+    // and ";" on Windows.
+    public static final String FLAG_PREFIX = File.pathSeparator;
+
     // patterns
     public static final String PATTERN_STRING_MESSAGE_NAME =
"\\d+\\.\\w+\\..+?";
-    public static final String PATTERN_STRING_FLAGS = ":2,[DFRST]*";
+    public static final String PATTERN_STRING_FLAGS = FLAG_PREFIX +
"2,[DFRST]*";
     public static final String PATTERN_STRING_SIZE = ",S=\\d+";
     public static final Pattern PATTERN_MESSAGE =
         Pattern.compile(PATTERN_STRING_MESSAGE_NAME +
optional(PATTERN_STRING_SIZE) + optional(PATTERN_STRING_FLAGS));

     public static final Pattern PATTERN_UNSEEN_MESSAGES =
-        Pattern.compile(PATTERN_STRING_MESSAGE_NAME +
PATTERN_STRING_SIZE + optional(":2,[^S]*"));
+        Pattern.compile(PATTERN_STRING_MESSAGE_NAME +
PATTERN_STRING_SIZE + optional(FLAG_PREFIX + "2,[^S]*"));

     public static final FilenameFilter FILTER_UNSEEN_MESSAGES =
createRegexFilter(PATTERN_UNSEEN_MESSAGES);

     public static final Pattern PATTERN_DELETED_MESSAGES =
-        Pattern.compile(PATTERN_STRING_MESSAGE_NAME +
PATTERN_STRING_SIZE + ":2,.*" + FLAG_DELETED);
+        Pattern.compile(PATTERN_STRING_MESSAGE_NAME +
PATTERN_STRING_SIZE + FLAG_PREFIX + "2,.*" + FLAG_DELETED);

     public static final FilenameFilter FILTER_DELETED_MESSAGES =
createRegexFilter(PATTERN_DELETED_MESSAGES);

@@ -250,7 +255,7 @@
      * into its components hostname, size and flags and fills the
respective variables.
      */
     private void splitHostNameAndMeta() {
-        String[] hostnamemetaFlags = hostnameAndMeta.split(":", 2);
+        String[] hostnamemetaFlags = hostnameAndMeta.split(FLAG_PREFIX,
2);
         if (hostnamemetaFlags.length >= 1) {
           this.hostnameAndMeta = hostnamemetaFlags[0];
           int firstEnd = hostnameAndMeta.indexOf(',');
@@ -272,7 +277,7 @@
         }

         if (hostnamemetaFlags.length >= 2) {
-            this.flagsString = ":" + hostnamemetaFlags[1];
+            this.flagsString = FLAG_PREFIX + hostnamemetaFlags[1];
         }
         if (isMessageNameStrictParse()) {
             if (sizeString == null) {
@@ -364,7 +369,7 @@
      * @return A String valid for Maildir
      */
     public String encodeFlags(Flags flags) {
-        StringBuilder localFlagsString = new StringBuilder(":2,");
+        StringBuilder localFlagsString = new StringBuilder(FLAG_PREFIX
+ "2,");
         if (flags.contains(Flags.Flag.DRAFT))
             localFlagsString.append(FLAG_DRAFT);
         if (flags.contains(Flags.Flag.FLAGGED))
Index:
src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java
---
src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java
Base (BASE)
+++
src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java
Locally Modified (Based On LOCAL)
@@ -48,34 +48,34 @@
     public static List<Object[]> testData() {
         List<Object[]> args = new ArrayList<Object[]>();
         // no size, two flags
-        Parts parts =
Parts.fullName("1328026049.19146_0.km1111:2,RS").timeSeconds(1328026049)
+        Parts parts =
Parts.fullName("1328026049.19146_0.km1111;2,RS").timeSeconds(1328026049)

.baseName("1328026049.19146_0.km1111").flagAnswered().flagSeen();
         args.add(valid(parts));

         // size and flag
-        parts =
Parts.fullName("1328613172.M569643P1862V0000000000000902I00EE42CE_0.km1111,S=13103:2,S")

+        parts =
Parts.fullName("1328613172.M569643P1862V0000000000000902I00EE42CE_0.km1111,S=13103;2,S")

                 .timeSeconds(1328613172).size(13103L)

.baseName("1328613172.M569643P1862V0000000000000902I00EE42CE_0.km1111").flagSeen();

         args.add(valid(parts));

         // size, no flags
-        parts =
Parts.fullName("1340124194.M723289P3184V0000000000000902I006780E9_6.km1111,S=1344:2,")

+        parts =
Parts.fullName("1340124194.M723289P3184V0000000000000902I006780E9_6.km1111,S=1344;2,")


.baseName("1340124194.M723289P3184V0000000000000902I006780E9_6.km1111").timeSeconds(1340124194)

                 .size(1344L);
         args.add(valid(parts));

         // three flags, no size
-        parts =
Parts.fullName("1106685752.12132_0.km1111:2,FRS").baseName("1106685752.12132_0.km1111")

+        parts =
Parts.fullName("1106685752.12132_0.km1111;2,FRS").baseName("1106685752.12132_0.km1111")


.timeSeconds(1106685752).flagFlagged().flagAnswered().flagSeen();
         args.add(valid(parts));

         // with dovecot attributes
-        parts =
Parts.fullName("1035478339.27041_118.foo.org,S=1000,W=1030:2,S")
+        parts =
Parts.fullName("1035478339.27041_118.foo.org,S=1000,W=1030;2,S")

.baseName("1035478339.27041_118.foo.org").timeSeconds(1035478339).size(1000L).flagSeen();

         args.add(valid(parts));

         parts = parts.copy();
-        parts.fullName = "1035478339.27041_118.foo.org,W=1030,S=1000:2,S";
+        parts.fullName = "1035478339.27041_118.foo.org,W=1030,S=1000;2,S";
         args.add(valid(parts));

         // new mail, no info part at all. found in courier maildirs
@@ -84,15 +84,15 @@
         args.add(valid(parts));

         // new mail, generated by james
-        parts =
Parts.fullName("1356001301.e563087e30181513.foohost,S=629:2,")
+        parts =
Parts.fullName("1356001301.e563087e30181513.foohost,S=629;2,")

.baseName("1356001301.e563087e30181513.foohost").timeSeconds(1356001301).size(629L);

         args.add(valid(parts));

-        parts =
Parts.fullName("1355675588.5c7e107958851103.foohost,S=654:2,S").timeSeconds(1355675588)

+        parts =
Parts.fullName("1355675588.5c7e107958851103.foohost,S=654;2,S").timeSeconds(1355675588)


.baseName("1355675588.5c7e107958851103.foohost").size(654L).flagSeen();
         args.add(valid(parts));

-        parts =
Parts.fullName("1355675651.f3dd564265174501.foohost,S=661:2,")
+        parts =
Parts.fullName("1355675651.f3dd564265174501.foohost,S=661;2,")

.baseName("1355675651.f3dd564265174501.foohost").timeSeconds(1355675651).size(661L);

         args.add(valid(parts));



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


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



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

Reply via email to