Delay JSNI injection until the end of loadClass instead of doing it eagerly in findClass; we were getting problems with circular class load dependencies.
Review by: jat (postmortem)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2606 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
index 8152abb..9b4cd4b 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
@@ -541,29 +541,38 @@
updateJavaScriptHost();
}
- JsniMethods jsniMethods = newClass.getAnnotation(JsniMethods.class);
- if (jsniMethods != null) {
- for (JsniMethod jsniMethod : jsniMethods.value()) {
- String[] bodyParts = jsniMethod.body();
- int size = 0;
- for (String bodyPart : bodyParts) {
- size += bodyPart.length();
- }
- StringBuilder body = new StringBuilder(size);
- for (String bodyPart : bodyParts) {
- body.append(bodyPart);
- }
- shellJavaScriptHost.createNative(jsniMethod.file(),
- jsniMethod.line(), jsniMethod.name(), jsniMethod.paramNames(),
- body.toString());
- }
- }
return newClass;
} catch (UnableToCompleteException e) {
throw new ClassNotFoundException(className);
}
}
+ /**
+ * Overridden to process JSNI annotations.
+ */
+ @Override
+ protected synchronized Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ Class<?> newClass = super.loadClass(name, resolve);
+ JsniMethods jsniMethods = newClass.getAnnotation(JsniMethods.class);
+ if (jsniMethods != null) {
+ for (JsniMethod jsniMethod : jsniMethods.value()) {
+ String[] bodyParts = jsniMethod.body();
+ int size = 0;
+ for (String bodyPart : bodyParts) {
+ size += bodyPart.length();
+ }
+ StringBuilder body = new StringBuilder(size);
+ for (String bodyPart : bodyParts) {
+ body.append(bodyPart);
+ }
+ shellJavaScriptHost.createNative(jsniMethod.file(), jsniMethod.line(),
+ jsniMethod.name(), jsniMethod.paramNames(), body.toString());
+ }
+ }
+ return newClass;
+ }
+
void clear() {
// Release our references to the shell.
shellJavaScriptHost = null;
@@ -614,8 +623,9 @@
* @see JavaScriptHost
*/
private void updateJavaScriptHost() {
- // Find the application's JavaScriptHost interface.
- //
+ if (javaScriptHostClass == null) {
+ return;
+ }
Throwable caught;
try {
final Class<?>[] paramTypes = new Class[] {ShellJavaScriptHost.class};