Browse Source

Merge -r 648748:648749 from trunk to 0.17 branch. Fixes HADOOP-3256.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/core/branches/branch-0.17@648750 13f79535-47bb-0310-9956-ffa450edef68
Devaraj Das 17 years ago
parent
commit
51b37f931e

+ 3 - 0
CHANGES.txt

@@ -576,6 +576,9 @@ Release 0.17.0 - Unreleased
     correctly read from the start of the split and not the beginning of the
     correctly read from the start of the split and not the beginning of the
     file. (cdouglas via acmurthy) 
     file. (cdouglas via acmurthy) 
 
 
+    HADOOP-3256. Encodes the job name used in the filename for history files.
+    (Arun Murthy via ddas)
+
 Release 0.16.3 - 2008-04-16
 Release 0.16.3 - 2008-04-16
 
 
   BUG FIXES
   BUG FIXES

+ 2 - 1
src/java/org/apache/hadoop/mapred/HistoryViewer.java

@@ -81,7 +81,8 @@ class HistoryViewer {
                               + historyLogDir.toString());
                               + historyLogDir.toString());
       }
       }
       jobLogFile = jobFiles[0].toString();
       jobLogFile = jobFiles[0].toString();
-      String[] jobDetails = jobFiles[0].getName().split("_");
+      String[] jobDetails = 
+          JobInfo.decodeJobHistoryFileName(jobFiles[0].getName()).split("_");
       trackerHostName = jobDetails[0];
       trackerHostName = jobDetails[0];
       trackerStartTime = jobDetails[1];
       trackerStartTime = jobDetails[1];
       jobId = jobDetails[2] + "_" + jobDetails[3] + "_" + jobDetails[4];
       jobId = jobDetails[2] + "_" + jobDetails[3] + "_" + jobDetails[4];

+ 87 - 10
src/java/org/apache/hadoop/mapred/JobHistory.java

@@ -26,6 +26,9 @@ import java.io.FileReader;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Iterator;
@@ -349,6 +352,75 @@ public class JobHistory {
                jobId + "_conf.xml";
                jobId + "_conf.xml";
     }
     }
     
     
+    /**
+     * Helper function to encode the URL of the path of the job-history
+     * log file. 
+     * 
+     * @param logFile path of the job-history file
+     * @return URL encoded path
+     * @throws IOException
+     */
+    public static String encodeJobHistoryFilePath(String logFile)
+    throws IOException {
+      Path rawPath = new Path(logFile);
+      String encodedFileName = null;
+      try {
+        encodedFileName = URLEncoder.encode(rawPath.getName(), "UTF-8");
+      } catch (UnsupportedEncodingException uee) {
+        IOException ioe = new IOException();
+        ioe.initCause(uee);
+        ioe.setStackTrace(uee.getStackTrace());
+        throw ioe;
+      }
+      
+      Path encodedPath = new Path(rawPath.getParent(), encodedFileName);
+      return encodedPath.toString();
+    }
+    
+    /**
+     * Helper function to encode the URL of the filename of the job-history 
+     * log file.
+     * 
+     * @param logFileName file name of the job-history file
+     * @return URL encoded filename
+     * @throws IOException
+     */
+    public static String encodeJobHistoryFileName(String logFileName)
+    throws IOException {
+      String encodedFileName = null;
+      try {
+        encodedFileName = URLEncoder.encode(logFileName, "UTF-8");
+      } catch (UnsupportedEncodingException uee) {
+        IOException ioe = new IOException();
+        ioe.initCause(uee);
+        ioe.setStackTrace(uee.getStackTrace());
+        throw ioe;
+      }
+      return encodedFileName;
+    }
+    
+    /**
+     * Helper function to decode the URL of the filename of the job-history 
+     * log file.
+     * 
+     * @param logFileName file name of the job-history file
+     * @return URL decoded filename
+     * @throws IOException
+     */
+    public static String decodeJobHistoryFileName(String logFileName)
+    throws IOException {
+      String decodedFileName = null;
+      try {
+        decodedFileName = URLDecoder.decode(logFileName, "UTF-8");
+      } catch (UnsupportedEncodingException uee) {
+        IOException ioe = new IOException();
+        ioe.initCause(uee);
+        ioe.setStackTrace(uee.getStackTrace());
+        throw ioe;
+      }
+      return decodedFileName;
+    }
+    
     /**
     /**
      * Log job submitted event to history. Creates a new file in history 
      * Log job submitted event to history. Creates a new file in history 
      * for the job. if history file creation fails, it disables history 
      * for the job. if history file creation fails, it disables history 
@@ -357,9 +429,11 @@ public class JobHistory {
      * @param jobConf job conf of the job
      * @param jobConf job conf of the job
      * @param jobConfPath path to job conf xml file in HDFS.
      * @param jobConfPath path to job conf xml file in HDFS.
      * @param submitTime time when job tracker received the job
      * @param submitTime time when job tracker received the job
+     * @throws IOException
      */
      */
     public static void logSubmitted(String jobId, JobConf jobConf, 
     public static void logSubmitted(String jobId, JobConf jobConf, 
-                                    String jobConfPath, long submitTime) {
+                                    String jobConfPath, long submitTime) 
+    throws IOException {
       String jobName = jobConf.getJobName();
       String jobName = jobConf.getJobName();
       String user = jobConf.getUser(); 
       String user = jobConf.getUser(); 
       FileSystem fs = null;
       FileSystem fs = null;
@@ -368,8 +442,10 @@ public class JobHistory {
 
 
       if (!disableHistory){
       if (!disableHistory){
         // setup the history log file for this job
         // setup the history log file for this job
-        String logFileName = jobUniqueString +  
-                             "_" + user+ "_" + jobName;
+        String logFileName = 
+            encodeJobHistoryFileName(jobUniqueString +  "_" + user+ "_" + 
+                                     jobName);
+        
         if (logFileName.length() > MAX_FILENAME_SIZE) {
         if (logFileName.length() > MAX_FILENAME_SIZE) {
           logFileName = logFileName.substring(0, MAX_FILENAME_SIZE-1);
           logFileName = logFileName.substring(0, MAX_FILENAME_SIZE-1);
         }
         }
@@ -382,16 +458,17 @@ public class JobHistory {
           userLogDir = null;
           userLogDir = null;
         }
         }
         if (userLogDir != null) {
         if (userLogDir != null) {
-          userLogDir = userLogDir + "/_logs/history";
+          userLogDir = userLogDir + Path.SEPARATOR + "_logs" + 
+                       Path.SEPARATOR + "history";
         }
         }
 
 
-        String logFile = null;
-        String userLogFile = null;
+        Path logFile = null;
+        Path userLogFile = null;
         if (LOG_DIR != null ) {
         if (LOG_DIR != null ) {
-          logFile = LOG_DIR + File.separator + logFileName;
+          logFile = new Path(LOG_DIR, logFileName);
         }
         }
         if (userLogDir != null ) {
         if (userLogDir != null ) {
-          userLogFile = userLogDir + File.separator + logFileName;
+          userLogFile = new Path(userLogDir, logFileName);
         }
         }
 
 
         try{
         try{
@@ -402,7 +479,7 @@ public class JobHistory {
           if (LOG_DIR != null) {
           if (LOG_DIR != null) {
             // create output stream for logging in hadoop.job.history.location
             // create output stream for logging in hadoop.job.history.location
             fs = new Path(LOG_DIR).getFileSystem(jobConf);
             fs = new Path(LOG_DIR).getFileSystem(jobConf);
-            out = fs.create(new Path(logFile), true, 4096);
+            out = fs.create(logFile, true, 4096);
             writer = new PrintWriter(out);
             writer = new PrintWriter(out);
             writers.add(writer);
             writers.add(writer);
           }
           }
@@ -410,7 +487,7 @@ public class JobHistory {
             // create output stream for logging 
             // create output stream for logging 
             // in hadoop.job.history.user.location
             // in hadoop.job.history.user.location
             fs = new Path(userLogDir).getFileSystem(jobConf);
             fs = new Path(userLogDir).getFileSystem(jobConf);
-            out = fs.create(new Path(userLogFile), true, 4096);
+            out = fs.create(userLogFile, true, 4096);
             writer = new PrintWriter(out);
             writer = new PrintWriter(out);
             writers.add(writer);
             writers.add(writer);
           }
           }

+ 12 - 11
src/webapps/job/analysejobhistory.jsp

@@ -19,6 +19,7 @@
 <%
 <%
   String jobid = request.getParameter("jobid");
   String jobid = request.getParameter("jobid");
   String logFile = request.getParameter("logFile");
   String logFile = request.getParameter("logFile");
+  String encodedLogFileName = JobHistory.JobInfo.encodeJobHistoryFilePath(logFile);
   String numTasks = request.getParameter("numTasks");
   String numTasks = request.getParameter("numTasks");
   int showTasks = 10 ; 
   int showTasks = 10 ; 
   if (numTasks != null) {
   if (numTasks != null) {
@@ -26,7 +27,7 @@
   }
   }
   JobInfo job = (JobInfo)request.getSession().getAttribute("job");
   JobInfo job = (JobInfo)request.getSession().getAttribute("job");
 %>
 %>
-<h2>Hadoop Job <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=logFile %>"><%=jobid %> </a></h2>
+<h2>Hadoop Job <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=encodedLogFileName%>"><%=jobid %> </a></h2>
 <b>User : </b> <%=job.get(Keys.USER) %><br/> 
 <b>User : </b> <%=job.get(Keys.USER) %><br/> 
 <b>JobName : </b> <%=job.get(Keys.JOBNAME) %><br/> 
 <b>JobName : </b> <%=job.get(Keys.JOBNAME) %><br/> 
 <b>JobConf : </b> <%=job.get(Keys.JOBCONF) %><br/> 
 <b>JobConf : </b> <%=job.get(Keys.JOBCONF) %><br/> 
@@ -100,7 +101,7 @@
 %>
 %>
 
 
 <h3>Time taken by best performing Map task 
 <h3>Time taken by best performing Map task 
-<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile%>&taskid=<%=minMap.get(Keys.TASKID)%>">
+<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>&taskid=<%=minMap.get(Keys.TASKID)%>">
 <%=minMap.get(Keys.TASKID) %></a> : <%=StringUtils.formatTimeDiff(minMap.getLong(Keys.FINISH_TIME), minMap.getLong(Keys.START_TIME) ) %></h3>
 <%=minMap.get(Keys.TASKID) %></a> : <%=StringUtils.formatTimeDiff(minMap.getLong(Keys.FINISH_TIME), minMap.getLong(Keys.START_TIME) ) %></h3>
 <h3>Average time taken by Map tasks: 
 <h3>Average time taken by Map tasks: 
 <%=StringUtils.formatTimeDiff(avgMapTime, 0) %></h3>
 <%=StringUtils.formatTimeDiff(avgMapTime, 0) %></h3>
@@ -111,7 +112,7 @@
   for (int i=0;i<showTasks && i<mapTasks.length; i++) {
   for (int i=0;i<showTasks && i<mapTasks.length; i++) {
 %>
 %>
     <tr>
     <tr>
-    <td><a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile%>&taskid=<%=mapTasks[i].get(Keys.TASKID)%>">
+    <td><a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>&taskid=<%=mapTasks[i].get(Keys.TASKID)%>">
         <%=mapTasks[i].get(Keys.TASKID) %></a></td>
         <%=mapTasks[i].get(Keys.TASKID) %></a></td>
     <td><%=StringUtils.formatTimeDiff(mapTasks[i].getLong(Keys.FINISH_TIME), mapTasks[i].getLong(Keys.START_TIME)) %></td>
     <td><%=StringUtils.formatTimeDiff(mapTasks[i].getLong(Keys.FINISH_TIME), mapTasks[i].getLong(Keys.START_TIME)) %></td>
     </tr>
     </tr>
@@ -133,7 +134,7 @@
 %>
 %>
 
 
 <h3>The last Map task 
 <h3>The last Map task 
-<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile%>
+<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>
 &taskid=<%=lastMap.get(Keys.TASKID)%>"><%=lastMap.get(Keys.TASKID) %></a> 
 &taskid=<%=lastMap.get(Keys.TASKID)%>"><%=lastMap.get(Keys.TASKID) %></a> 
 finished at (relative to the Job launch time): 
 finished at (relative to the Job launch time): 
 <%=StringUtils.getFormattedTimeWithDiff(dateFormat, 
 <%=StringUtils.getFormattedTimeWithDiff(dateFormat, 
@@ -147,7 +148,7 @@ finished at (relative to the Job launch time):
   JobHistory.Task minShuffle = reduceTasks[reduceTasks.length-1] ;
   JobHistory.Task minShuffle = reduceTasks[reduceTasks.length-1] ;
 %>
 %>
 <h3>Time taken by best performing shuffle
 <h3>Time taken by best performing shuffle
-<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile%>
+<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>
 &taskid=<%=minShuffle.get(Keys.TASKID)%>"><%=minShuffle.get(Keys.TASKID)%></a> : 
 &taskid=<%=minShuffle.get(Keys.TASKID)%>"><%=minShuffle.get(Keys.TASKID)%></a> : 
 <%=StringUtils.formatTimeDiff(minShuffle.getLong(Keys.SHUFFLE_FINISHED), 
 <%=StringUtils.formatTimeDiff(minShuffle.getLong(Keys.SHUFFLE_FINISHED), 
                               minShuffle.getLong(Keys.START_TIME) ) %></h3>
                               minShuffle.getLong(Keys.START_TIME) ) %></h3>
@@ -161,7 +162,7 @@ finished at (relative to the Job launch time):
 %>
 %>
     <tr>
     <tr>
     <td><a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=
     <td><a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=
-        <%=logFile%>&taskid=<%=reduceTasks[i].get(Keys.TASKID)%>">
+        <%=encodedLogFileName%>&taskid=<%=reduceTasks[i].get(Keys.TASKID)%>">
         <%=reduceTasks[i].get(Keys.TASKID) %></a></td>
         <%=reduceTasks[i].get(Keys.TASKID) %></a></td>
     <td><%=
     <td><%=
            StringUtils.formatTimeDiff(
            StringUtils.formatTimeDiff(
@@ -187,7 +188,7 @@ finished at (relative to the Job launch time):
 %>
 %>
 
 
 <h3>The last Shuffle  
 <h3>The last Shuffle  
-<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile%>
+<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>
 &taskid=<%=lastShuffle.get(Keys.TASKID)%>"><%=lastShuffle.get(Keys.TASKID)%>
 &taskid=<%=lastShuffle.get(Keys.TASKID)%>"><%=lastShuffle.get(Keys.TASKID)%>
 </a> finished at (relative to the Job launch time): 
 </a> finished at (relative to the Job launch time): 
 <%=StringUtils.getFormattedTimeWithDiff(dateFormat,
 <%=StringUtils.getFormattedTimeWithDiff(dateFormat,
@@ -209,7 +210,7 @@ finished at (relative to the Job launch time):
 %>
 %>
 <hr/>
 <hr/>
 <h3>Time taken by best performing Reduce task : 
 <h3>Time taken by best performing Reduce task : 
-<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile%>&taskid=<%=minReduce.get(Keys.TASKID)%>">
+<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>&taskid=<%=minReduce.get(Keys.TASKID)%>">
 <%=minReduce.get(Keys.TASKID) %></a> : 
 <%=minReduce.get(Keys.TASKID) %></a> : 
 <%=StringUtils.formatTimeDiff(minReduce.getLong(Keys.FINISH_TIME),
 <%=StringUtils.formatTimeDiff(minReduce.getLong(Keys.FINISH_TIME),
     minReduce.getLong(Keys.SHUFFLE_FINISHED) ) %></h3>
     minReduce.getLong(Keys.SHUFFLE_FINISHED) ) %></h3>
@@ -223,7 +224,7 @@ finished at (relative to the Job launch time):
   for (int i=0;i<showTasks && i<reduceTasks.length; i++) {
   for (int i=0;i<showTasks && i<reduceTasks.length; i++) {
 %>
 %>
     <tr>
     <tr>
-    <td><a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile%>&taskid=<%=reduceTasks[i].get(Keys.TASKID)%>">
+    <td><a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>&taskid=<%=reduceTasks[i].get(Keys.TASKID)%>">
         <%=reduceTasks[i].get(Keys.TASKID) %></a></td>
         <%=reduceTasks[i].get(Keys.TASKID) %></a></td>
     <td><%=StringUtils.formatTimeDiff(
     <td><%=StringUtils.formatTimeDiff(
              reduceTasks[i].getLong(Keys.FINISH_TIME), 
              reduceTasks[i].getLong(Keys.FINISH_TIME), 
@@ -239,11 +240,11 @@ finished at (relative to the Job launch time):
 %>
 %>
 
 
 <h3>The last Reduce task 
 <h3>The last Reduce task 
-<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile%>
+<a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>
 &taskid=<%=lastReduce.get(Keys.TASKID)%>"><%=lastReduce.get(Keys.TASKID)%>
 &taskid=<%=lastReduce.get(Keys.TASKID)%>"><%=lastReduce.get(Keys.TASKID)%>
 </a> finished at (relative to the Job launch time): 
 </a> finished at (relative to the Job launch time): 
 <%=StringUtils.getFormattedTimeWithDiff(dateFormat,
 <%=StringUtils.getFormattedTimeWithDiff(dateFormat,
                               lastReduce.getLong(Keys.FINISH_TIME), 
                               lastReduce.getLong(Keys.FINISH_TIME), 
                               job.getLong(Keys.LAUNCH_TIME) ) %></h3>
                               job.getLong(Keys.LAUNCH_TIME) ) %></h3>
 </center>
 </center>
-</body></html>
+</body></html>

+ 12 - 11
src/webapps/job/jobdetailshistory.jsp

@@ -17,6 +17,7 @@
 <%
 <%
     String jobid = request.getParameter("jobid");
     String jobid = request.getParameter("jobid");
     String logFile = request.getParameter("logFile");
     String logFile = request.getParameter("logFile");
+	String encodedLogFileName = JobHistory.JobInfo.encodeJobHistoryFilePath(logFile);
 	
 	
     Path jobFile = new Path(logFile);
     Path jobFile = new Path(logFile);
     String[] jobDetails = jobFile.getName().split("_");
     String[] jobDetails = jobFile.getName().split("_");
@@ -87,7 +88,7 @@
       }
       }
     }
     }
 %>
 %>
-<b><a href="analysejobhistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>">Analyse This Job</a></b> 
+<b><a href="analysejobhistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>">Analyse This Job</a></b> 
 <hr/>
 <hr/>
 <center>
 <center>
 <table border="2" cellpadding="5" cellspacing="2">
 <table border="2" cellpadding="5" cellspacing="2">
@@ -96,26 +97,26 @@
 </tr>
 </tr>
 <tr>
 <tr>
 <td>Map</td>
 <td>Map</td>
-    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>&taskType=<%=Values.MAP.name() %>&status=all">
+    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.MAP.name() %>&status=all">
         <%=totalMaps %></a></td>
         <%=totalMaps %></a></td>
-    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>&taskType=<%=Values.MAP.name() %>&status=<%=Values.SUCCESS %>">
+    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.MAP.name() %>&status=<%=Values.SUCCESS %>">
         <%=job.getInt(Keys.FINISHED_MAPS) %></a></td>
         <%=job.getInt(Keys.FINISHED_MAPS) %></a></td>
-    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>&taskType=<%=Values.MAP.name() %>&status=<%=Values.FAILED %>">
+    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.MAP.name() %>&status=<%=Values.FAILED %>">
         <%=numFailedMaps %></a></td>
         <%=numFailedMaps %></a></td>
-    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>&taskType=<%=Values.MAP.name() %>&status=<%=Values.KILLED %>">
+    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.MAP.name() %>&status=<%=Values.KILLED %>">
         <%=numKilledMaps %></a></td>
         <%=numKilledMaps %></a></td>
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, mapStarted, 0) %></td>
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, mapStarted, 0) %></td>
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, mapFinished, mapStarted) %></td>
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, mapFinished, mapStarted) %></td>
 </tr>
 </tr>
 <tr>
 <tr>
 <td>Reduce</td>
 <td>Reduce</td>
-    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>&taskType=<%=Values.REDUCE.name() %>&status=all">
+    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.REDUCE.name() %>&status=all">
         <%=totalReduces%></a></td>
         <%=totalReduces%></a></td>
-    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>&taskType=<%=Values.REDUCE.name() %>&status=<%=Values.SUCCESS %>">
+    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.REDUCE.name() %>&status=<%=Values.SUCCESS %>">
         <%=job.getInt(Keys.FINISHED_REDUCES)%></a></td>
         <%=job.getInt(Keys.FINISHED_REDUCES)%></a></td>
-    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>&taskType=<%=Values.REDUCE.name() %>&status=<%=Values.FAILED %>">
+    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.REDUCE.name() %>&status=<%=Values.FAILED %>">
         <%=numFailedReduces%></a></td>
         <%=numFailedReduces%></a></td>
-    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=logFile %>&taskType=<%=Values.REDUCE.name() %>&status=<%=Values.KILLED %>">
+    <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.REDUCE.name() %>&status=<%=Values.KILLED %>">
         <%=numKilledReduces%></a></td>  
         <%=numKilledReduces%></a></td>  
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, reduceStarted, 0) %></td>
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, reduceStarted, 0) %></td>
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, reduceFinished, reduceStarted) %></td>
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, reduceFinished, reduceStarted) %></td>
@@ -144,7 +145,7 @@
 <%
 <%
         for (String t : failedTasks) {
         for (String t : failedTasks) {
 %>
 %>
-          <a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile %>&taskid=<%=t %>"><%=t %></a>,&nbsp;
+          <a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>&taskid=<%=t %>"><%=t %></a>,&nbsp;
 <%		  
 <%		  
         }
         }
 %>	
 %>	
@@ -177,7 +178,7 @@
 <%
 <%
         for (String t : killedTasks) {
         for (String t : killedTasks) {
 %>
 %>
-          <a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=logFile %>&taskid=<%=t %>"><%=t %></a>,&nbsp;
+          <a href="taskdetailshistory.jsp?jobid=<%=jobid%>&logFile=<%=encodedLogFileName%>&taskid=<%=t %>"><%=t %></a>,&nbsp;
 <%		  
 <%		  
         }
         }
 %>	
 %>	

+ 24 - 6
src/webapps/job/jobhistory.jsp

@@ -46,8 +46,18 @@
     // sort the files on creation time.
     // sort the files on creation time.
     Arrays.sort(jobFiles, new Comparator<Path>() {
     Arrays.sort(jobFiles, new Comparator<Path>() {
       public int compare(Path p1, Path p2) {
       public int compare(Path p1, Path p2) {
-        String[] split1 = p1.getName().split("_");
-        String[] split2 = p2.getName().split("_");
+        String dp1 = null;
+        String dp2 = null;
+        
+        try {
+          dp1 = JobHistory.JobInfo.decodeJobHistoryFileName(p1.getName());
+          dp2 = JobHistory.JobInfo.decodeJobHistoryFileName(p2.getName());
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+                
+        String[] split1 = dp1.split("_");
+        String[] split2 = dp2.split("_");
         
         
         // compare job tracker start time
         // compare job tracker start time
         int res = new Date(Long.parseLong(split1[1])).compareTo(
         int res = new Date(Long.parseLong(split1[1])).compareTo(
@@ -72,17 +82,25 @@
               "<td>Job Id</td><td>Name</td><td>User</td>") ; 
               "<td>Job Id</td><td>Name</td><td>User</td>") ; 
     out.print("</tr>"); 
     out.print("</tr>"); 
     for (Path jobFile: jobFiles) {
     for (Path jobFile: jobFiles) {
-      String[] jobDetails = jobFile.getName().split("_");
+      String decodedJobFileName = 
+          JobHistory.JobInfo.decodeJobHistoryFileName(jobFile.getName());
+
+      String[] jobDetails = decodedJobFileName.split("_");
       String trackerHostName = jobDetails[0];
       String trackerHostName = jobDetails[0];
       String trackerStartTime = jobDetails[1];
       String trackerStartTime = jobDetails[1];
       String jobId = jobDetails[2] + "_" +jobDetails[3] + "_" + jobDetails[4] ;
       String jobId = jobDetails[2] + "_" +jobDetails[3] + "_" + jobDetails[4] ;
       String user = jobDetails[5];
       String user = jobDetails[5];
       String jobName = jobDetails[6];
       String jobName = jobDetails[6];
+      
+      // Encode the logfile name again to cancel the decoding done by the browser
+      String encodedJobFileName = 
+          JobHistory.JobInfo.encodeJobHistoryFileName(jobFile.getName());
 %>
 %>
 <center>
 <center>
 <%	
 <%	
       printJob(trackerHostName, trackerStartTime, jobId,
       printJob(trackerHostName, trackerStartTime, jobId,
-               jobName, user, jobFile.toString(), out) ; 
+               jobName, user, new Path(jobFile.getParent(), encodedJobFileName), 
+               out) ; 
 %>
 %>
 </center> 
 </center> 
 <%
 <%
@@ -91,13 +109,13 @@
 <%!
 <%!
     private void printJob(String trackerHostName, String trackerid,
     private void printJob(String trackerHostName, String trackerid,
                           String jobId, String jobName,
                           String jobId, String jobName,
-                          String user, String logFile, JspWriter out)
+                          String user, Path logFile, JspWriter out)
     throws IOException {
     throws IOException {
       out.print("<tr>"); 
       out.print("<tr>"); 
       out.print("<td>" + trackerHostName + "</td>"); 
       out.print("<td>" + trackerHostName + "</td>"); 
       out.print("<td>" + new Date(Long.parseLong(trackerid)) + "</td>"); 
       out.print("<td>" + new Date(Long.parseLong(trackerid)) + "</td>"); 
       out.print("<td>" + "<a href=\"jobdetailshistory.jsp?jobid=" + jobId + 
       out.print("<td>" + "<a href=\"jobdetailshistory.jsp?jobid=" + jobId + 
-                "&logFile=" + logFile + "\">" + jobId + "</a></td>"); 
+                "&logFile=" + logFile.toString() + "\">" + jobId + "</a></td>"); 
       out.print("<td>" + jobName + "</td>"); 
       out.print("<td>" + jobName + "</td>"); 
       out.print("<td>" + user + "</td>"); 
       out.print("<td>" + user + "</td>"); 
       out.print("</tr>");
       out.print("</tr>");

+ 5 - 4
src/webapps/job/jobtaskshistory.jsp

@@ -20,6 +20,7 @@
 <%	
 <%	
   String jobid = request.getParameter("jobid");
   String jobid = request.getParameter("jobid");
   String logFile = request.getParameter("logFile");
   String logFile = request.getParameter("logFile");
+  String encodedLogFileName = JobHistory.JobInfo.encodeJobHistoryFilePath(logFile);
   String taskStatus = request.getParameter("status"); 
   String taskStatus = request.getParameter("status"); 
   String taskType = request.getParameter("taskType"); 
   String taskType = request.getParameter("taskType"); 
   
   
@@ -29,7 +30,7 @@
 %>
 %>
 <html>
 <html>
 <body>
 <body>
-<h2><%=taskStatus%> <%=taskType %> task list for <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=logFile %>"><%=jobid %> </a></h2>
+<h2><%=taskStatus%> <%=taskType %> task list for <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=encodedLogFileName%>"><%=jobid %> </a></h2>
 <center>
 <center>
 <table border="2" cellpadding="5" cellspacing="2">
 <table border="2" cellpadding="5" cellspacing="2">
 <tr><td>Task Id</td><td>Start Time</td><td>Finish Time<br/></td><td>Error</td></tr>
 <tr><td>Task Id</td><td>Start Time</td><td>Finish Time<br/></td><td>Error</td></tr>
@@ -40,7 +41,7 @@
       for (JobHistory.TaskAttempt taskAttempt : taskAttempts.values()) {
       for (JobHistory.TaskAttempt taskAttempt : taskAttempts.values()) {
         if (taskStatus.equals(taskAttempt.get(Keys.TASK_STATUS)) || 
         if (taskStatus.equals(taskAttempt.get(Keys.TASK_STATUS)) || 
           taskStatus.equals("all")){
           taskStatus.equals("all")){
-          printTask(jobid, logFile, taskAttempt, out); 
+          printTask(jobid, encodedLogFileName, taskAttempt, out); 
         }
         }
       }
       }
     }
     }
@@ -48,11 +49,11 @@
 %>
 %>
 </table>
 </table>
 <%!
 <%!
-  private void printTask(String jobid, String trackerId,
+  private void printTask(String jobid, String logFile,
     JobHistory.TaskAttempt attempt, JspWriter out) throws IOException{
     JobHistory.TaskAttempt attempt, JspWriter out) throws IOException{
     out.print("<tr>"); 
     out.print("<tr>"); 
     out.print("<td>" + "<a href=\"taskdetailshistory.jsp?jobid=" + jobid + 
     out.print("<td>" + "<a href=\"taskdetailshistory.jsp?jobid=" + jobid + 
-          "&logFile="+ trackerId +"&taskid="+attempt.get(Keys.TASKID)+"\">" +
+          "&logFile="+ logFile +"&taskid="+attempt.get(Keys.TASKID)+"\">" +
           attempt.get(Keys.TASKID) + "</a></td>");
           attempt.get(Keys.TASKID) + "</a></td>");
     out.print("<td>" + StringUtils.getFormattedTimeWithDiff(dateFormat, 
     out.print("<td>" + StringUtils.getFormattedTimeWithDiff(dateFormat, 
           attempt.getLong(Keys.START_TIME), 0 ) + "</td>");
           attempt.getLong(Keys.START_TIME), 0 ) + "</td>");

+ 2 - 1
src/webapps/job/taskdetailshistory.jsp

@@ -17,6 +17,7 @@
 <%	
 <%	
   String jobid = request.getParameter("jobid");
   String jobid = request.getParameter("jobid");
   String logFile = request.getParameter("logFile");
   String logFile = request.getParameter("logFile");
+  String encodedLogFileName = JobHistory.JobInfo.encodeJobHistoryFilePath(logFile);
   String taskid = request.getParameter("taskid"); 
   String taskid = request.getParameter("taskid"); 
   JobHistory.JobInfo job = (JobHistory.JobInfo)
   JobHistory.JobInfo job = (JobHistory.JobInfo)
                               request.getSession().getAttribute("job");
                               request.getSession().getAttribute("job");
@@ -24,7 +25,7 @@
 %>
 %>
 <html>
 <html>
 <body>
 <body>
-<h2><%=taskid %> attempts for <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=logFile %>"> <%=jobid %> </a></h2>
+<h2><%=taskid %> attempts for <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=encodedLogFileName%>"> <%=jobid %> </a></h2>
 <center>
 <center>
 <table border="2" cellpadding="5" cellspacing="2">
 <table border="2" cellpadding="5" cellspacing="2">
 <tr><td>Task Id</td><td>Start Time</td>
 <tr><td>Task Id</td><td>Start Time</td>