ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tbeerbo...@apache.org
Subject ambari git commit: AMBARI-10748 - Views: IllegalAccessError: tried to access class (tbeerbower)
Date Mon, 27 Apr 2015 22:42:36 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.0.maint 020d8d300 -> f82ed9213


AMBARI-10748 - Views: IllegalAccessError: tried to access class (tbeerbower)


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

Branch: refs/heads/branch-2.0.maint
Commit: f82ed9213f1117ff6faf986bfcb181ff60aa77dd
Parents: 020d8d3
Author: tbeerbower <tbeerbower@hortonworks.com>
Authored: Mon Apr 27 11:44:49 2015 -0400
Committer: tbeerbower <tbeerbower@hortonworks.com>
Committed: Mon Apr 27 17:03:17 2015 -0400

----------------------------------------------------------------------
 ambari-project/pom.xml                          |  22 +++
 ambari-server/pom.xml                           |  18 +++
 .../server/controller/AmbariHandlerList.java    |  56 ++++---
 .../ambari/server/controller/AmbariServer.java  |   1 -
 .../server/controller/FailsafeHandlerList.java  | 154 -------------------
 .../controller/FailsafeServletResponse.java     |  77 ----------
 .../ambari/server/view/ViewArchiveUtility.java  |  11 +-
 .../ambari/server/view/ViewClassLoader.java     | 118 ++++++++++++++
 .../ambari/server/view/ViewExtractor.java       |   3 +-
 .../controller/AmbariHandlerListTest.java       |  13 +-
 .../controller/FailsafeHandlerListTest.java     |  71 ---------
 .../controller/FailsafeServletResponseTest.java |  54 -------
 .../ambari/server/view/ViewClassLoaderTest.java | 101 ++++++++++++
 13 files changed, 302 insertions(+), 397 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-project/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml
index 466c4c4..10380a1 100644
--- a/ambari-project/pom.xml
+++ b/ambari-project/pom.xml
@@ -321,6 +321,28 @@ instead of a SNAPSHOT. -->
         <artifactId>jetty-webapp</artifactId>
         <version>7.6.7.v20120910</version>
       </dependency>
+      <!--jsp support for jetty -->
+      <dependency>
+        <groupId>org.mortbay.jetty</groupId>
+        <artifactId>jsp-api-2.1-glassfish</artifactId>
+        <version>2.1.v20100127</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mortbay.jetty</groupId>
+        <artifactId>jsp-2.1-glassfish</artifactId>
+        <version>2.1.v20100127</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.ant</groupId>
+        <artifactId>ant</artifactId>
+        <version>1.7.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.ant</groupId>
+        <artifactId>ant-launcher</artifactId>
+        <version>1.7.1</version>
+      </dependency>
+
       <dependency>
         <groupId>commons-logging</groupId>
         <artifactId>commons-logging</artifactId>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index 11e2790..f75d05a 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -1564,6 +1564,24 @@
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-webapp</artifactId>
     </dependency>
+    <!--jsp support for jetty -->
+    <dependency>
+      <groupId>org.mortbay.jetty</groupId>
+      <artifactId>jsp-api-2.1-glassfish</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mortbay.jetty</groupId>
+      <artifactId>jsp-2.1-glassfish</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.ant</groupId>
+      <artifactId>ant</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.ant</groupId>
+      <artifactId>ant-launcher</artifactId>
+    </dependency>
+
     <dependency>
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-server</artifactId>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
index 7c68311..c6aac1d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
@@ -19,7 +19,6 @@ package org.apache.ambari.server.controller;
 
 import java.io.IOException;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -40,13 +39,12 @@ import org.apache.ambari.view.ViewContext;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.handler.HandlerCollection;
 import org.eclipse.jetty.server.session.SessionHandler;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.webapp.WebAppContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.web.context.WebApplicationContext;
-import org.springframework.web.context.support.GenericWebApplicationContext;
 import org.springframework.web.filter.DelegatingFilterProxy;
 
 /**
@@ -54,7 +52,7 @@ import org.springframework.web.filter.DelegatingFilterProxy;
  * of view instances as handlers.
  */
 @Singleton
-public class AmbariHandlerList extends FailsafeHandlerList implements ViewInstanceHandlerList
{
+public class AmbariHandlerList extends HandlerCollection implements ViewInstanceHandlerList
{
 
   /**
    * The target pattern for a view resource request.
@@ -88,11 +86,6 @@ public class AmbariHandlerList extends FailsafeHandlerList implements ViewInstan
   private final Map<ViewInstanceEntity, Handler> handlerMap = new HashMap<ViewInstanceEntity,
Handler>();
 
   /**
-   * Spring web app context.
-   */
-  private GenericWebApplicationContext springWebAppContext;
-
-  /**
    * The logger.
    */
   protected final static Logger LOG = LoggerFactory.getLogger(AmbariHandlerList.class);
@@ -113,9 +106,7 @@ public class AmbariHandlerList extends FailsafeHandlerList implements
ViewInstan
 
         context.setClassLoader(viewInstanceDefinition.getViewEntity().getClassLoader());
         context.setAttribute(ViewContext.CONTEXT_ATTRIBUTE, new ViewContextImpl(viewInstanceDefinition,
viewRegistry));
-
         context.setSessionHandler(new SharedSessionHandler(sessionManager));
-        context.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
springWebAppContext);
         context.addFilter(new FilterHolder(springSecurityFilter), "/*", 1);
 
         return context;
@@ -133,28 +124,19 @@ public class AmbariHandlerList extends FailsafeHandlerList implements
ViewInstan
     this.handlerFactory = handlerFactory;
   }
 
-  /**
-   * Sets the spring web app context.
-   *
-   * @param springWebAppContext the spring web app context
-   */
-  public void setSpringWebAppContext(
-      GenericWebApplicationContext springWebAppContext) {
-    this.springWebAppContext = springWebAppContext;
-  }
 
 
-  // ----- FailsafeHandlerList -----------------------------------------------
+  // ----- HandlerCollection -------------------------------------------------
 
   @Override
-  protected void handleNonFailSafe(String target, Request baseRequest,
-                                   HttpServletRequest request, HttpServletResponse response,
-                                   List<Handler> handlers) throws IOException, ServletException
{
+  public void handle(String target, Request baseRequest,
+                     HttpServletRequest request, HttpServletResponse response)
+      throws IOException, ServletException {
 
     ViewEntity viewEntity = getTargetView(target);
 
     if (viewEntity == null) {
-      super.handleNonFailSafe(target, baseRequest, request, response, handlers);
+      processHandlers(target, baseRequest, request, response);
     } else {
       // if there is a view target (as in a view resource request) then set the view class
loader
       ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
@@ -163,11 +145,11 @@ public class AmbariHandlerList extends FailsafeHandlerList implements
ViewInstan
       try {
         viewClassLoader = viewEntity.getClassLoader();
         if (viewClassLoader == null) {
-          LOG.warn("No class loader associated with view " + viewEntity.getName() + ".");
+          LOG.debug("No class loader associated with view " + viewEntity.getName() + ".");
         } else {
           Thread.currentThread().setContextClassLoader(viewClassLoader);
         }
-        super.handleNonFailSafe(target, baseRequest, request, response, handlers);
+        processHandlers(target, baseRequest, request, response);
       } finally {
         if (viewClassLoader != null) {
           Thread.currentThread().setContextClassLoader(contextClassLoader);
@@ -183,7 +165,7 @@ public class AmbariHandlerList extends FailsafeHandlerList implements
ViewInstan
   public void addViewInstance(ViewInstanceEntity viewInstanceDefinition) throws SystemException
{
     Handler handler = getHandler(viewInstanceDefinition);
     handlerMap.put(viewInstanceDefinition, handler);
-    addFailsafeHandler(handler);
+    addHandler(handler);
     // if this is running then start the handler being added...
     if(!isStopped() && !isStopping()) {
       try {
@@ -206,6 +188,23 @@ public class AmbariHandlerList extends FailsafeHandlerList implements
ViewInstan
 
   // ----- helper methods ----------------------------------------------------
 
+  // call the handlers until the request is handled
+  private void processHandlers(String target, Request baseRequest,
+                               HttpServletRequest request, HttpServletResponse response)
+      throws IOException, ServletException {
+
+    final Handler[] handlers = getHandlers();
+
+    if (handlers != null && isStarted()) {
+      for (Handler handler : handlers) {
+        handler.handle(target, baseRequest, request, response);
+        if (baseRequest.isHandled()) {
+          return;
+        }
+      }
+    }
+  }
+
   /**
    * Get a Handler for the given view instance.
    *
@@ -221,7 +220,6 @@ public class AmbariHandlerList extends FailsafeHandlerList implements
ViewInstan
     return handlerFactory.create(viewInstanceDefinition, viewDefinition.getArchive(), viewInstanceDefinition.getContextPath());
   }
 
-
   /**
    * Get the view that is the target of the request; null if not a view request.
    *

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 9b340ee..4e684d3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -257,7 +257,6 @@ public class AmbariServer {
       root.getServletContext().setAttribute(
           WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
           springWebAppContext);
-      handlerList.setSpringWebAppContext(springWebAppContext);
 
       certMan.initRootCert();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
deleted file mode 100644
index 26395cc..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * 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.ambari.server.controller;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.HandlerCollection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This extension of {@link HandlerCollection} will call each contained handler
- * in turn until the response is committed, a positive response status is set or
- * an exception from important handler is thrown. Handlers added via
- * {@link #addFailsafeHandler(Handler)} do not stop the polling when they raise
- * an exception.
- *
- */
-public class FailsafeHandlerList extends HandlerCollection {
-
-  /**
-   * Logger.
-   */
-  private static Logger LOG = LoggerFactory.getLogger(FailsafeHandlerList.class);
-
-  /**
-   * Fail-safe handlers do not stop the processing of the request if they raise an exception.
-   */
-  private final List<Handler> failsafeHandlers = new ArrayList<Handler>();
-
-
-  // ----- Constructors ------------------------------------------------------
-
-  /**
-   * Construct a FailsafeHandlerList.
-   */
-  public FailsafeHandlerList() {
-  }
-
-  /**
-   * Construct a FailsafeHandlerList.
-   *
-   * @param mutableWhenRunning allow for changes while running
-   */
-  public FailsafeHandlerList(boolean mutableWhenRunning) {
-    super(mutableWhenRunning);
-  }
-
-
-  // ----- FailsafeHandlerList -----------------------------------------------
-
-  /**
-   * Adds handler to collection and marks it as fail-safe.
-   *
-   * @param handler fail-safe handler
-   */
-  public void addFailsafeHandler(Handler handler) {
-    addHandler(handler);
-    failsafeHandlers.add(handler);
-  }
-
-
-  // ----- HandlerCollection -------------------------------------------------
-
-  @Override
-  public void removeHandler(Handler handler) {
-    super.removeHandler(handler);
-    failsafeHandlers.remove(handler);
-  }
-
-  /**
-   * @see Handler#handle(String, Request, HttpServletRequest,
-   *      HttpServletResponse)
-   */
-  @Override
-  public void handle(String target, Request baseRequest,
-      HttpServletRequest request, HttpServletResponse response)
-      throws IOException, ServletException {
-
-    final Handler[] handlers = getHandlers();
-
-    if (handlers != null && isStarted()) {
-
-      List<Handler> nonFailsafeHandlers = new ArrayList<Handler>();
-
-      for (int i = 0; i < handlers.length; i++) {
-        final Handler handler = handlers[i];
-        // Do all of the fail-safe handlers first...
-        if (failsafeHandlers.contains(handler)) {
-          try {
-            final FailsafeServletResponse responseWrapper = new FailsafeServletResponse(response);
-            handler.handle(target, baseRequest, request, responseWrapper);
-            if (responseWrapper.isRequestFailed()) {
-              response.reset();
-              baseRequest.setHandled(false);
-            }
-          } catch (Exception ex) {
-            LOG.warn("Fail-safe handler failed to process request, continuing handler polling",
ex);
-            continue;
-          }
-        } else {
-          nonFailsafeHandlers.add(handler);
-        }
-        if (baseRequest.isHandled()) {
-          return;
-        }
-      }
-      handleNonFailSafe(target, baseRequest, request, response, nonFailsafeHandlers);
-    }
-  }
-
-  /**
-   * Attempt to handle the request with the non-failsafe handlers.
-   *
-   * @param target       the target of the request - either a URI or a name
-   * @param baseRequest  the original unwrapped request object.
-   * @param request      the request
-   * @param response     the response
-   * @param handlers     the non-failsafe handlers
-   */
-  protected void handleNonFailSafe(String target, Request baseRequest, HttpServletRequest
request,
-                                   HttpServletResponse response, List<Handler> handlers)
-      throws IOException, ServletException {
-
-    for (Handler handler : handlers) {
-      handler.handle(target, baseRequest, request, response);
-      if (baseRequest.isHandled()) {
-        return;
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java
deleted file mode 100644
index 094c4c5..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * 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.ambari.server.controller;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
-
-/**
- * Wraps standard wrapper for {@link HttpServletResponse} to cancel sending
- * errors on failed requests.
- */
-public class FailsafeServletResponse extends HttpServletResponseWrapper {
-  /**
-   * Indicates that request failed.
-   */
-  private boolean error;
-
-  /**
-   * List of errors which should not be consumed by fail-safe handler.
-   */
-  private List<Integer> allowedErrors = Arrays.asList(HttpServletResponse.SC_FORBIDDEN);
-
-  /**
-   * Constructor.
-   *
-   * @param response response to be wrapped
-   */
-  public FailsafeServletResponse(HttpServletResponse response) {
-    super(response);
-  }
-
-  @Override
-  public void sendError(int sc) throws IOException {
-    if (allowedErrors.contains(sc)) {
-      super.sendError(sc);
-    } else {
-      error = true;
-    }
-  }
-
-  @Override
-  public void sendError(int sc, String msg) throws IOException {
-    if (allowedErrors.contains(sc)) {
-      super.sendError(sc, msg);
-    } else {
-      error = true;
-    }
-  }
-
-  /**
-   * Indicates that request failed to execute.
-   *
-   * @return true if request failed
-   */
-  public boolean isRequestFailed() {
-    return error;
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/main/java/org/apache/ambari/server/view/ViewArchiveUtility.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewArchiveUtility.java
b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewArchiveUtility.java
index 8720d7c..3ff640e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewArchiveUtility.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewArchiveUtility.java
@@ -48,6 +48,7 @@ public class ViewArchiveUtility {
    * Constants
    */
   private static final String VIEW_XML = "view.xml";
+  private static final String WEB_INF_VIEW_XML = "WEB-INF/classes/" + VIEW_XML;
   private static final String VIEW_XSD = "view.xsd";
 
 
@@ -66,7 +67,11 @@ public class ViewArchiveUtility {
       throws MalformedURLException, JAXBException {
     ClassLoader cl = URLClassLoader.newInstance(new URL[]{archiveFile.toURI().toURL()});
 
-    InputStream configStream      = cl.getResourceAsStream(VIEW_XML);
+    InputStream configStream = cl.getResourceAsStream(VIEW_XML);
+    if (configStream == null) {
+      configStream = cl.getResourceAsStream(WEB_INF_VIEW_XML);
+    }
+
     JAXBContext jaxbContext       = JAXBContext.newInstance(ViewConfig.class);
     Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
 
@@ -90,6 +95,10 @@ public class ViewArchiveUtility {
 
     File configFile = new File(archivePath + File.separator + VIEW_XML);
 
+    if (!configFile.exists()) {
+      configFile = new File(archivePath + File.separator + WEB_INF_VIEW_XML);
+    }
+
     if (validate) {
       validateConfig(new FileInputStream(configFile));
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java
b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java
new file mode 100644
index 0000000..7c8f7bd
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java
@@ -0,0 +1,118 @@
+/**
+ * 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.ambari.server.view;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+
+/**
+ * Class loader used to load classes and resources from a search path of URLs referring to
both JAR files
+ * and directories.  The URLs will be searched in the order specified for classes and resources
before
+ * searching the parent class loader.
+ */
+public class ViewClassLoader extends URLClassLoader {
+
+  // ----- Constructors ------------------------------------------------------
+
+  /**
+   * Constructs a new ViewClassLoader for the given URLs using a default parent class loader.
+   * The URLs will be searched in the order specified for classes and resources before searching
+   * the parent class loader.
+   *
+   * @param urls  the URLs from which to load classes and resources
+   */
+  public ViewClassLoader(URL[] urls) {
+    this(null, urls);
+  }
+
+  /**
+   * Constructs a new ViewClassLoader for the given URLs.
+   * The URLs will be searched in the order specified for classes and resources before searching
the specified
+   * parent class loader.
+   *
+   * @param parent  the parent class loader
+   * @param urls    the URLs from which to load classes and resources
+   */
+  public ViewClassLoader(ClassLoader parent, URL[] urls) {
+    super(new URL[]{}, selectParentClassLoader(parent));
+
+    for (URL url : urls) {
+      addURL(url);
+    }
+  }
+
+
+  // ----- ClassLoader -------------------------------------------------------
+
+  @Override
+  public synchronized URL getResource(String name) {
+    URL resource = this.findResource(name);
+
+    if (resource == null) {
+      ClassLoader parentClassLoader = getParent();
+      if (parentClassLoader != null) {
+        resource = parentClassLoader.getResource(name);
+      }
+    }
+    return resource;
+  }
+
+  @Override
+  protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException
{
+    Class clazz = findLoadedClass(name);
+
+    if (clazz == null) {
+      try {
+        clazz = this.findClass(name);
+      } catch (ClassNotFoundException e) {
+        ClassLoader parentClassLoader = getParent();
+        if (parentClassLoader != null) {
+          clazz = parentClassLoader.loadClass(name);
+        }
+
+        if (clazz == null) {
+          throw e;
+        }
+      }
+    }
+
+    if (resolve) {
+      resolveClass(clazz);
+    }
+    return clazz;
+  }
+
+
+  // ----- helper methods ----------------------------------------------------
+
+  // Get an appropriate parent class loader.
+  private static ClassLoader selectParentClassLoader(ClassLoader parentClassLoader) {
+
+    if (parentClassLoader == null) {
+
+      parentClassLoader = Thread.currentThread().getContextClassLoader();
+
+      if (parentClassLoader == null) {
+        parentClassLoader = ViewClassLoader.class.getClassLoader();
+      }
+    }
+    return parentClassLoader;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
index fdce03c..73b0059 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
@@ -27,7 +27,6 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.net.URLClassLoader;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.jar.JarEntry;
@@ -210,7 +209,7 @@ public class ViewExtractor {
     // include the archive directory
     urlList.add(archiveDir.toURI().toURL());
 
-    return URLClassLoader.newInstance(urlList.toArray(new URL[urlList.size()]));
+    return new ViewClassLoader(urlList.toArray(new URL[urlList.size()]));
   }
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
index 04a4b15..dba9147 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
@@ -35,8 +35,6 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
 
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
@@ -116,7 +114,7 @@ public class AmbariHandlerListTest {
   }
 
   @Test
-  public void testHandleNonFailSafe() throws Exception {
+  public void testHandle() throws Exception {
     TestHandler handler = new TestHandler();
     AmbariHandlerList.HandlerFactory handlerFactory = createNiceMock(AmbariHandlerList.HandlerFactory.class);
     ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
@@ -128,9 +126,6 @@ public class AmbariHandlerListTest {
     HttpServletRequest request = createNiceMock(HttpServletRequest.class);
     HttpServletResponse response = createNiceMock(HttpServletResponse.class);
 
-    List <Handler> handlers = new LinkedList<Handler>();
-    handlers.add(handler);
-
     expect(viewRegistry.getDefinition("TEST", "1.0.0")).andReturn(viewEntity).anyTimes();
     expect(viewEntity.getClassLoader()).andReturn(classLoader).anyTimes();
 
@@ -139,8 +134,10 @@ public class AmbariHandlerListTest {
     AmbariHandlerList handlerList = new AmbariHandlerList(handlerFactory);
     handlerList.viewRegistry = viewRegistry;
 
-    handlerList.handleNonFailSafe("/api/v1/views/TEST/versions/1.0.0/instances/INSTANCE_1/resources/test",
-        baseRequest, request, response, handlers);
+    handlerList.addHandler(handler);
+    handlerList.start();
+    handlerList.handle("/api/v1/views/TEST/versions/1.0.0/instances/INSTANCE_1/resources/test",
+        baseRequest, request, response);
 
     Assert.assertEquals("/api/v1/views/TEST/versions/1.0.0/instances/INSTANCE_1/resources/test",
handler.getTarget());
     Assert.assertEquals(classLoader, handler.getClassLoader());

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/test/java/org/apache/ambari/server/controller/FailsafeHandlerListTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/FailsafeHandlerListTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/controller/FailsafeHandlerListTest.java
deleted file mode 100644
index 8d1ba0d..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/FailsafeHandlerListTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * 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.ambari.server.controller;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.easymock.EasyMock;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Request;
-import org.junit.Test;
-
-/**
- * Tests the {@link FailsafeHandlerList} class
- */
-public class FailsafeHandlerListTest {
-  @Test
-  public void testHandleWithFailures() throws Exception {
-    final FailsafeHandlerList handlerList = EasyMock
-        .createMockBuilder(FailsafeHandlerList.class).withConstructor()
-        .addMockedMethod("isStarted").createMock();
-    EasyMock.expect(handlerList.isStarted()).andReturn(false).times(3).andReturn(true).anyTimes();
-    final Handler normalHandler1 = EasyMock.createNiceMock(Handler.class);
-    final Handler normalHandler2 = EasyMock.createNiceMock(Handler.class);
-    final Handler failureHandler = EasyMock.createNiceMock(Handler.class);
-    final HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
-    final HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
-    normalHandler1.handle(EasyMock.<String> anyObject(),
-        EasyMock.<Request> anyObject(),
-        EasyMock.<HttpServletRequest> anyObject(),
-        EasyMock.<HttpServletResponse> anyObject());
-    EasyMock.expectLastCall().once();
-    normalHandler2.handle(EasyMock.<String> anyObject(),
-        EasyMock.<Request> anyObject(),
-        EasyMock.<HttpServletRequest> anyObject(),
-        EasyMock.<HttpServletResponse> anyObject());
-    EasyMock.expectLastCall().once();
-    failureHandler.handle(EasyMock.<String> anyObject(),
-        EasyMock.<Request> anyObject(),
-        EasyMock.<HttpServletRequest> anyObject(),
-        EasyMock.<HttpServletResponse> anyObject());
-    EasyMock.expectLastCall().andThrow(new IOException());
-    EasyMock.replay(handlerList, normalHandler1, normalHandler2, failureHandler);
-
-    handlerList.addFailsafeHandler(normalHandler1);
-    handlerList.addFailsafeHandler(failureHandler);
-    handlerList.addFailsafeHandler(normalHandler2);
-    handlerList.start();
-    handlerList.handle("", new Request(), request, response);
-
-    EasyMock.verify(handlerList, normalHandler1, normalHandler2, failureHandler);
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/test/java/org/apache/ambari/server/controller/FailsafeServletResponseTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/FailsafeServletResponseTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/controller/FailsafeServletResponseTest.java
deleted file mode 100644
index 249a3f5..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/FailsafeServletResponseTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.ambari.server.controller;
-
-import javax.servlet.http.HttpServletResponse;
-
-import junit.framework.Assert;
-
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.junit.Test;
-
-/**
- * Tests the {@link FailsafeServletResponse} class
- */
-public class FailsafeServletResponseTest {
-  @Test
-  public void testRequestFailure() throws Exception {
-    final HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
-    final FailsafeServletResponse responseWrapper = new FailsafeServletResponse(response);
-    final IAnswer<Void> answer = new IAnswer<Void>() {
-      @Override
-      public Void answer() throws Throwable {
-        Assert.fail("Original response should not commit errors");
-        return null;
-      }
-    };
-    response.sendError(0);
-    EasyMock.expectLastCall().andAnswer(answer).anyTimes();
-    response.sendError(0, "");
-    EasyMock.expectLastCall().andAnswer(answer).anyTimes();
-    EasyMock.replay(response);
-    responseWrapper.sendError(0);
-    responseWrapper.sendError(0, "");
-    Assert.assertTrue(responseWrapper.isRequestFailed());
-    EasyMock.verify(response);
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f82ed921/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java
new file mode 100644
index 0000000..1f1ae9b
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java
@@ -0,0 +1,101 @@
+/**
+ * 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.ambari.server.view;
+
+import junit.framework.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.net.URL;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * ViewClassLoader test.
+ */
+public class ViewClassLoaderTest {
+
+  @Test
+  public void testGetResource() throws Exception {
+    ClassLoader parentClassLoader = createMock(ClassLoader.class);
+    URL parentResource = new File("parent-resource").toURI().toURL();
+
+    expect(parentClassLoader.getResource("parent-resource")).andReturn(parentResource).once();
+
+    replay(parentClassLoader);
+
+    File file = new File("./src/test/resources");
+    URL testURL = file.toURI().toURL();
+
+    URL[] urls = new URL[]{testURL};
+
+    ViewClassLoader classLoader = new ViewClassLoader(parentClassLoader, urls);
+
+    URL url = classLoader.getResource("ambari.properties");
+
+    Assert.assertNotNull(url);
+
+    url = classLoader.getResource("parent-resource");
+
+    Assert.assertNotNull(url);
+    Assert.assertSame(parentResource, url);
+
+    verify(parentClassLoader);
+  }
+
+  @Test
+  public void testLoadClass() throws Exception {
+    TestClassLoader parentClassLoader = createMock(TestClassLoader.class);
+    Class parentClass = Object.class;
+
+    expect(parentClassLoader.getPackage("org.apache.ambari.server.view")).andReturn(null).anyTimes();
+    expect(parentClassLoader.loadClass("java.lang.Object")).andReturn(parentClass).anyTimes();
+    expect(parentClassLoader.loadClass("ParentClass")).andReturn(parentClass).once();
+
+    replay(parentClassLoader);
+
+    File file = new File("./target/test-classes");
+    URL testURL = file.toURI().toURL();
+
+    URL[] urls = new URL[]{testURL};
+
+    ViewClassLoader classLoader = new ViewClassLoader(parentClassLoader, urls);
+
+    Class clazz = classLoader.loadClass("org.apache.ambari.server.view.ViewClassLoaderTest");
+
+    Assert.assertNotNull(clazz);
+
+    clazz = classLoader.loadClass("ParentClass");
+
+    Assert.assertNotNull(clazz);
+    Assert.assertSame(parentClass, clazz);
+
+    verify(parentClassLoader);
+  }
+
+  public class TestClassLoader extends ClassLoader {
+    @Override
+    public Package getPackage(String s) {
+      return super.getPackage(s);
+    }
+  }
+}


Mime
View raw message