All classes loaded through the 'vm' object will have 'invoke' method that can be used to invoke static methods like main(String[]), so our examples no longer need to rely on initialization in static initializers.
1.1 --- a/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calc.java Wed May 28 09:07:48 2014 +0200
1.2 +++ b/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calc.java Wed May 28 10:47:18 2014 +0200
1.3 @@ -39,7 +39,7 @@
1.4 @Property(name = "history", type = double.class, array = true)
1.5 })
1.6 public class Calc {
1.7 - static {
1.8 + public static void main(String... args) throws Exception {
1.9 new Calculator().applyBindings().setOperation("plus");
1.10 }
1.11
2.1 --- a/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Wed May 28 09:07:48 2014 +0200
2.2 +++ b/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Wed May 28 10:47:18 2014 +0200
2.3 @@ -92,7 +92,8 @@
2.4 <script src="bck2brwsr.js"></script>
2.5 <script>
2.6 var vm = bck2brwsr('calculator.js');
2.7 - vm.loadClass('org.apidesign.bck2brwsr.demo.calc.staticcompilation.Calc');
2.8 + var c = vm.loadClass('org.apidesign.bck2brwsr.demo.calc.staticcompilation.Calc');
2.9 + c.invoke('main');
2.10 </script>
2.11 </body>
2.12 </html>
3.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Wed May 28 09:07:48 2014 +0200
3.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Wed May 28 10:47:18 2014 +0200
3.3 @@ -26,7 +26,7 @@
3.4 * be used to bootstrap and load the virtual machine: <pre>
3.5 * var vm = bck2brwsr();
3.6 * var main = vm.loadClass('org.your.pkg.Main');
3.7 - * main.main__V_3Ljava_lang_String_2(null);
3.8 + * main.invoke('main');
3.9 * </pre>
3.10 * In case one wants to initialize the virtual machine with ability to
3.11 * load classes lazily when needed, one can provide a loader function to
3.12 @@ -39,15 +39,27 @@
3.13 * function is asked for its byte code and the system dynamically transforms
3.14 * it to JavaScript.
3.15 * <p>
3.16 - * Instead of a loader function, one can also provide a URL to a JAR file.
3.17 + * Instead of a loader function, one can also provide a URL to a JAR file
3.18 + * or a library JavaScript file generated with {@link #library(java.lang.String...)}
3.19 + * option on.
3.20 * The <code>bck2brwsr</code> system will do its best to download the file
3.21 - * and provide loader function for it automatically.
3.22 + * and provide loader function for it automatically. In order to use
3.23 + * the JAR file <code>emul.zip</code> module needs to be available in the system.
3.24 * <p>
3.25 - * One can provide as many loader functions and JAR URL references as necessary.
3.26 + * One can provide as many loader functions and URL references as necessary.
3.27 * Then the initialization code would look like:<pre>
3.28 * var vm = bck2brwsr(url1, url2, fnctn1, url3, functn2);
3.29 * </pre>
3.30 * The provided URLs and loader functions will be consulted one by one.
3.31 + * <p>
3.32 + * The initialization of the <b>Bck2Brwsr</b> is done asynchronously since
3.33 + * version 0.9. E.g. call to <pre>
3.34 + * var vm = bck2brwsr('myapp.js');
3.35 + * var main = vm.loadClass('org.your.pkg.Main');
3.36 + * main.invoke('main');
3.37 + * </pre>
3.38 + * returns immediately and the call to the static main method will happen
3.39 + * once the virtual machine is initialized and the class available.
3.40 *
3.41 * @author Jaroslav Tulach <jtulach@netbeans.org>
3.42 */
4.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Wed May 28 09:07:48 2014 +0200
4.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Wed May 28 10:47:18 2014 +0200
4.3 @@ -493,14 +493,28 @@
4.4 + " var at = pending.indexOf(ev.target);\n"
4.5 + " pending.splice(at, 1);\n"
4.6 + " if (pending.length === 0) {\n"
4.7 - + " for (var i = 0; i < pendingClasses.length; i += 2) {\n"
4.8 - + " var vm = pendingClasses[i];\n"
4.9 - + " var n = pendingClasses[i + 1];\n"
4.10 - + " vm.loadClass(n);\n"
4.11 + + " for (var i = 0; i < pendingClasses.length; i += 3) {\n"
4.12 + + " invokeMethod(pendingClasses[i], pendingClasses[i + 1], pendingClasses[i + 2]);\n"
4.13 + " }\n"
4.14 + " pendingClasses = [];\n"
4.15 + " }\n"
4.16 + " }\n"
4.17 + + " function invokeMethod(vm, n, args) {\n"
4.18 + + " var clazz = vm.loadClass(n);\n"
4.19 + + " if (args) {\n"
4.20 + + " var seek = args[0];\n"
4.21 + + " var prefix = seek.indexOf('__') == -1 ? seek + '__' : seek;\n"
4.22 + + " args = Array.prototype.slice.call(args, 1);\n"
4.23 + + " var found = '';\n"
4.24 + + " for (var m in clazz) {\n"
4.25 + + " if (m.indexOf(prefix) === 0) {\n"
4.26 + + " return clazz[m].apply(null, args);\n"
4.27 + + " }\n"
4.28 + + " found += m.toString() + '\\n'\n"
4.29 + + " }\n"
4.30 + + " throw 'Cannot find ' + seek + ' in ' + n + ' found:\\n' + found;\n"
4.31 + + " }\n"
4.32 + + " }\n"
4.33 + " function extensionError(ev) {\n"
4.34 + " console.log('error loading ' + ev.target.src);\n"
4.35 + " extensionLoaded(ev);\n"
4.36 @@ -611,14 +625,29 @@
4.37 + " loader.loadClass = function(name) {\n"
4.38 + " if (pending.length === 0) {\n"
4.39 + " try {\n"
4.40 - + " return loadClass(name);\n"
4.41 + + " var c = loadClass(name);\n"
4.42 + + " c['invoke'] = function() {\n"
4.43 + + " return invokeMethod(vm, name, arguments);\n"
4.44 + + " };\n"
4.45 + + " return c;\n"
4.46 + " } catch (err) {\n"
4.47 + " if (pending.length === 0) throw err;\n"
4.48 + " }\n"
4.49 + " }\n"
4.50 + " pendingClasses.push(vm);\n"
4.51 + " pendingClasses.push(name);\n"
4.52 - + " return null;\n"
4.53 + + " pendingClasses.push(null);\n"
4.54 + + " return {\n"
4.55 + + " 'invoke' : function() {\n"
4.56 + + " if (pending.length === 0) {\n"
4.57 + + " invokeMethod(vm, name, arguments);\n"
4.58 + + " return;\n"
4.59 + + " }\n"
4.60 + + " pendingClasses.push(vm);\n"
4.61 + + " pendingClasses.push(name);\n"
4.62 + + " pendingClasses.push(arguments);\n"
4.63 + + " }\n"
4.64 + + " };\n"
4.65 + " }\n"
4.66 + " return loader;\n"
4.67 + " };\n");
5.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Wed May 28 09:07:48 2014 +0200
5.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Wed May 28 10:47:18 2014 +0200
5.3 @@ -23,7 +23,10 @@
5.4 import java.io.IOException;
5.5 import java.io.InputStream;
5.6 import java.net.URL;
5.7 +import java.util.ArrayList;
5.8 +import java.util.Arrays;
5.9 import java.util.Enumeration;
5.10 +import java.util.List;
5.11 import javax.script.Invocable;
5.12 import javax.script.ScriptContext;
5.13 import javax.script.ScriptEngine;
5.14 @@ -60,7 +63,10 @@
5.15 Object ret = null;
5.16 try {
5.17 ret = code.invokeMethod(bck2brwsr, "loadClass", clazz.getName());
5.18 - ret = code.invokeMethod(ret, method, args);
5.19 + List<Object> ma = new ArrayList<>();
5.20 + ma.add(method);
5.21 + ma.addAll(Arrays.asList(args));
5.22 + ret = code.invokeMethod(ret, "invoke", ma.toArray());
5.23 } catch (ScriptException ex) {
5.24 fail("Execution failed in " + dumpJS(codeSeq) + ": " + ex.getMessage(), ex);
5.25 } catch (NoSuchMethodException ex) {