Browse Source

HDFS-525. The SimpleDateFormat object in ListPathsServlet is not thread
safe. (Suresh Srinivas and cdouglas)


git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.20@808673 13f79535-47bb-0310-9956-ffa450edef68

Christopher Douglas 16 years ago
parent
commit
d9ad2986a7

+ 3 - 0
CHANGES.txt

@@ -244,6 +244,9 @@ Release 0.20.1 - Unreleased
     MAPREDUCE-421. Fix Pipes to use returned system exit code.
     (Christian Kunz via omalley)
 
+    HDFS-525. The SimpleDateFormat object in ListPathsServlet is not thread
+    safe. (Suresh Srinivas and cdouglas)
+
 Release 0.20.0 - 2009-04-15
 
   INCOMPATIBLE CHANGES

+ 19 - 3
src/hdfs/org/apache/hadoop/hdfs/HftpFileSystem.java

@@ -35,6 +35,7 @@ import java.text.SimpleDateFormat;
 
 import java.util.ArrayList;
 import java.util.Random;
+import java.util.TimeZone;
 
 import javax.security.auth.login.LoginException;
 
@@ -77,7 +78,21 @@ public class HftpFileSystem extends FileSystem {
   protected UserGroupInformation ugi; 
   protected final Random ran = new Random();
 
-  protected static final SimpleDateFormat df = ListPathsServlet.df;
+  public static final String HFTP_TIMEZONE = "UTC";
+  public static final String HFTP_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
+
+  public static final SimpleDateFormat getDateFormat() {
+    final SimpleDateFormat df = new SimpleDateFormat(HFTP_DATE_FORMAT);
+    df.setTimeZone(TimeZone.getTimeZone(HFTP_TIMEZONE));
+    return df;
+  }
+
+  protected static final ThreadLocal<SimpleDateFormat> df =
+    new ThreadLocal<SimpleDateFormat>() {
+      protected SimpleDateFormat initialValue() {
+        return getDateFormat();
+      }
+    };
 
   @Override
   public void initialize(URI name, Configuration conf) throws IOException {
@@ -181,10 +196,11 @@ public class HftpFileSystem extends FileSystem {
       long modif;
       long atime = 0;
       try {
-        modif = df.parse(attrs.getValue("modified")).getTime();
+        final SimpleDateFormat ldf = df.get();
+        modif = ldf.parse(attrs.getValue("modified")).getTime();
         String astr = attrs.getValue("accesstime");
         if (astr != null) {
-          atime = df.parse(astr).getTime();
+          atime = ldf.parse(astr).getTime();
         }
       } catch (ParseException e) { throw new SAXException(e); }
       FileStatus fs = "file".equals(qname)

+ 11 - 11
src/hdfs/org/apache/hadoop/hdfs/server/namenode/ListPathsServlet.java

@@ -18,6 +18,7 @@
 package org.apache.hadoop.hdfs.server.namenode;
 
 import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.hdfs.HftpFileSystem;
 import org.apache.hadoop.hdfs.protocol.ClientProtocol;
 import org.apache.hadoop.ipc.RemoteException;
 import org.apache.hadoop.security.UnixUserGroupInformation;
@@ -32,7 +33,6 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Stack;
-import java.util.TimeZone;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 import javax.servlet.ServletException;
@@ -47,11 +47,12 @@ public class ListPathsServlet extends DfsServlet {
   /** For java.io.Serializable */
   private static final long serialVersionUID = 1L;
 
-  public static final SimpleDateFormat df =
-    new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
-  static {
-    df.setTimeZone(TimeZone.getTimeZone("UTC"));
-  }
+  public static final ThreadLocal<SimpleDateFormat> df =
+    new ThreadLocal<SimpleDateFormat>() {
+      protected SimpleDateFormat initialValue() {
+        return HftpFileSystem.getDateFormat();
+      }
+    };
 
   /**
    * Write a node to output.
@@ -59,10 +60,11 @@ public class ListPathsServlet extends DfsServlet {
    * For files, it also includes size, replication and block-size. 
    */
   static void writeInfo(FileStatus i, XMLOutputter doc) throws IOException {
+    final SimpleDateFormat ldf = df.get();
     doc.startTag(i.isDir() ? "directory" : "file");
     doc.attribute("path", i.getPath().toUri().getPath());
-    doc.attribute("modified", df.format(new Date(i.getModificationTime())));
-    doc.attribute("accesstime", df.format(new Date(i.getAccessTime())));
+    doc.attribute("modified", ldf.format(new Date(i.getModificationTime())));
+    doc.attribute("accesstime", ldf.format(new Date(i.getAccessTime())));
     if (!i.isDir()) {
       doc.attribute("size", String.valueOf(i.getLen()));
       doc.attribute("replication", String.valueOf(i.getReplication()));
@@ -93,7 +95,7 @@ public class ListPathsServlet extends DfsServlet {
     root.put("recursive", recur ? "yes" : "no");
     root.put("filter", filter);
     root.put("exclude", exclude);
-    root.put("time", df.format(new Date()));
+    root.put("time", df.get().format(new Date()));
     root.put("version", VersionInfo.getVersion());
     return root;
   }
@@ -163,8 +165,6 @@ public class ListPathsServlet extends DfsServlet {
         }
         catch(RemoteException re) {re.writeXml(p, doc);}
       }
-    } catch (PatternSyntaxException e) {
-      out.println(e.toString());
     } finally {
       if (doc != null) {
         doc.endDocument();