1.1 --- a/boot-fx/pom.xml Sun Nov 22 21:18:35 2015 +0100
1.2 +++ b/boot-fx/pom.xml Thu Nov 26 20:59:51 2015 +0100
1.3 @@ -21,6 +21,12 @@
1.4 <plugin>
1.5 <groupId>org.apache.felix</groupId>
1.6 <artifactId>maven-bundle-plugin</artifactId>
1.7 + <configuration>
1.8 + <instructions>
1.9 + <Require-Capability>osgi.extender;resolution:=optional;filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
1.10 + <Provide-Capability>osgi.serviceloader;osgi.serviceloader=org.netbeans.html.boot.spi.Fn$Presenter</Provide-Capability>
1.11 + </instructions>
1.12 + </configuration>
1.13 </plugin>
1.14 <plugin>
1.15 <groupId>org.netbeans.html</groupId>
2.1 --- a/boot/pom.xml Sun Nov 22 21:18:35 2015 +0100
2.2 +++ b/boot/pom.xml Thu Nov 26 20:59:51 2015 +0100
2.3 @@ -26,6 +26,7 @@
2.4 <Agent-Class>org.netbeans.html.boot.impl.JsAgent</Agent-Class>
2.5 <Premain-Class>org.netbeans.html.boot.impl.JsAgent</Premain-Class>
2.6 <Eclipse-BuddyPolicy>dependent</Eclipse-BuddyPolicy>
2.7 + <Require-Capability>osgi.extender;resolution:=optional;filter:="(osgi.extender=osgi.serviceloader.processor)",osgi.serviceloader;filter:="(osgi.serviceloader=org.netbeans.html.boot.spi.Fn$Presenter)";cardinality:=multiple;resolution:=optional</Require-Capability>
2.8 </instructions>
2.9 </configuration>
2.10 </plugin>
3.1 --- a/context/pom.xml Sun Nov 22 21:18:35 2015 +0100
3.2 +++ b/context/pom.xml Thu Nov 26 20:59:51 2015 +0100
3.3 @@ -24,6 +24,7 @@
3.4 <configuration>
3.5 <instructions>
3.6 <Eclipse-BuddyPolicy>dependent</Eclipse-BuddyPolicy>
3.7 + <Require-Capability>osgi.extender;resolution:=optional;filter:="(osgi.extender=osgi.serviceloader.processor)",osgi.serviceloader;filter:="(osgi.serviceloader=org.netbeans.html.context.spi.Contexts$Provider)";cardinality:=multiple;resolution:=optional</Require-Capability>
3.8 </instructions>
3.9 </configuration>
3.10 </plugin>
4.1 --- a/ko-felix-test/pom.xml Sun Nov 22 21:18:35 2015 +0100
4.2 +++ b/ko-felix-test/pom.xml Thu Nov 26 20:59:51 2015 +0100
4.3 @@ -36,6 +36,7 @@
4.4 <additionalClasspathElements>
4.5 <additionalClasspathElement>${project.build.directory}/${project.build.finalName}.jar</additionalClasspathElement>
4.6 </additionalClasspathElements>
4.7 + <forkMode>always</forkMode>
4.8 </configuration>
4.9 <executions>
4.10 <execution>
4.11 @@ -125,5 +126,15 @@
4.12 <groupId>org.apache.felix</groupId>
4.13 <artifactId>org.apache.felix.framework</artifactId>
4.14 </dependency>
4.15 + <dependency>
4.16 + <groupId>org.apache.aries.spifly</groupId>
4.17 + <artifactId>org.apache.aries.spifly.dynamic.bundle</artifactId>
4.18 + <version>1.0.4</version>
4.19 + </dependency>
4.20 + <dependency>
4.21 + <groupId>org.osgi</groupId>
4.22 + <artifactId>org.osgi.service.log</artifactId>
4.23 + <version>1.3.0</version>
4.24 + </dependency>
4.25 </dependencies>
4.26 </project>
4.27 \ No newline at end of file
5.1 --- a/ko-felix-test/src/main/java/org/netbeans/html/ko/felix/test/KnockoutFelixTCKImpl.java Sun Nov 22 21:18:35 2015 +0100
5.2 +++ b/ko-felix-test/src/main/java/org/netbeans/html/ko/felix/test/KnockoutFelixTCKImpl.java Thu Nov 26 20:59:51 2015 +0100
5.3 @@ -101,18 +101,20 @@
5.4 return testClasses();
5.5 }
5.6
5.7 - public static void start(URI server) throws Exception {
5.8 + public static void start(String callBackClass, URI server, final boolean useAllClassloader) throws Exception {
5.9 final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(KnockoutFelixTCKImpl.class).
5.10 loadPage(server.toString()).
5.11 - invoke("initialized");
5.12 + invoke("initialized", callBackClass);
5.13
5.14 Executors.newSingleThreadExecutor().submit(new Runnable() {
5.15 @Override
5.16 public void run() {
5.17 try {
5.18 Bundle[] arr = FrameworkUtil.getBundle(BrowserBuilder.class).getBundleContext().getBundles();
5.19 - final ClassLoader osgiClassLoader = new AllBundlesLoader(arr);
5.20 - bb.classloader(osgiClassLoader);
5.21 + if (useAllClassloader) {
5.22 + final ClassLoader osgiClassLoader = new AllBundlesLoader(arr);
5.23 + bb.classloader(osgiClassLoader);
5.24 + }
5.25 bb.showAndWait();
5.26 } catch (Throwable t) {
5.27 t.printStackTrace();
5.28 @@ -121,16 +123,14 @@
5.29 });
5.30 }
5.31
5.32 - public static void initialized() throws Exception {
5.33 + public static void initialized(String... args) throws Exception {
5.34 Bundle bundle = FrameworkUtil.getBundle(KnockoutFelixTCKImpl.class);
5.35 if (bundle == null) {
5.36 throw new IllegalStateException(
5.37 "Should be loaded from a bundle. But was: " + KnockoutFelixTCKImpl.class.getClassLoader()
5.38 );
5.39 }
5.40 - Class<?> classpathClass = ClassLoader.getSystemClassLoader().loadClass(
5.41 - "org.netbeans.html.ko.felix.test.KnockoutFelixIT"
5.42 - );
5.43 + Class<?> classpathClass = ClassLoader.getSystemClassLoader().loadClass(args[0]);
5.44 Method m = classpathClass.getMethod("initialized", Class.class, Object.class);
5.45 browserContext = Fn.activePresenter();
5.46 m.invoke(null, KnockoutFelixTCKImpl.class, browserContext);
6.1 --- a/ko-felix-test/src/test/java/org/netbeans/html/ko/felix/test/KOFx.java Sun Nov 22 21:18:35 2015 +0100
6.2 +++ b/ko-felix-test/src/test/java/org/netbeans/html/ko/felix/test/KOFx.java Thu Nov 26 20:59:51 2015 +0100
6.3 @@ -60,8 +60,10 @@
6.4 private Object result;
6.5 private Object inst;
6.6 private int count;
6.7 + private final Class<?> itClass;
6.8
6.9 - KOFx(Object p, Method m) {
6.10 + KOFx(Class<?> itClass, Object p, Method m) {
6.11 + this.itClass = itClass;
6.12 this.p = p;
6.13 this.m = m;
6.14 }
6.15 @@ -90,7 +92,7 @@
6.16 boolean notify = true;
6.17 Closeable a = null;
6.18 try {
6.19 - a = KnockoutFelixIT.activateInOSGi(p);
6.20 + a = (Closeable) itClass.getMethod("activateInOSGi", Object.class).invoke(null, p);
6.21 if (inst == null) {
6.22 inst = m.getDeclaringClass().newInstance();
6.23 }
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/ko-felix-test/src/test/java/org/netbeans/html/ko/felix/test/KnockoutFelixAriesIT.java Thu Nov 26 20:59:51 2015 +0100
7.3 @@ -0,0 +1,258 @@
7.4 +/**
7.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
7.6 + *
7.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
7.8 + *
7.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7.10 + * Other names may be trademarks of their respective owners.
7.11 + *
7.12 + * The contents of this file are subject to the terms of either the GNU
7.13 + * General Public License Version 2 only ("GPL") or the Common
7.14 + * Development and Distribution License("CDDL") (collectively, the
7.15 + * "License"). You may not use this file except in compliance with the
7.16 + * License. You can obtain a copy of the License at
7.17 + * http://www.netbeans.org/cddl-gplv2.html
7.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
7.19 + * specific language governing permissions and limitations under the
7.20 + * License. When distributing the software, include this License Header
7.21 + * Notice in each file and include the License file at
7.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
7.23 + * particular file as subject to the "Classpath" exception as provided
7.24 + * by Oracle in the GPL Version 2 section of the License file that
7.25 + * accompanied this code. If applicable, add the following below the
7.26 + * License Header, with the fields enclosed by brackets [] replaced by
7.27 + * your own identifying information:
7.28 + * "Portions Copyrighted [year] [name of copyright owner]"
7.29 + *
7.30 + * Contributor(s):
7.31 + *
7.32 + * The Original Software is NetBeans. The Initial Developer of the Original
7.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
7.34 + *
7.35 + * If you wish your version of this file to be governed by only the CDDL
7.36 + * or only the GPL Version 2, indicate your decision by adding
7.37 + * "[Contributor] elects to include this software in this distribution
7.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
7.39 + * single choice of license, a recipient has the option to distribute
7.40 + * your version of this file under either the CDDL, the GPL Version 2 or
7.41 + * to extend the choice of license to its licensees as provided above.
7.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
7.43 + * Version 2 license, then the option applies only if the new code is
7.44 + * made subject to such option by the copyright holder.
7.45 + */
7.46 +package org.netbeans.html.ko.felix.test;
7.47 +
7.48 +import java.io.Closeable;
7.49 +import java.io.File;
7.50 +import java.io.IOException;
7.51 +import java.lang.annotation.Annotation;
7.52 +import java.lang.reflect.Method;
7.53 +import java.net.URI;
7.54 +import java.util.ArrayList;
7.55 +import java.util.HashMap;
7.56 +import java.util.List;
7.57 +import java.util.Map;
7.58 +import java.util.ServiceLoader;
7.59 +import java.util.concurrent.Callable;
7.60 +import java.util.jar.JarFile;
7.61 +import java.util.logging.Level;
7.62 +import java.util.logging.Logger;
7.63 +import org.netbeans.html.boot.spi.Fn;
7.64 +import org.netbeans.html.json.tck.KOTest;
7.65 +import org.netbeans.html.json.tck.KnockoutTCK;
7.66 +import org.osgi.framework.Bundle;
7.67 +import org.osgi.framework.BundleException;
7.68 +import org.osgi.framework.Constants;
7.69 +import org.osgi.framework.launch.Framework;
7.70 +import org.osgi.framework.launch.FrameworkFactory;
7.71 +import static org.testng.Assert.assertNotNull;
7.72 +import static org.testng.Assert.assertTrue;
7.73 +import static org.testng.Assert.fail;
7.74 +import org.testng.annotations.AfterClass;
7.75 +import org.testng.annotations.Factory;
7.76 +
7.77 +public class KnockoutFelixAriesIT {
7.78 + private static final Logger LOG = Logger.getLogger(KnockoutFelixAriesIT.class.getName());
7.79 + private static Framework framework;
7.80 + private static File dir;
7.81 + static Framework framework() throws Exception {
7.82 + if (framework != null) {
7.83 + return framework;
7.84 + }
7.85 + for (FrameworkFactory ff : ServiceLoader.load(FrameworkFactory.class)) {
7.86 +
7.87 + String basedir = System.getProperty("basedir");
7.88 + assertNotNull("basedir preperty provided", basedir);
7.89 + File target = new File(basedir, "target");
7.90 + dir = new File(target, "osgi-aries");
7.91 + dir.mkdirs();
7.92 +
7.93 + Map<String,String> config = new HashMap<String, String>();
7.94 + config.put(Constants.FRAMEWORK_STORAGE, dir.getPath());
7.95 + config.put(Constants.FRAMEWORK_STORAGE_CLEAN, "true");
7.96 + config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "sun.misc,"
7.97 + + "javafx.application,"
7.98 + + "javafx.beans,"
7.99 + + "javafx.beans.property,"
7.100 + + "javafx.beans.value,"
7.101 + + "javafx.collections,"
7.102 + + "javafx.concurrent,"
7.103 + + "javafx.event,"
7.104 + + "javafx.geometry,"
7.105 + + "javafx.scene,"
7.106 + + "javafx.scene.control,"
7.107 + + "javafx.scene.image,"
7.108 + + "javafx.scene.layout,"
7.109 + + "javafx.scene.text,"
7.110 + + "javafx.scene.web,"
7.111 + + "javafx.stage,"
7.112 + + "javafx.util,"
7.113 + + "netscape.javascript"
7.114 + );
7.115 + framework = ff.newFramework(config);
7.116 + framework.init();
7.117 + loadClassPathBundles(framework);
7.118 + framework.start();
7.119 + boolean ok = false;
7.120 + for (Bundle b : framework.getBundleContext().getBundles()) {
7.121 + try {
7.122 + if (!b.getSymbolicName().equals("org.apache.aries.spifly.dynamic.bundle")) {
7.123 + continue;
7.124 + }
7.125 + b.start();
7.126 + ok = true;
7.127 + LOG.log(Level.INFO, "Started {0}", b.getSymbolicName());
7.128 + } catch (BundleException ex) {
7.129 + LOG.log(Level.WARNING, "Cannot start bundle " + b.getSymbolicName(), ex);
7.130 + }
7.131 + }
7.132 + assertTrue(ok, "Aries installed");
7.133 + for (Bundle b : framework.getBundleContext().getBundles()) {
7.134 + try {
7.135 + if (b.getSymbolicName().contains("felix.framework")) {
7.136 + continue;
7.137 + }
7.138 + if (b.getSymbolicName().contains("glassfish.grizzly")) {
7.139 + continue;
7.140 + }
7.141 + b.start();
7.142 + LOG.log(Level.INFO, "Started {0}", b.getSymbolicName());
7.143 + } catch (BundleException ex) {
7.144 + LOG.log(Level.WARNING, "Cannot start bundle " + b.getSymbolicName(), ex);
7.145 + }
7.146 + }
7.147 + return framework;
7.148 + }
7.149 + fail("No OSGi framework in the path");
7.150 + return null;
7.151 + }
7.152 +
7.153 + @AfterClass public static void cleanUp() throws Exception {
7.154 + if (framework != null) framework.stop();
7.155 + clearUpDir(dir);
7.156 + }
7.157 + private static void clearUpDir(File dir) {
7.158 + if (dir.isDirectory()) {
7.159 + for (File f : dir.listFiles()) {
7.160 + clearUpDir(f);
7.161 + }
7.162 + }
7.163 + dir.delete();
7.164 + }
7.165 +
7.166 +
7.167 +
7.168 + private static void loadClassPathBundles(Framework f) throws IOException, BundleException {
7.169 + for (String jar : System.getProperty("java.class.path").split(File.pathSeparator)) {
7.170 + File file = new File(jar);
7.171 + if (!file.isFile()) {
7.172 + LOG.info("Not loading " + file);
7.173 + continue;
7.174 + }
7.175 + JarFile jf = new JarFile(file);
7.176 + final String name = jf.getManifest().getMainAttributes().getValue("Bundle-SymbolicName");
7.177 + jf.close();
7.178 + if (name != null) {
7.179 + if (name.contains("org.eclipse.osgi")) {
7.180 + throw new IllegalStateException("Found " + name + " !");
7.181 + }
7.182 + if (name.contains("felix.framework")) {
7.183 + continue;
7.184 + }
7.185 + if (name.contains("testng")) {
7.186 + continue;
7.187 + }
7.188 + final String path = "reference:" + file.toURI().toString();
7.189 + try {
7.190 + Bundle b = f.getBundleContext().installBundle(path);
7.191 + } catch (BundleException ex) {
7.192 + LOG.log(Level.WARNING, "Cannot install " + file, ex);
7.193 + }
7.194 + }
7.195 + }
7.196 + }
7.197 +
7.198 + private static Class<?> loadOSGiClass(Class<?> c) throws Exception {
7.199 + return KnockoutFelixTCKImpl.loadOSGiClass(c.getName(), KnockoutFelixAriesIT.framework().getBundleContext());
7.200 + }
7.201 +
7.202 + private static Class<?> browserClass;
7.203 + private static Object browserContext;
7.204 +
7.205 + @Factory public static Object[] compatibilityTests() throws Exception {
7.206 + Class<?> tck = loadOSGiClass(KnockoutTCK.class);
7.207 + Class<?> peer = loadOSGiClass(KnockoutFelixTCKImpl.class);
7.208 + // initialize the TCK
7.209 + Callable<Class[]> inst = (Callable<Class[]>) peer.newInstance();
7.210 +
7.211 + Class[] arr = inst.call();
7.212 + for (int i = 0; i < arr.length; i++) {
7.213 + if (arr[i].getClassLoader() == ClassLoader.getSystemClassLoader()) {
7.214 + fail("Should be an OSGi class: " + arr[i]);
7.215 + }
7.216 + }
7.217 +
7.218 + URI uri = DynamicHTTP.initServer();
7.219 +
7.220 + Method start = peer.getMethod("start", String.class, URI.class, boolean.class);
7.221 + start.invoke(null, KnockoutFelixAriesIT.class.getName(), uri, false);
7.222 +
7.223 + ClassLoader l = getClassLoader();
7.224 + List<Object> res = new ArrayList<Object>();
7.225 + for (int i = 0; i < arr.length; i++) {
7.226 + seekKOTests(arr[i], res);
7.227 + }
7.228 + return res.toArray();
7.229 + }
7.230 +
7.231 + private static void seekKOTests(Class<?> c, List<Object> res) throws SecurityException, ClassNotFoundException {
7.232 + Class<? extends Annotation> koTest =
7.233 + c.getClassLoader().loadClass(KOTest.class.getName()).
7.234 + asSubclass(Annotation.class);
7.235 + for (Method m : c.getMethods()) {
7.236 + if (m.getAnnotation(koTest) != null) {
7.237 + res.add(new KOFx(KnockoutFelixAriesIT.class, browserContext, m));
7.238 + }
7.239 + }
7.240 + }
7.241 +
7.242 + static synchronized ClassLoader getClassLoader() throws InterruptedException {
7.243 + while (browserClass == null) {
7.244 + KnockoutFelixAriesIT.class.wait();
7.245 + }
7.246 + return browserClass.getClassLoader();
7.247 + }
7.248 +
7.249 + public static synchronized void initialized(Class<?> browserCls, Object presenter) throws Exception {
7.250 + browserClass = browserCls;
7.251 + browserContext = presenter;
7.252 + KnockoutFelixAriesIT.class.notifyAll();
7.253 + }
7.254 +
7.255 + public static Closeable activateInOSGi(Object presenter) throws Exception {
7.256 + Class<?> presenterClass = loadOSGiClass(Fn.Presenter.class);
7.257 + Class<?> fnClass = loadOSGiClass(Fn.class);
7.258 + Method m = fnClass.getMethod("activate", presenterClass);
7.259 + return (Closeable) m.invoke(null, presenter);
7.260 + }
7.261 +}
8.1 --- a/ko-felix-test/src/test/java/org/netbeans/html/ko/felix/test/KnockoutFelixIT.java Sun Nov 22 21:18:35 2015 +0100
8.2 +++ b/ko-felix-test/src/test/java/org/netbeans/html/ko/felix/test/KnockoutFelixIT.java Thu Nov 26 20:59:51 2015 +0100
8.3 @@ -42,7 +42,6 @@
8.4 */
8.5 package org.netbeans.html.ko.felix.test;
8.6
8.7 -import org.netbeans.html.ko.felix.test.KnockoutFelixTCKImpl;
8.8 import java.io.Closeable;
8.9 import java.io.File;
8.10 import java.io.IOException;
8.11 @@ -172,6 +171,9 @@
8.12 if (name.contains("testng")) {
8.13 continue;
8.14 }
8.15 + if (name.equals("org.apache.aries.spifly.dynamic.bundle")) {
8.16 + continue;
8.17 + }
8.18 final String path = "reference:" + file.toURI().toString();
8.19 try {
8.20 Bundle b = f.getBundleContext().installBundle(path);
8.21 @@ -204,10 +206,10 @@
8.22
8.23 URI uri = DynamicHTTP.initServer();
8.24
8.25 - Method start = peer.getMethod("start", URI.class);
8.26 - start.invoke(null, uri);
8.27 + Method start = peer.getMethod("start", String.class, URI.class, boolean.class);
8.28 + start.invoke(null, KnockoutFelixIT.class.getName(), uri, true);
8.29
8.30 - ClassLoader l = getClassLoader();
8.31 + ClassLoader l = getClassLoader(null);
8.32 List<Object> res = new ArrayList<Object>();
8.33 for (int i = 0; i < arr.length; i++) {
8.34 seekKOTests(arr[i], res);
8.35 @@ -221,15 +223,18 @@
8.36 asSubclass(Annotation.class);
8.37 for (Method m : c.getMethods()) {
8.38 if (m.getAnnotation(koTest) != null) {
8.39 - res.add(new KOFx(browserContext, m));
8.40 + res.add(new KOFx(KnockoutFelixIT.class, browserContext, m));
8.41 }
8.42 }
8.43 }
8.44
8.45 - static synchronized ClassLoader getClassLoader() throws InterruptedException {
8.46 + static synchronized ClassLoader getClassLoader(Object[] presenter) throws InterruptedException {
8.47 while (browserClass == null) {
8.48 KnockoutFelixIT.class.wait();
8.49 }
8.50 + if (presenter != null) {
8.51 + presenter[0] = browserContext;
8.52 + }
8.53 return browserClass.getClassLoader();
8.54 }
8.55
8.56 @@ -239,7 +244,7 @@
8.57 KnockoutFelixIT.class.notifyAll();
8.58 }
8.59
8.60 - static Closeable activateInOSGi(Object presenter) throws Exception {
8.61 + public static Closeable activateInOSGi(Object presenter) throws Exception {
8.62 Class<?> presenterClass = loadOSGiClass(Fn.Presenter.class);
8.63 Class<?> fnClass = loadOSGiClass(Fn.class);
8.64 Method m = fnClass.getMethod("activate", presenterClass);
9.1 --- a/ko4j/pom.xml Sun Nov 22 21:18:35 2015 +0100
9.2 +++ b/ko4j/pom.xml Thu Nov 26 20:59:51 2015 +0100
9.3 @@ -22,6 +22,12 @@
9.4 <plugin>
9.5 <groupId>org.apache.felix</groupId>
9.6 <artifactId>maven-bundle-plugin</artifactId>
9.7 + <configuration>
9.8 + <instructions>
9.9 + <Require-Capability>osgi.extender;resolution:=optional;filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
9.10 + <Provide-Capability>osgi.serviceloader;osgi.serviceloader=org.netbeans.html.context.spi.Contexts$Provider</Provide-Capability>
9.11 + </instructions>
9.12 + </configuration>
9.13 </plugin>
9.14 <plugin>
9.15 <groupId>org.netbeans.html</groupId>
10.1 --- a/src/main/javadoc/overview.html Sun Nov 22 21:18:35 2015 +0100
10.2 +++ b/src/main/javadoc/overview.html Thu Nov 26 20:59:51 2015 +0100
10.3 @@ -115,6 +115,8 @@
10.4 </configuration>
10.5 </plugin>
10.6 </pre>
10.7 + OSGi headers are now <a href="https://netbeans.org/bugzilla/show_bug.cgi?id=256696">
10.8 + enterprise OSGi ready</a>.
10.9
10.10 <h3>What's Been Improved in Version 1.2.3?</h3>
10.11