Simplified GWTShellServlet's pinning and lookup of servlet instances by module. Changed HostedModeServletContextProxy to assert that its weakly-referenced moduleDef is non-null. Suggested by: jat Review by: jat git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2212 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java b/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java index 2d9a301..d348d97 100644 --- a/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java +++ b/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java
@@ -96,20 +96,12 @@ ReferenceMap.HARD, ReferenceMap.WEAK); /** - * Used to quickly lookup servlets by name, but does not pin them; servlets - * are pinned by their module in {@link #loadedServletsPinnedByModule}. - */ - @SuppressWarnings("unchecked") - private final Map<String, HttpServlet> loadedServletsByModuleAndClassName = new ReferenceMap( - ReferenceMap.HARD, ReferenceMap.WEAK); - - /** * The lifetime of the module pins the lifetime of the associated servlet; * this is because the loaded servlet has a weak backRef to its live module * through its context. When the module dies, the servlet needs to die also. */ @SuppressWarnings("unchecked") - private final Map<ModuleDef, HttpServlet> loadedServletsPinnedByModule = new ReferenceMap( + private final Map<ModuleDef, Map<String, HttpServlet>> loadedServletsByModuleAndClassName = new ReferenceMap( ReferenceMap.WEAK, ReferenceMap.HARD, true); private final Map<String, String> mimeTypes = new HashMap<String, String>(); @@ -926,9 +918,19 @@ private HttpServlet tryGetOrLoadServlet(TreeLogger logger, ModuleDef moduleDef, String className) { + + // Maps className to live servlet for this module. + Map<String, HttpServlet> moduleServlets; synchronized (loadedServletsByModuleAndClassName) { - String moduleAndClassName = moduleDef.getName() + "/" + className; - HttpServlet servlet = loadedServletsByModuleAndClassName.get(moduleAndClassName); + moduleServlets = loadedServletsByModuleAndClassName.get(moduleDef); + if (moduleServlets == null) { + moduleServlets = new HashMap<String, HttpServlet>(); + loadedServletsByModuleAndClassName.put(moduleDef, moduleServlets); + } + } + + synchronized (moduleServlets) { + HttpServlet servlet = moduleServlets.get(className); if (servlet != null) { // Found it. // @@ -963,8 +965,7 @@ servlet.init(config); - loadedServletsByModuleAndClassName.put(moduleAndClassName, servlet); - loadedServletsPinnedByModule.put(moduleDef, servlet); + moduleServlets.put(className, servlet); return servlet; } catch (ClassNotFoundException e) { caught = e;
diff --git a/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java b/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java index 7f4a2af..adf1ced 100644 --- a/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java +++ b/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java
@@ -154,9 +154,10 @@ */ public URL getResource(String path) throws MalformedURLException { ModuleDef moduleDef = moduleDefRef.get(); - if (moduleDef == null) { - return context.getResource(path); - } + assert (moduleDef != null) : "GWTShellServlet should have guaranteed that a" + + " live servlet will never process a request for a dead module; if you" + + " are using this servlet outside the context of processing a call," + + " then don't do that"; String moduleContext = "/" + moduleDef.getName() + "/"; if (!path.startsWith(moduleContext)) { @@ -164,7 +165,7 @@ moduleContext = "/" + moduleDef.getCanonicalName() + "/"; if (!path.startsWith(moduleContext)) { // This path is in a different context; just return null - return null; + return null; } }