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;
}
}