# HG changeset patch # User Jaroslav Tulach # Date 1417296340 -3600 # Node ID af690d50d7d6bfb0feba300ff0a0c3eaca5b8135 # Parent 3299d5335b8f4592812120f3ed627dfca3cd262a Use optional dependency on asm-5.0.jar, so we don't have to bundle it when the classes are post processed. diff -r 3299d5335b8f -r af690d50d7d6 boot-agent-test/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-agent-test/pom.xml Sat Nov 29 22:25:40 2014 +0100 @@ -0,0 +1,61 @@ + + + 4.0.0 + + org.netbeans.html + pom + 2.0-SNAPSHOT + + boot-agent-test + jar + Dynamic Boot Test + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + + + org.testng + testng + test + + + org.netbeans.html + net.java.html + ${project.version} + test + jar + + + org.netbeans.html + net.java.html.boot + ${project.version} + test + jar + + + org.netbeans.api + org-openide-util-lookup + test + jar + + + ${project.groupId} + net.java.html.boot.fx + ${project.version} + test + + + org.ow2.asm + asm + test + + + \ No newline at end of file diff -r 3299d5335b8f -r af690d50d7d6 boot-agent-test/src/test/java/org/netbeans/html/bootagent/DynamicClassLoaderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-agent-test/src/test/java/org/netbeans/html/bootagent/DynamicClassLoaderTest.java Sat Nov 29 22:25:40 2014 +0100 @@ -0,0 +1,126 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.bootagent; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import net.java.html.BrwsrCtx; +import net.java.html.boot.BrowserBuilder; +import org.netbeans.html.boot.spi.Fn; +import org.testng.Assert; +import static org.testng.Assert.assertNotSame; +import static org.testng.Assert.assertSame; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +public class DynamicClassLoaderTest { + private static Class browserClass; + private static Fn.Presenter browserPresenter; + + public DynamicClassLoaderTest() { + } + + @Factory public static Object[] compatibilityTests() throws Exception { + final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(DynamicClassLoaderTest.class). + loadPage("empty.html"). + invoke("initialized"); + + Executors.newSingleThreadExecutor().submit(new Runnable() { + @Override + public void run() { + bb.showAndWait(); + } + }); + + List res = new ArrayList(); + + Class[] arr = new Class[] { loadClass() }; + for (Class c : arr) { + for (Method m : c.getDeclaredMethods()) { + if ((m.getModifiers() & Modifier.PUBLIC) != 0) { + res.add(new KOFx(browserPresenter, m)); + } + } + } + return res.toArray(); + } + + static synchronized Class loadClass() throws InterruptedException { + while (browserClass == null) { + DynamicClassLoaderTest.class.wait(); + } + return browserClass; + } + + public static void ready(Class browserCls) throws Exception { + Class origClazz = ClassLoader.getSystemClassLoader().loadClass(DynamicClassLoaderTest.class.getName()); + final Field f1 = origClazz.getDeclaredField("browserClass"); + f1.setAccessible(true); + f1.set(null, browserCls); + final Field f2 = origClazz.getDeclaredField("browserPresenter"); + f2.setAccessible(true); + f2.set(null, Fn.activePresenter()); + synchronized (origClazz) { + origClazz.notifyAll(); + } + } + + public static void initialized() throws Exception { + BrwsrCtx b1 = BrwsrCtx.findDefault(DynamicClassLoaderTest.class); + assertNotSame(b1, BrwsrCtx.EMPTY, "Browser context is not empty"); + BrwsrCtx b2 = BrwsrCtx.findDefault(DynamicClassLoaderTest.class); + assertSame(b1, b2, "Browser context remains stable"); + Assert.assertNotSame(DynamicClassLoaderTest.class.getClassLoader(), + ClassLoader.getSystemClassLoader(), + "Should use special classloader, not system one" + ); + DynamicClassLoaderTest.ready(JavaScriptBodyTst.class); + } +} diff -r 3299d5335b8f -r af690d50d7d6 boot-agent-test/src/test/java/org/netbeans/html/bootagent/JavaScriptBodyTst.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-agent-test/src/test/java/org/netbeans/html/bootagent/JavaScriptBodyTst.java Sat Nov 29 22:25:40 2014 +0100 @@ -0,0 +1,63 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.bootagent; + +import net.java.html.js.JavaScriptBody; + +/** + * + * @author Jaroslav Tulach + */ +public class JavaScriptBodyTst { + + public JavaScriptBodyTst() { + } + + public void assert42() { + int v = mul(7, 6); + assert v == 42 : "Really 42: " + v; + } + + @JavaScriptBody(args = { "x", "y" }, body = "return x * y;") + private static native int mul(int x, int y); +} diff -r 3299d5335b8f -r af690d50d7d6 boot-agent-test/src/test/java/org/netbeans/html/bootagent/KOFx.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-agent-test/src/test/java/org/netbeans/html/bootagent/KOFx.java Sat Nov 29 22:25:40 2014 +0100 @@ -0,0 +1,125 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.bootagent; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import javafx.application.Platform; +import org.netbeans.html.boot.impl.FnContext; +import org.netbeans.html.boot.spi.Fn; +import org.testng.IHookCallBack; +import org.testng.IHookable; +import org.testng.ITest; +import org.testng.ITestResult; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public final class KOFx implements ITest, IHookable, Runnable { + private final Fn.Presenter p; + private final Method m; + private Object result; + private Object inst; + + KOFx(Fn.Presenter p, Method m) { + this.p = p; + this.m = m; + } + + @Override + public String getTestName() { + return m.getName(); + } + + @Test + public synchronized void executeTest() throws Exception { + if (result == null) { + Platform.runLater(this); + wait(); + } + if (result instanceof Exception) { + throw (Exception)result; + } + if (result instanceof Error) { + throw (Error)result; + } + } + + @Override + public synchronized void run() { + boolean notify = true; + try { + FnContext.currentPresenter(p); + if (inst == null) { + inst = m.getDeclaringClass().newInstance(); + } + result = m.invoke(inst); + if (result == null) { + result = this; + } + } catch (InvocationTargetException ex) { + Throwable r = ex.getTargetException(); + if (r instanceof InterruptedException) { + notify = false; + Platform.runLater(this); + return; + } + result = r; + } catch (Exception ex) { + result = ex; + } finally { + if (notify) { + notifyAll(); + } + FnContext.currentPresenter(null); + } + } + + @Override + public void run(IHookCallBack ihcb, ITestResult itr) { + ihcb.runTestMethod(itr); + } + +} diff -r 3299d5335b8f -r af690d50d7d6 boot-agent-test/src/test/resources/org/netbeans/html/bootagent/empty.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-agent-test/src/test/resources/org/netbeans/html/bootagent/empty.html Sat Nov 29 22:25:40 2014 +0100 @@ -0,0 +1,55 @@ + + + + + Bootstrap Dynamically + + + + +
Bootstrap Dynamically
+ + diff -r 3299d5335b8f -r af690d50d7d6 boot-fx/src/test/java/org/netbeans/html/boot/fx/BootstrapTest.java --- a/boot-fx/src/test/java/org/netbeans/html/boot/fx/BootstrapTest.java Thu Nov 20 14:59:04 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/** - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.html.boot.fx; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import net.java.html.BrwsrCtx; -import net.java.html.boot.BrowserBuilder; -import org.netbeans.html.boot.spi.Fn; -import org.netbeans.html.context.spi.Contexts; -import org.netbeans.html.json.tck.KOTest; -import org.openide.util.lookup.ServiceProvider; -import org.testng.Assert; -import static org.testng.Assert.assertNotSame; -import static org.testng.Assert.assertSame; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Factory; - -/** - * - * @author Jaroslav Tulach - */ -public class BootstrapTest { - private static Class browserClass; - private static Fn.Presenter browserPresenter; - - public BootstrapTest() { - } - - @Factory public static Object[] compatibilityTests() throws Exception { - final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(BootstrapTest.class). - loadPage("empty.html"). - invoke("initialized"); - - Executors.newSingleThreadExecutor().submit(new Runnable() { - @Override - public void run() { - bb.showAndWait(); - } - }); - - List res = new ArrayList(); - Class test = - loadClass().getClassLoader().loadClass(KOTest.class.getName()). - asSubclass(Annotation.class); - - Class[] arr = (Class[]) loadClass().getDeclaredMethod("tests").invoke(null); - for (Class c : arr) { - for (Method m : c.getMethods()) { - if (m.getAnnotation(test) != null) { - res.add(new KOFx(browserPresenter, m)); - } - } - } - return res.toArray(); - } - - static synchronized Class loadClass() throws InterruptedException { - while (browserClass == null) { - BootstrapTest.class.wait(); - } - return browserClass; - } - - public static synchronized void ready(Class browserCls) throws Exception { - browserClass = browserCls; - browserPresenter = Fn.activePresenter(); - BootstrapTest.class.notifyAll(); - } - - public static void initialized() throws Exception { - BrwsrCtx b1 = BrwsrCtx.findDefault(BootstrapTest.class); - TestingProvider.assertCalled("Our context created"); - assertNotSame(b1, BrwsrCtx.EMPTY, "Browser context is not empty"); - BrwsrCtx b2 = BrwsrCtx.findDefault(BootstrapTest.class); - assertSame(b1, b2, "Browser context remains stable"); - Assert.assertSame( - BootstrapTest.class.getClassLoader(), - ClassLoader.getSystemClassLoader(), - "No special classloaders" - ); - BootstrapTest.ready(FxJavaScriptTst.class); - } -} diff -r 3299d5335b8f -r af690d50d7d6 boot/pom.xml --- a/boot/pom.xml Thu Nov 20 14:59:04 2014 +0100 +++ b/boot/pom.xml Sat Nov 29 22:25:40 2014 +0100 @@ -36,6 +36,8 @@ org.ow2.asm asm jar + provided + true org.testng diff -r 3299d5335b8f -r af690d50d7d6 boot/src/main/java/net/java/html/boot/BrowserBuilder.java --- a/boot/src/main/java/net/java/html/boot/BrowserBuilder.java Thu Nov 20 14:59:04 2014 +0100 +++ b/boot/src/main/java/net/java/html/boot/BrowserBuilder.java Sat Nov 29 22:25:40 2014 +0100 @@ -273,13 +273,16 @@ final ClassLoader activeLoader; if (loader != null) { - if (!FnUtils.isJavaScriptCapable(loader)) { + if (!FnContext.isJavaScriptCapable(loader)) { throw new IllegalStateException("Loader cannot resolve @JavaScriptBody: " + loader); } activeLoader = loader; - } else if (FnUtils.isJavaScriptCapable(myCls.getClassLoader())) { + } else if (FnContext.isJavaScriptCapable(myCls.getClassLoader())) { activeLoader = myCls.getClassLoader(); } else { + if (!FnContext.isAsmPresent()) { + throw new IllegalStateException("Cannot find asm-5.0.jar classes!"); + } FImpl impl = new FImpl(myCls.getClassLoader()); activeLoader = FnUtils.newLoader(impl, dfnr, myCls.getClassLoader().getParent()); } diff -r 3299d5335b8f -r af690d50d7d6 boot/src/main/java/net/java/html/js/package.html --- a/boot/src/main/java/net/java/html/js/package.html Thu Nov 20 14:59:04 2014 +0100 +++ b/boot/src/main/java/net/java/html/js/package.html Sat Nov 29 22:25:40 2014 +0100 @@ -231,6 +231,7 @@ calls or changes on it.

Post Process Classes

+ Classes with {@link net.java.html.js.JavaScriptBody} annotated methods need to be post processed before they can be used - e.g. their native @@ -290,7 +291,9 @@ will create a special classloader to that does the processing before loading the bytecode into the virtual machine.

- The options are rich, however to avoid any troubles, it is recommended + The options are rich, however to avoid any troubles (as the runtime + processing needs to also include asm-5.0.jar on application + classpath), it is recommended to perform the compile time processing.

Getting Started

diff -r 3299d5335b8f -r af690d50d7d6 boot/src/main/java/org/netbeans/html/boot/impl/FnContext.java --- a/boot/src/main/java/org/netbeans/html/boot/impl/FnContext.java Thu Nov 20 14:59:04 2014 +0100 +++ b/boot/src/main/java/org/netbeans/html/boot/impl/FnContext.java Sat Nov 29 22:25:40 2014 +0100 @@ -45,8 +45,10 @@ import java.io.Closeable; import java.io.Flushable; import java.io.IOException; +import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.html.boot.spi.Fn; +import org.objectweb.asm.Opcodes; /** * @@ -60,6 +62,33 @@ DUMMY.prev = DUMMY; } + public static boolean isJavaScriptCapable(ClassLoader l) { + if (l instanceof JsClassLoader) { + return true; + } + if (l.getResource("META-INF/net.java.html.js.classes") != null) { + return false; + } + return true; + } + + public static boolean isAsmPresent() { + Throwable t; + try { + Class.forName(Opcodes.class.getName()); + return true; + } catch (LinkageError ex) { + t = ex; + } catch (ClassNotFoundException ex) { + t = ex; + } + LOG.log(Level.SEVERE, "When using @JavaScriptBody methods, one needs to either:"); + LOG.log(Level.SEVERE, " - include asm-5.0.jar on runtime classpath"); + LOG.log(Level.SEVERE, " - post process classes, see http://bits.netbeans.org/html+java/dev/net/java/html/js/package-summary.html#post-process"); + LOG.log(Level.SEVERE, "Cannot initialize asm-5.0.jar!", t); + return false; + } + private Object prev; private final Fn.Presenter current; private FnContext(Fn.Presenter prevP, Fn.Presenter newP) { diff -r 3299d5335b8f -r af690d50d7d6 boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java --- a/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java Thu Nov 20 14:59:04 2014 +0100 +++ b/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java Sat Nov 29 22:25:40 2014 +0100 @@ -108,16 +108,6 @@ return bytecode; } - public static boolean isJavaScriptCapable(ClassLoader l) { - if (l instanceof JsClassLoader) { - return true; - } - if (l.getResource("META-INF/net.java.html.js.classes") != null) { - return false; - } - return true; - } - public static boolean isValid(Fn fn) { return fn != null && fn.isValid(); } diff -r 3299d5335b8f -r af690d50d7d6 pom.xml --- a/pom.xml Thu Nov 20 14:59:04 2014 +0100 +++ b/pom.xml Sat Nov 29 22:25:40 2014 +0100 @@ -34,6 +34,7 @@ ko-osgi-test equinox-agentclass-hook boot-script + boot-agent-test @@ -245,7 +246,7 @@ org.ow2.asm asm - 4.1 + 5.0 org.netbeans.api