Browse Source

svn merge -c 1334013 FIXES: MAPREDUCE-4048. NullPointerException exception while accessing the Application Master UI (Devaraj K via bobby)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1334014 13f79535-47bb-0310-9956-ffa450edef68
Robert Joseph Evans 13 years ago
parent
commit
13acee63d3

+ 3 - 0
hadoop-mapreduce-project/CHANGES.txt

@@ -343,6 +343,9 @@ Release 0.23.3 - UNRELEASED
 
 
     MAPREDUCE-4163. consistently set the bind address (Daryn Sharp via bobby)
     MAPREDUCE-4163. consistently set the bind address (Daryn Sharp via bobby)
 
 
+    MAPREDUCE-4048. NullPointerException exception while accessing the
+    Application Master UI (Devaraj K via bobby)
+
 Release 0.23.2 - UNRELEASED
 Release 0.23.2 - UNRELEASED
 
 
   INCOMPATIBLE CHANGES
   INCOMPATIBLE CHANGES

+ 10 - 1
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java

@@ -27,6 +27,8 @@ import java.util.Locale;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
 
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.mapreduce.JobACL;
 import org.apache.hadoop.mapreduce.JobACL;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
@@ -47,6 +49,8 @@ import com.google.inject.Inject;
  * This class renders the various pages that the web app supports.
  * This class renders the various pages that the web app supports.
  */
  */
 public class AppController extends Controller implements AMParams {
 public class AppController extends Controller implements AMParams {
+  private static final Log LOG = LogFactory.getLog(AppController.class);
+  
   protected final App app;
   protected final App app;
   
   
   protected AppController(App app, Configuration conf, RequestContext ctx,
   protected AppController(App app, Configuration conf, RequestContext ctx,
@@ -220,6 +224,8 @@ public class AppController extends Controller implements AMParams {
             toString().toLowerCase(Locale.US));
             toString().toLowerCase(Locale.US));
         setTitle(join(tt, " Tasks for ", $(JOB_ID)));
         setTitle(join(tt, " Tasks for ", $(JOB_ID)));
       } catch (Exception e) {
       } catch (Exception e) {
+        LOG.error("Failed to render tasks page with task type : "
+            + $(TASK_TYPE) + " for job id : " + $(JOB_ID), e);
         badRequest(e.getMessage());
         badRequest(e.getMessage());
       }
       }
     }
     }
@@ -283,6 +289,8 @@ public class AppController extends Controller implements AMParams {
 
 
         render(attemptsPage());
         render(attemptsPage());
       } catch (Exception e) {
       } catch (Exception e) {
+        LOG.error("Failed to render attempts page with task type : "
+            + $(TASK_TYPE) + " for job id : " + $(JOB_ID), e);
         badRequest(e.getMessage());
         badRequest(e.getMessage());
       }
       }
     }
     }
@@ -316,7 +324,8 @@ public class AppController extends Controller implements AMParams {
    */
    */
   void badRequest(String s) {
   void badRequest(String s) {
     setStatus(HttpServletResponse.SC_BAD_REQUEST);
     setStatus(HttpServletResponse.SC_BAD_REQUEST);
-    setTitle(join("Bad request: ", s));
+    String title = "Bad request: ";
+    setTitle((s != null) ? join(title, s) : title);
   }
   }
 
 
   /**
   /**

+ 71 - 0
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAppController.java

@@ -0,0 +1,71 @@
+/**
+ * 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.hadoop.mapreduce.v2.app.webapp;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.util.Records;
+import org.apache.hadoop.yarn.webapp.Controller.RequestContext;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestAppController {
+
+  private AppController appController;
+  private RequestContext ctx;
+
+  @Before
+  public void setUp() {
+    AppContext context = mock(AppContext.class);
+    when(context.getApplicationID()).thenReturn(
+        Records.newRecord(ApplicationId.class));
+    App app = new App(context);
+    Configuration conf = new Configuration();
+    ctx = mock(RequestContext.class);
+    appController = new AppController(app, conf, ctx);
+  }
+
+  @Test
+  public void testBadRequest() {
+    String message = "test string";
+    appController.badRequest(message);
+    verifyExpectations(message);
+  }
+
+  @Test
+  public void testBadRequestWithNullMessage() {
+    // It should not throw NullPointerException
+    appController.badRequest(null);
+    verifyExpectations(StringUtils.EMPTY);
+  }
+
+  private void verifyExpectations(String message) {
+    verify(ctx).setStatus(400);
+    verify(ctx).set("app.id", "application_0_0000");
+    verify(ctx).set(eq("rm.web"), anyString());
+    verify(ctx).set("title", "Bad request: " + message);
+  }
+}