# HG changeset patch # User Jaroslav Tulach # Date 1371053969 -7200 # Node ID f78cdceed17bef61950427f7081ff5632def9dbc # Parent c04c43d5fdc6400899b0af12362e3617f1035020 Trying to use JsClassLoader in FX launcher diff -r c04c43d5fdc6 -r f78cdceed17b launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java Tue Jun 11 09:13:33 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java Wed Jun 12 18:19:29 2013 +0200 @@ -89,11 +89,12 @@ * Create a resizable WebView pane */ private static class WebController { - private final JVMBridge bridge = new JVMBridge(); + private final JVMBridge bridge; private final WebDebug dbg; private final String ud; public WebController(WebView view, String ud, List params) { + this.bridge = new JVMBridge(view.getEngine()); this.ud = ud; LOG.log(Level.INFO, "Initializing WebView with {0}", params); final WebEngine eng = view.getEngine(); diff -r c04c43d5fdc6 -r f78cdceed17b launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java Tue Jun 11 09:13:33 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java Wed Jun 12 18:19:29 2013 +0200 @@ -17,16 +17,27 @@ */ package org.apidesign.bck2brwsr.launcher.fximpl; +import java.net.URL; import java.util.TooManyListenersException; import javafx.beans.value.ChangeListener; +import javafx.scene.web.WebEngine; +import netscape.javascript.JSObject; /** * * @author Jaroslav Tulach */ public final class JVMBridge { + private final WebEngine engine; + private final WebClassLoader cl; + private static ClassLoader[] ldrs; private static ChangeListener onBck2BrwsrLoad; + + JVMBridge(WebEngine eng) { + this.engine = eng; + this.cl = new WebClassLoader(JVMBridge.class.getClassLoader()); + } public static void registerClassLoaders(ClassLoader[] loaders) { ldrs = loaders.clone(); @@ -47,18 +58,57 @@ } public Class loadClass(String name) throws ClassNotFoundException { - System.err.println("trying to load " + name); - ClassNotFoundException ex = null; - if (ldrs != null) for (ClassLoader l : ldrs) { - try { - return Class.forName(name, true, l); - } catch (ClassNotFoundException ex2) { - ex = ex2; + return Class.forName(name, true, cl); + } + + private final class WebClassLoader extends JsClassLoader { + public WebClassLoader(ClassLoader parent) { + super(parent); + } + + @Override + protected URL findResource(String name) { + if (ldrs != null) for (ClassLoader l : ldrs) { + URL u = l.getResource(name); + if (u != null) { + return u; + } } + return null; } - if (ex == null) { - ex = new ClassNotFoundException("No loaders"); + + @Override + protected Fn defineFn(String code, String... names) { + StringBuilder sb = new StringBuilder(); + sb.append("(function() {"); + sb.append(" var x = {};"); + sb.append(" x.fn = function("); + String sep = ""; + for (String n : names) { + sb.append(sep).append(n); + sep = ","; + } + sb.append(") {\n"); + sb.append(code); + sb.append("};"); + sb.append("return x;"); + sb.append("})()"); + + JSObject x = (JSObject) engine.executeScript(sb.toString()); + return new JSFn(x); } - throw ex; + } + + private static final class JSFn extends Fn { + private final JSObject fn; + + public JSFn(JSObject fn) { + this.fn = fn; + } + + @Override + public Object invoke(Object... args) throws Exception { + return fn.call("fn", args); // NOI18N + } } } diff -r c04c43d5fdc6 -r f78cdceed17b launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java Tue Jun 11 09:13:33 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java Wed Jun 12 18:19:29 2013 +0200 @@ -38,10 +38,13 @@ * * @author Jaroslav Tulach */ -abstract class JsClassLoader extends URLClassLoader { - JsClassLoader(URL[] urls, ClassLoader parent) { - super(urls, parent); +abstract class JsClassLoader extends ClassLoader { + JsClassLoader(ClassLoader parent) { + super(parent); } + + @Override + protected abstract URL findResource(String name); @Override protected Class findClass(String name) throws ClassNotFoundException { diff -r c04c43d5fdc6 -r f78cdceed17b launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java --- a/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java Tue Jun 11 09:13:33 2013 +0200 +++ b/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java Wed Jun 12 18:19:29 2013 +0200 @@ -20,6 +20,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; +import java.net.URLClassLoader; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; @@ -45,9 +46,14 @@ ScriptEngineManager sem = new ScriptEngineManager(); final ScriptEngine eng = sem.getEngineByMimeType("text/javascript"); - URL my = JsClassLoaderTest.class.getProtectionDomain().getCodeSource().getLocation(); + final URL my = JsClassLoaderTest.class.getProtectionDomain().getCodeSource().getLocation(); ClassLoader parent = JsClassLoaderTest.class.getClassLoader().getParent(); - loader = new JsClassLoader(new URL[] { my }, parent) { + final URLClassLoader ul = new URLClassLoader(new URL[] { my }, parent); + loader = new JsClassLoader(parent) { + @Override + protected URL findResource(String name) { + return ul.getResource(name); + } @Override protected Fn defineFn(String code, String... names) { StringBuilder sb = new StringBuilder();