Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2019-07-03 13:06:44 +0000
committerThomas Watson2019-10-30 16:49:50 +0000
commitfb6258ed257d3b1263c7c7e340b44a5102b52b79 (patch)
tree5f8bd95086baa02d6de1d512ec15c442bf555b67
parent8706b4088137e0949adeb3fbd527167a9aea266f (diff)
downloadrt.equinox.framework-fb6258ed257d3b1263c7c7e340b44a5102b52b79.tar.gz
rt.equinox.framework-fb6258ed257d3b1263c7c7e340b44a5102b52b79.tar.xz
rt.equinox.framework-fb6258ed257d3b1263c7c7e340b44a5102b52b79.zip
Bug 552573 - [osgi r8] Implement OSGi Connect
Initial OSGi Connect implementation based on early proposal of the OSGi Connect API. This is likely to change over the course of the specification development. Change-Id: I92f6a3312dfc64d6b56d103c889aad3e00a56c7e Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
-rw-r--r--bundles/org.eclipse.osgi.tests/.classpath770
-rw-r--r--bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs38
-rw-r--r--bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper1
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper1
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java10
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java5
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java1
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java727
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator.java31
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator1.java18
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator2.java18
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator3.java18
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/1.txt1
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/2.txt1
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/3.txt1
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java3
-rw-r--r--bundles/org.eclipse.osgi/.settings/.api_filters58
-rw-r--r--bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs15
-rw-r--r--bundles/org.eclipse.osgi/META-INF/MANIFEST.MF9
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFile.java129
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFileFactory.java103
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java249
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/DelegatingConnectClassLoader.java67
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java26
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/FrameworkUtilHelper.java36
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java3
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java27
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java7
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java2
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java2
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java2
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java70
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java2
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java2
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectContent.java184
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectFactory.java89
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectModule.java42
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java41
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/package-info.java34
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java31
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java2
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java16
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java6
-rw-r--r--bundles/org.eclipse.osgi/pom.xml2
45 files changed, 2664 insertions, 238 deletions
diff --git a/bundles/org.eclipse.osgi.tests/.classpath b/bundles/org.eclipse.osgi.tests/.classpath
index 2650588cc..da0075e48 100644
--- a/bundles/org.eclipse.osgi.tests/.classpath
+++ b/bundles/org.eclipse.osgi.tests/.classpath
@@ -1,134 +1,646 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="src" output="bundle_tests/test" path="bundles_src/test"/>
- <classpathentry kind="src" output="bundle_tests/test2" path="bundles_src/test2"/>
- <classpathentry kind="src" output="bundle_tests/chain.test" path="bundles_src/chain.test"/>
- <classpathentry kind="src" output="bundle_tests/chain.test.a" path="bundles_src/chain.test.a"/>
- <classpathentry kind="src" output="bundle_tests/chain.test.b" path="bundles_src/chain.test.b"/>
- <classpathentry kind="src" output="bundle_tests/chain.test.c" path="bundles_src/chain.test.c"/>
- <classpathentry kind="src" output="bundle_tests/chain.test.d" path="bundles_src/chain.test.d"/>
- <classpathentry kind="src" output="bundle_tests/circularity.test" path="bundles_src/circularity.test"/>
- <classpathentry kind="src" output="bundle_tests/circularity.test.a" path="bundles_src/circularity.test.a"/>
- <classpathentry kind="src" output="bundle_tests/fragment.test.attach.host.a" path="bundles_src/fragment.test.attach.host.a"/>
- <classpathentry kind="src" output="bundle_tests/fragment.test.attach.host.a.v2" path="bundles_src/fragment.test.attach.host.a.v2"/>
- <classpathentry kind="src" output="bundle_tests/fragment.test.attach.host.a.require" path="bundles_src/fragment.test.attach.host.a.require"/>
- <classpathentry kind="src" output="bundle_tests/fragment.test.attach.frag.a" path="bundles_src/fragment.test.attach.frag.a"/>
- <classpathentry kind="src" output="bundle_tests/fragment.test.attach.frag.b" path="bundles_src/fragment.test.attach.frag.b"/>
- <classpathentry kind="src" output="bundle_tests/legacy.lazystart" path="bundles_src/legacy.lazystart"/>
- <classpathentry kind="src" output="bundle_tests/legacy.lazystart.a" path="bundles_src/legacy.lazystart.a"/>
- <classpathentry kind="src" output="bundle_tests/legacy.lazystart.b" path="bundles_src/legacy.lazystart.b"/>
- <classpathentry kind="src" output="bundle_tests/legacy.lazystart.c" path="bundles_src/legacy.lazystart.c"/>
- <classpathentry kind="src" output="bundle_tests/osgi.lazystart" path="bundles_src/osgi.lazystart"/>
- <classpathentry kind="src" output="bundle_tests/osgi.lazystart.a" path="bundles_src/osgi.lazystart.a"/>
- <classpathentry kind="src" output="bundle_tests/osgi.lazystart.b" path="bundles_src/osgi.lazystart.b"/>
- <classpathentry kind="src" output="bundle_tests/osgi.lazystart.c" path="bundles_src/osgi.lazystart.c"/>
- <classpathentry kind="src" output="bundle_tests/osgi.lazystart.d" path="bundles_src/osgi.lazystart.d"/>
- <classpathentry kind="src" output="bundle_tests/osgi.lazystart.e" path="bundles_src/osgi.lazystart.e"/>
- <classpathentry kind="src" output="bundle_tests/thread.locktest" path="bundles_src/thread.locktest"/>
- <classpathentry kind="src" output="bundle_tests/buddy.registered.a" path="bundles_src/buddy.registered.a"/>
- <classpathentry kind="src" output="bundle_tests/buddy.registered.a.test1" path="bundles_src/buddy.registered.a.test1"/>
- <classpathentry kind="src" output="bundle_tests/buddy.registered.a.test2" path="bundles_src/buddy.registered.a.test2"/>
- <classpathentry kind="src" output="bundle_tests/buddy.dependent.a" path="bundles_src/buddy.dependent.a"/>
- <classpathentry kind="src" output="bundle_tests/buddy.dependent.a.test1" path="bundles_src/buddy.dependent.a.test1"/>
- <classpathentry kind="src" output="bundle_tests/buddy.dependent.a.test2" path="bundles_src/buddy.dependent.a.test2"/>
- <classpathentry kind="src" output="bundle_tests/buddy.invalid.a" path="bundles_src/buddy.invalid.a"/>
- <classpathentry kind="src" output="bundle_tests/nativetest.a1" path="bundles_src/nativetest.a1"/>
- <classpathentry kind="src" output="bundle_tests/nativetest.a2" path="bundles_src/nativetest.a2"/>
- <classpathentry kind="src" output="bundle_tests/nativetest.b1" path="bundles_src/nativetest.b1"/>
- <classpathentry kind="src" output="bundle_tests/nativetest.b2" path="bundles_src/nativetest.b2"/>
- <classpathentry kind="src" output="bundle_tests/nativetest.c" path="bundles_src/nativetest.c"/>
- <classpathentry kind="src" output="bundle_tests/nativetest.d" path="bundles_src/nativetest.d"/>
- <classpathentry kind="src" output="bundle_tests/nativetest.e" path="bundles_src/nativetest.e"/>
- <classpathentry kind="src" output="bundle_tests/nativetest.f" path="bundles_src/nativetest.f"/>
- <classpathentry kind="src" output="bundle_tests/host.multiple.exports" path="bundles_src/host.multiple.exports"/>
- <classpathentry kind="src" output="bundle_tests/frag.multiple.exports" path="bundles_src/frag.multiple.exports"/>
- <classpathentry kind="src" output="bundle_tests/client1.multiple.exports" path="bundles_src/client1.multiple.exports"/>
- <classpathentry kind="src" output="bundle_tests/client2.multiple.exports" path="bundles_src/client2.multiple.exports"/>
- <classpathentry kind="src" output="bundle_tests/xfriends.test1" path="bundles_src/xfriends.test1"/>
- <classpathentry kind="src" output="bundle_tests/xfriends.test2" path="bundles_src/xfriends.test2"/>
- <classpathentry kind="src" output="bundle_tests/xfriends.test3" path="bundles_src/xfriends.test3"/>
- <classpathentry kind="src" output="bundle_tests/ext.framework.a" path="bundles_src/ext.framework.a"/>
- <classpathentry kind="src" output="bundle_tests/ext.framework.a.importer" path="bundles_src/ext.framework.a.importer"/>
- <classpathentry kind="src" output="bundle_tests/ext.framework.a.requires" path="bundles_src/ext.framework.a.requires"/>
- <classpathentry kind="src" output="bundle_tests/ext.framework.b" path="bundles_src/ext.framework.b"/>
- <classpathentry kind="src" output="bundle_tests/ext.extclasspath.a" path="bundles_src/ext.extclasspath.a"/>
- <classpathentry kind="src" output="bundle_tests/ext.extclasspath.a.importer" path="bundles_src/ext.extclasspath.a.importer"/>
- <classpathentry kind="src" output="bundle_tests/exporter.importer1" path="bundles_src/exporter.importer1"/>
- <classpathentry kind="src" output="bundle_tests/exporter.importer2" path="bundles_src/exporter.importer2"/>
- <classpathentry kind="src" output="bundle_tests/exporter.importer3" path="bundles_src/exporter.importer3"/>
- <classpathentry kind="src" output="bundle_tests/exporter.importer4" path="bundles_src/exporter.importer4"/>
- <classpathentry kind="src" output="bundle_tests/test.bug235958.x" path="bundles_src/test.bug235958.x"/>
- <classpathentry kind="src" output="bundle_tests/test.bug235958.y" path="bundles_src/test.bug235958.y"/>
- <classpathentry kind="src" output="bundle_tests/test.fragment1" path="bundles_src/test.fragment1"/>
- <classpathentry kind="src" output="bundle_tests/test.fragment2" path="bundles_src/test.fragment2"/>
- <classpathentry kind="src" output="bundle_tests/test.fragment3" path="bundles_src/test.fragment3"/>
- <classpathentry kind="src" output="bundle_tests/test.fragment4" path="bundles_src/test.fragment4"/>
- <classpathentry kind="src" output="bundle_tests/test.fragment5" path="bundles_src/test.fragment5"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.a" path="bundles_src/substitutes.a"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.a.frag" path="bundles_src/substitutes.a.frag"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.b" path="bundles_src/substitutes.b"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.b.frag" path="bundles_src/substitutes.b.frag"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.c" path="bundles_src/substitutes.c"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.d" path="bundles_src/substitutes.d"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.e" path="bundles_src/substitutes.e"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.f" path="bundles_src/substitutes.f"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.g" path="bundles_src/substitutes.g"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.h" path="bundles_src/substitutes.h"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.i" path="bundles_src/substitutes.i"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.j" path="bundles_src/substitutes.j"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.k" path="bundles_src/substitutes.k"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.l" path="bundles_src/substitutes.l"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.m" path="bundles_src/substitutes.m"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.n" path="bundles_src/substitutes.n"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.p" path="bundles_src/substitutes.p"/>
- <classpathentry kind="src" output="bundle_tests/substitutes.q" path="bundles_src/substitutes.q"/>
- <classpathentry kind="src" output="bundle_tests/activator.error1" path="bundles_src/activator.error1"/>
- <classpathentry kind="src" output="bundle_tests/activator.error2" path="bundles_src/activator.error2"/>
- <classpathentry kind="src" output="bundle_tests/activator.error3" path="bundles_src/activator.error3"/>
- <classpathentry kind="src" output="bundle_tests/activator.error4" path="bundles_src/activator.error4"/>
- <classpathentry kind="src" output="bundle_tests/security.a" path="bundles_src/security.a"/>
- <classpathentry kind="src" output="bundle_tests/security.a.frag.a" path="bundles_src/security.a.frag.a"/>
- <classpathentry kind="src" output="bundle_tests/security.b" path="bundles_src/security.b"/>
- <classpathentry kind="src" output="bundle_tests/test.filter.a" path="bundles_src/test.filter.a"/>
- <classpathentry kind="src" output="bundle_tests/test.link.a" path="bundles_src/test.link.a"/>
- <classpathentry kind="src" output="bundle_tests/test.link.a.client" path="bundles_src/test.link.a.client"/>
- <classpathentry kind="src" output="bundle_tests/test.bug259903.a" path="bundles_src/test.bug259903.a"/>
- <classpathentry kind="src" output="bundle_tests/test.bug259903.a.update" path="bundles_src/test.bug259903.a.update"/>
- <classpathentry kind="src" output="bundle_tests/test.bug259903.b" path="bundles_src/test.bug259903.b"/>
- <classpathentry kind="src" output="bundle_tests/test.bug259903.c" path="bundles_src/test.bug259903.c"/>
- <classpathentry kind="src" output="bundle_tests/test.tccl" path="bundles_src/test.tccl"/>
- <classpathentry kind="src" output="bundle_tests/test.manifestpackage" path="bundles_src/test.manifestpackage"/>
- <classpathentry kind="src" output="bundle_tests/test.bug286307" path="bundles_src/test.bug286307"/>
- <classpathentry kind="src" output="bundle_tests/test.bug287636.a1" path="bundles_src/test.bug287636.a1"/>
- <classpathentry kind="src" output="bundle_tests/test.bug287636.a2" path="bundles_src/test.bug287636.a2"/>
- <classpathentry kind="src" output="bundle_tests/test.bug287636.b" path="bundles_src/test.bug287636.b"/>
- <classpathentry kind="src" output="bundle_tests/test.bug287750" path="bundles_src/test.bug287750"/>
- <classpathentry kind="src" output="bundle_tests/test.bug306181a" path="bundles_src/test.bug306181a"/>
- <classpathentry kind="src" output="bundle_tests/test.bug306181b" path="bundles_src/test.bug306181b"/>
- <classpathentry kind="src" output="bundle_tests/test.logging.a" path="bundles_src/test.logging.a"/>
- <classpathentry kind="src" output="bundle_tests/geturl" path="bundles_src/geturl"/>
- <classpathentry kind="src" output="bundle_tests/test.bug375784" path="bundles_src/test.bug375784"/>
- <classpathentry kind="src" output="bundle_tests/storage.hooks.a" path="bundles_src/storage.hooks.a"/>
- <classpathentry kind="src" output="bundle_tests/test.bug412228" path="bundles_src/test.bug412228"/>
- <classpathentry kind="src" output="bundle_tests/test.uninstall.start1" path="bundles_src/test.uninstall.start1"/>
- <classpathentry kind="src" output="bundle_tests/test.uninstall.start2" path="bundles_src/test.uninstall.start2"/>
- <classpathentry kind="src" output="bundle_tests/ext.framework.osgiee.b.jar" path="bundles_src/ext.framework.osgiee.b"/>
- <classpathentry kind="src" output="bundle_tests/classloader.hooks.a" path="bundles_src/classloader.hooks.a"/>
- <classpathentry kind="src" output="bundle_tests/test.bug438904.host" path="bundles_src/test.bug438904.host"/>
- <classpathentry kind="src" output="bundle_tests/test.bug438904.frag" path="bundles_src/test.bug438904.frag"/>
- <classpathentry kind="src" output="bundle_tests/test.bug438904.global" path="bundles_src/test.bug438904.global"/>
- <classpathentry kind="src" output="bundle_tests/test.system.nls" path="bundles_src/test.system.nls"/>
- <classpathentry kind="src" output="bundle_tests/test.bug449484" path="bundles_src/test.bug449484"/>
- <classpathentry kind="src" output="bundle_tests/wrapper.hooks.a" path="bundles_src/wrapper.hooks.a"/>
- <classpathentry kind="src" output="bundle_tests/test.protocol.handler" path="bundles_src/test.protocol.handler"/>
- <classpathentry kind="src" output="bundle_tests/test.protocol.handler.user" path="bundles_src/test.protocol.handler.user"/>
- <classpathentry kind="src" output="bundle_tests/test.bug471551" path="bundles_src/test.bug471551"/>
- <classpathentry kind="src" output="bundle_tests/test.dynamicimport" path="bundles_src/test.dynamicimport"/>
- <classpathentry kind="src" output="bundle_tests/test.bug490902.a" path="bundles_src/test.bug490902.a"/>
- <classpathentry kind="src" output="bundle_tests/test.bug490902.b" path="bundles_src/test.bug490902.b"/>
- <classpathentry kind="src" output="bundle_tests/mrBundleInputBase" path="bundles_src/mrBundleInputBase"/>
+ <classpathentry kind="src" path="src">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test" path="bundles_src/test">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test2" path="bundles_src/test2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/chain.test" path="bundles_src/chain.test">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/chain.test.a" path="bundles_src/chain.test.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/chain.test.b" path="bundles_src/chain.test.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/chain.test.c" path="bundles_src/chain.test.c">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/chain.test.d" path="bundles_src/chain.test.d">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/circularity.test" path="bundles_src/circularity.test">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/circularity.test.a" path="bundles_src/circularity.test.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/fragment.test.attach.host.a" path="bundles_src/fragment.test.attach.host.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/fragment.test.attach.host.a.v2" path="bundles_src/fragment.test.attach.host.a.v2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/fragment.test.attach.host.a.require" path="bundles_src/fragment.test.attach.host.a.require">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/fragment.test.attach.frag.a" path="bundles_src/fragment.test.attach.frag.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/fragment.test.attach.frag.b" path="bundles_src/fragment.test.attach.frag.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/legacy.lazystart" path="bundles_src/legacy.lazystart">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/legacy.lazystart.a" path="bundles_src/legacy.lazystart.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/legacy.lazystart.b" path="bundles_src/legacy.lazystart.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/legacy.lazystart.c" path="bundles_src/legacy.lazystart.c">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/osgi.lazystart" path="bundles_src/osgi.lazystart">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/osgi.lazystart.a" path="bundles_src/osgi.lazystart.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/osgi.lazystart.b" path="bundles_src/osgi.lazystart.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/osgi.lazystart.c" path="bundles_src/osgi.lazystart.c">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/osgi.lazystart.d" path="bundles_src/osgi.lazystart.d">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/osgi.lazystart.e" path="bundles_src/osgi.lazystart.e">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/thread.locktest" path="bundles_src/thread.locktest">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/buddy.registered.a" path="bundles_src/buddy.registered.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/buddy.registered.a.test1" path="bundles_src/buddy.registered.a.test1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/buddy.registered.a.test2" path="bundles_src/buddy.registered.a.test2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/buddy.dependent.a" path="bundles_src/buddy.dependent.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/buddy.dependent.a.test1" path="bundles_src/buddy.dependent.a.test1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/buddy.dependent.a.test2" path="bundles_src/buddy.dependent.a.test2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/buddy.invalid.a" path="bundles_src/buddy.invalid.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/nativetest.a1" path="bundles_src/nativetest.a1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/nativetest.a2" path="bundles_src/nativetest.a2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/nativetest.b1" path="bundles_src/nativetest.b1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/nativetest.b2" path="bundles_src/nativetest.b2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/nativetest.c" path="bundles_src/nativetest.c">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/nativetest.d" path="bundles_src/nativetest.d">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/nativetest.e" path="bundles_src/nativetest.e">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/nativetest.f" path="bundles_src/nativetest.f">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/host.multiple.exports" path="bundles_src/host.multiple.exports">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/frag.multiple.exports" path="bundles_src/frag.multiple.exports">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/client1.multiple.exports" path="bundles_src/client1.multiple.exports">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/client2.multiple.exports" path="bundles_src/client2.multiple.exports">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/xfriends.test1" path="bundles_src/xfriends.test1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/xfriends.test2" path="bundles_src/xfriends.test2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/xfriends.test3" path="bundles_src/xfriends.test3">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/ext.framework.a" path="bundles_src/ext.framework.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/ext.framework.a.importer" path="bundles_src/ext.framework.a.importer">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/ext.framework.a.requires" path="bundles_src/ext.framework.a.requires">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/ext.framework.b" path="bundles_src/ext.framework.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/ext.extclasspath.a" path="bundles_src/ext.extclasspath.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/ext.extclasspath.a.importer" path="bundles_src/ext.extclasspath.a.importer">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/exporter.importer1" path="bundles_src/exporter.importer1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/exporter.importer2" path="bundles_src/exporter.importer2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/exporter.importer3" path="bundles_src/exporter.importer3">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/exporter.importer4" path="bundles_src/exporter.importer4">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug235958.x" path="bundles_src/test.bug235958.x">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug235958.y" path="bundles_src/test.bug235958.y">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.fragment1" path="bundles_src/test.fragment1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.fragment2" path="bundles_src/test.fragment2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.fragment3" path="bundles_src/test.fragment3">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.fragment4" path="bundles_src/test.fragment4">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.fragment5" path="bundles_src/test.fragment5">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.a" path="bundles_src/substitutes.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.a.frag" path="bundles_src/substitutes.a.frag">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.b" path="bundles_src/substitutes.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.b.frag" path="bundles_src/substitutes.b.frag">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.c" path="bundles_src/substitutes.c">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.d" path="bundles_src/substitutes.d">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.e" path="bundles_src/substitutes.e">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.f" path="bundles_src/substitutes.f">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.g" path="bundles_src/substitutes.g">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.h" path="bundles_src/substitutes.h">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.i" path="bundles_src/substitutes.i">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.j" path="bundles_src/substitutes.j">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.k" path="bundles_src/substitutes.k">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.l" path="bundles_src/substitutes.l">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.m" path="bundles_src/substitutes.m">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.n" path="bundles_src/substitutes.n">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.p" path="bundles_src/substitutes.p">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/substitutes.q" path="bundles_src/substitutes.q">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/activator.error1" path="bundles_src/activator.error1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/activator.error2" path="bundles_src/activator.error2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/activator.error3" path="bundles_src/activator.error3">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/activator.error4" path="bundles_src/activator.error4">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/security.a" path="bundles_src/security.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/security.a.frag.a" path="bundles_src/security.a.frag.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/security.b" path="bundles_src/security.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.filter.a" path="bundles_src/test.filter.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.link.a" path="bundles_src/test.link.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.link.a.client" path="bundles_src/test.link.a.client">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug259903.a" path="bundles_src/test.bug259903.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug259903.a.update" path="bundles_src/test.bug259903.a.update">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug259903.b" path="bundles_src/test.bug259903.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug259903.c" path="bundles_src/test.bug259903.c">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.tccl" path="bundles_src/test.tccl">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.manifestpackage" path="bundles_src/test.manifestpackage">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug286307" path="bundles_src/test.bug286307">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug287636.a1" path="bundles_src/test.bug287636.a1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug287636.a2" path="bundles_src/test.bug287636.a2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug287636.b" path="bundles_src/test.bug287636.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug287750" path="bundles_src/test.bug287750">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug306181a" path="bundles_src/test.bug306181a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug306181b" path="bundles_src/test.bug306181b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.logging.a" path="bundles_src/test.logging.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/geturl" path="bundles_src/geturl">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug375784" path="bundles_src/test.bug375784">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/storage.hooks.a" path="bundles_src/storage.hooks.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug412228" path="bundles_src/test.bug412228">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.uninstall.start1" path="bundles_src/test.uninstall.start1">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.uninstall.start2" path="bundles_src/test.uninstall.start2">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/ext.framework.osgiee.b.jar" path="bundles_src/ext.framework.osgiee.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/classloader.hooks.a" path="bundles_src/classloader.hooks.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug438904.host" path="bundles_src/test.bug438904.host">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug438904.frag" path="bundles_src/test.bug438904.frag">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug438904.global" path="bundles_src/test.bug438904.global">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.system.nls" path="bundles_src/test.system.nls">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug449484" path="bundles_src/test.bug449484">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/wrapper.hooks.a" path="bundles_src/wrapper.hooks.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.protocol.handler" path="bundles_src/test.protocol.handler">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.protocol.handler.user" path="bundles_src/test.protocol.handler.user">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug471551" path="bundles_src/test.bug471551">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.dynamicimport" path="bundles_src/test.dynamicimport">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug490902.a" path="bundles_src/test.bug490902.a">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/test.bug490902.b" path="bundles_src/test.bug490902.b">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="bundle_tests/mrBundleInputBase" path="bundles_src/mrBundleInputBase">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs
index c69c78f2d..77c9cee27 100644
--- a/bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs
@@ -13,9 +13,10 @@ org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annota
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -31,6 +32,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
@@ -82,6 +84,7 @@ org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=igno
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
@@ -114,23 +117,28 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
-org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
@@ -206,11 +214,12 @@ org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
@@ -240,6 +249,8 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=inser
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
@@ -263,12 +274,16 @@ org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
@@ -314,6 +329,8 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do n
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
@@ -349,8 +366,11 @@ org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not inser
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
@@ -373,6 +393,10 @@ org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
org.eclipse.jdt.core.formatter.tabulation.char=tab
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
-org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
org.eclipse.jdt.core.incompatibleJDKLevel=ignore
org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
index 3eb75b52f..fb9722396 100644
--- a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
@@ -14,7 +14,7 @@ Bundle-Activator: org.eclipse.osgi.tests.OSGiTestsActivator
Import-Package: org.osgi.service.event; resolution:="optional"
Export-Package: org.eclipse.osgi.tests.bundles,
org.eclipse.osgi.tests.appadmin
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
DynamicImport-Package: ext.framework.b
Eclipse-BundleShape: dir
Automatic-Module-Name: org.eclipse.osgi.tests
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper
deleted file mode 100644
index a3365b5b5..000000000
--- a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.osgi.tests.hooks.framework.storage.a.TestHelper \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper
new file mode 100644
index 000000000..875f91cd6
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper
@@ -0,0 +1 @@
+org.eclipse.osgi.tests.hooks.framework.storage.a.TestHelper
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java
index 35b949cc3..cffc2118b 100644
--- a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java
@@ -13,14 +13,18 @@
*******************************************************************************/
package org.eclipse.osgi.tests.hooks.framework.storage.a;
-import org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper;
import org.osgi.framework.Bundle;
+import org.osgi.framework.connect.FrameworkUtilHelper;
-public class TestHelper extends FrameworkUtilHelper {
- volatile static Bundle testBundle = null;
+public class TestHelper implements FrameworkUtilHelper {
+ volatile static Bundle testBundle;
@Override
public Bundle getBundle(Class<?> classFromBundle) {
return testBundle;
}
+
+ public static void setBundle(Bundle testBundle) {
+ TestHelper.testBundle = testBundle;
+ }
}
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java
index fc9d094cb..07d28e4b4 100644
--- a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java
@@ -174,15 +174,14 @@ public class TestHookConfigurator implements HookConfigurator {
@Override
public BundleActivator createActivator() {
return new BundleActivator() {
-
@Override
public void start(BundleContext context) throws Exception {
- TestHelper.testBundle = context.getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
+ TestHelper.setBundle(context.getBundle(Constants.SYSTEM_BUNDLE_LOCATION));
}
@Override
public void stop(BundleContext context) throws Exception {
- // nothing
+ TestHelper.setBundle(null);
}
};
}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java
index 0b497d5ba..0f63632b6 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java
@@ -19,6 +19,7 @@ import junit.framework.TestSuite;
public class BundleTests {
public static Test suite() {
TestSuite suite = new TestSuite(BundleTests.class.getName());
+ suite.addTest(ConnectTests.suite());
suite.addTest(ImportJavaSEPackagesTests.suite());
suite.addTest(MultiReleaseJarTests.suite());
suite.addTest(URLHandlerTests.suite());
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java
new file mode 100644
index 000000000..56dd9df1f
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java
@@ -0,0 +1,727 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.eclipse.osgi.launch.EquinoxFactory;
+import org.eclipse.osgi.tests.OSGiTestsActivator;
+import org.eclipse.osgi.tests.bundles.classes.Activator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.connect.ConnectContent;
+import org.osgi.framework.connect.ConnectContent.ConnectEntry;
+import org.osgi.framework.connect.ConnectFactory;
+import org.osgi.framework.connect.ConnectModule;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+public class ConnectTests extends AbstractBundleTests {
+
+ public static Test suite() {
+ return new TestSuite(ConnectTests.class);
+ }
+
+ void doTestConnect(ConnectFactory connectFactory, Map<String, String> fwkConfig, Consumer<Framework> test) {
+ File config = OSGiTestsActivator.getContext().getDataFile(getName());
+ config.mkdirs();
+ fwkConfig.put(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath());
+ FrameworkFactory fwkFactory = new EquinoxFactory();
+ Framework framework = fwkFactory.newFramework(fwkConfig, connectFactory);
+ boolean passed = false;
+ try {
+ test.accept(framework);
+ passed = true;
+ } finally {
+ try {
+ framework.stop();
+ framework.waitForStop(10000);
+ } catch (Exception e) {
+ if (passed) {
+ sneakyThrow(e);
+ }
+ }
+ }
+ }
+
+ public static class TestCountingConnectFactory implements ConnectFactory {
+ private final AtomicInteger initializeCalled = new AtomicInteger();
+ private final Queue<String> getModuleCalled = new ConcurrentLinkedQueue<>();
+ private final AtomicInteger createBundleActivatorCalled = new AtomicInteger();
+ private final Map<String, ConnectModule> modules = new ConcurrentHashMap<String, ConnectModule>();
+
+ @Override
+ public void initialize(File storage, Map<String, String> config) {
+ initializeCalled.getAndIncrement();
+ }
+
+ @Override
+ public Optional<ConnectModule> getModule(String location) {
+ getModuleCalled.add(location);
+ ConnectModule m = modules.get(location);
+ if (m == ILLEGAL_STATE_EXCEPTION) {
+ throw new IllegalStateException();
+ }
+ return Optional.ofNullable(m);
+ }
+
+ @Override
+ public Optional<BundleActivator> createBundleActivator() {
+ createBundleActivatorCalled.getAndIncrement();
+ return Optional.empty();
+ }
+
+ int getInitializeCnt() {
+ return initializeCalled.get();
+ }
+
+ List<String> getModuleLocations() {
+ return new ArrayList<>(getModuleCalled);
+ }
+
+ int getCreateBundleActivatorCnt() {
+ return createBundleActivatorCalled.get();
+ }
+
+ void setModule(String location, ConnectModule module) {
+ if (module == null) {
+ modules.remove(location);
+ } else {
+ modules.put(location, module);
+ }
+ }
+ }
+
+ public static class TestConnectModule implements ConnectModule {
+ private volatile TestConnectContent content;
+
+ public TestConnectModule(TestConnectContent content) {
+ this.content = content;
+ }
+
+ @Override
+ public TestConnectContent getContent() {
+ return content;
+ }
+
+ void setContent(TestConnectContent updatedContent) {
+ this.content = updatedContent;
+ }
+ }
+
+ public static class TestConnectContent implements ConnectContent {
+ private final Map<String, String> headers;
+ private final Map<String, ConnectEntry> entries = new LinkedHashMap<>();
+ private final ClassLoader loader;
+ private final AtomicBoolean isOpen = new AtomicBoolean();
+
+ public TestConnectContent(Map<String, String> headers, ClassLoader loader) {
+ this.headers = headers;
+ this.loader = loader;
+ }
+
+ @Override
+ public Optional<Map<String, String>> getHeaders() {
+ checkOpen();
+ return Optional.ofNullable(headers);
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public Iterable<String> getEntries() throws IOException {
+ checkOpen();
+ return entries.keySet();
+ }
+
+ @Override
+ public Optional<ConnectEntry> getEntry(String name) {
+ checkOpen();
+ return Optional.ofNullable(entries.get(name));
+ }
+
+ @Override
+ public Optional<ClassLoader> getClassLoader() {
+ checkOpen();
+ return Optional.ofNullable(loader);
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public void open() throws IOException {
+ if (!isOpen.compareAndSet(false, true)) {
+ throw new IllegalStateException("Already Opened.");
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public void close() throws IOException {
+ if (!isOpen.compareAndSet(true, false)) {
+ throw new IllegalStateException("Already Closed.");
+ }
+ }
+
+ void addEntry(String path, ConnectEntry entry) {
+ entries.put(path, entry);
+ }
+
+ private void checkOpen() {
+ if (!isOpen.get()) {
+ throw new IllegalStateException("Not Opened.");
+ }
+ }
+
+ boolean isOpen() {
+ return isOpen.get();
+ }
+ }
+
+ public static class TestConnectEntryBytes implements ConnectEntry {
+ private final String name;
+ private final byte[] bytes;
+
+ public TestConnectEntryBytes(String name, byte[] bytes) {
+ this.name = name;
+ this.bytes = bytes;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public long getContentLength() {
+ return bytes.length;
+ }
+
+ @Override
+ public long getLastModified() {
+ return 0;
+ }
+
+ @Override
+ public byte[] getBytes() {
+ return bytes.clone();
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ return new ByteArrayInputStream(bytes);
+ }
+
+ }
+
+ public static class TestConnectEntryURL implements ConnectEntry {
+ private final String name;
+ private final URL content;
+
+ public TestConnectEntryURL(String name, URL content) {
+ this.name = name;
+ this.content = content;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public long getContentLength() {
+ try {
+ return content.openConnection().getContentLengthLong();
+ } catch (IOException e) {
+ return 0;
+ }
+ }
+
+ @Override
+ public long getLastModified() {
+ try {
+ return content.openConnection().getLastModified();
+ } catch (IOException e) {
+ return 0;
+ }
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return content.openStream();
+ }
+
+ }
+
+ static final TestConnectModule ILLEGAL_STATE_EXCEPTION = new TestConnectModule(null);
+
+ public void testConnectFactoryNoModules() {
+ TestCountingConnectFactory connectFactory = new TestCountingConnectFactory();
+
+ doTestConnect(connectFactory, new HashMap<>(), (f) -> {
+ try {
+ f.start();
+ f.stop();
+ f.waitForStop(5000);
+ f.start();
+ f.stop();
+ f.waitForStop(5000);
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ doTestConnect(connectFactory, new HashMap<>(), (f) -> {
+ try {
+ f.start();
+ f.stop();
+ } catch (BundleException e) {
+ sneakyThrow(e);
+ }
+ });
+
+ assertEquals("Wrong number of init called.", 2, connectFactory.getInitializeCnt());
+ assertEquals("Wrong number of create activator called.", 3, connectFactory.getCreateBundleActivatorCnt());
+ }
+
+ public void testConnectActivator() {
+ final AtomicInteger bundleActvatorStartCalled = new AtomicInteger();
+ final AtomicInteger bundleActvatorStopCalled = new AtomicInteger();
+ ConnectFactory activatorFactory = new TestCountingConnectFactory() {
+ @Override
+ public Optional<BundleActivator> createBundleActivator() {
+ super.createBundleActivator();
+ return Optional.of(new BundleActivator() {
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ bundleActvatorStartCalled.getAndIncrement();
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ bundleActvatorStopCalled.getAndIncrement();
+ }
+ });
+ }
+ };
+
+ doTestConnect(activatorFactory, new HashMap<>(), (f) -> {
+ try {
+ f.start();
+ f.stop();
+ f.waitForStop(5000);
+ f.start();
+ f.stop();
+ f.waitForStop(5000);
+ } catch (Exception e) {
+ sneakyThrow(e);
+ }
+ });
+ assertEquals("Wrong number of start called.", 2, bundleActvatorStartCalled.get());
+ assertEquals("Wrong number of stop called.", 2, bundleActvatorStopCalled.get());
+ }
+
+ public void testConnectInit() {
+ final AtomicReference<File> initFile = new AtomicReference<>();
+ final AtomicReference<File> storeFile = new AtomicReference<>();
+ final AtomicReference<Map<String, String>> initConfig = new AtomicReference<>();
+ ConnectFactory activatorFactory = new TestCountingConnectFactory() {
+ @Override
+ public void initialize(File storage, Map<String, String> config) {
+ super.initialize(storage, config);
+ initFile.set(storage);
+ initConfig.set(config);
+ }
+ };
+
+ Map<String, String> config = new HashMap<>();
+ config.put("k1", "v1");
+ config.put("k2", "v2");
+
+ doTestConnect(activatorFactory, config, (f) -> {
+ try {
+ f.init();
+ BundleContext bc = f.getBundleContext();
+ storeFile.set(new File(bc.getProperty(Constants.FRAMEWORK_STORAGE)));
+ } catch (Exception e) {
+ sneakyThrow(e);
+ }
+ });
+ TestCase.assertEquals("Wrong init store file.", storeFile.get(), initFile.get());
+ assertTrue("Did not find all init configs: " + initConfig.get(), initConfig.get().entrySet().containsAll(config.entrySet()));
+ try {
+ initConfig.get().put("k3", "v3");
+ fail("Expected unmodifiable map");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testConnectContentHeaders() throws IOException {
+ doTestConnectContentSimple(false);
+ }
+
+ public void testConnectContentManifest() throws IOException {
+ doTestConnectContentSimple(true);
+ }
+
+ void doTestConnectContentSimple(boolean withManifest) throws IOException {
+ TestCountingConnectFactory connectFactory = new TestCountingConnectFactory();
+ final List<String> locations = Arrays.asList("b.1", "b.2", "b.3", "b.4");
+ for (String l : locations) {
+ connectFactory.setModule(l, withManifest ? createSimpleManifestModule(l) : createSimpleHeadersModule(l));
+ }
+
+ doTestConnect(connectFactory, new HashMap<>(), (f) -> {
+ try {
+ f.init();
+ for (String l : locations) {
+ Bundle b = f.getBundleContext().installBundle(l);
+ assertEquals("Wrong symbolic name.", l, b.getSymbolicName());
+ }
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+
+ doTestConnect(connectFactory, new HashMap<>(), (f) -> {
+ try {
+ f.init();
+ Bundle[] bundles = f.getBundleContext().getBundles();
+ assertEquals("Wrong number of bundles from cache.", locations.size() + 1, bundles.length);
+ for (String l : locations) {
+ Bundle b = f.getBundleContext().getBundle(l);
+ assertNotNull("No bundle at location: " + l, b);
+ assertEquals("Wrong symbolic name.", l, b.getSymbolicName());
+ }
+ } catch (BundleException e) {
+ sneakyThrow(e);
+ }
+ });
+
+ connectFactory.setModule("b.2", null);
+ connectFactory.setModule("b.3", ILLEGAL_STATE_EXCEPTION);
+ doTestConnect(connectFactory, new HashMap<>(), (f) -> {
+ try {
+ f.init();
+ Bundle[] bundles = f.getBundleContext().getBundles();
+ assertEquals("Wrong number of bundles from cache.", locations.size() - 1, bundles.length);
+ for (String l : locations) {
+ Bundle b = f.getBundleContext().getBundle(l);
+ if ("b.2".equals(l) || "b.3".equals(l)) {
+ assertNull("Found unexpected bundle.", b);
+ } else {
+ assertNotNull("No bundle at location: " + l, b);
+ assertEquals("Wrong symbolic name.", l, b.getSymbolicName());
+ }
+ }
+ } catch (BundleException e) {
+ sneakyThrow(e);
+ }
+ });
+ }
+
+ public void testConnectContentActivatorsWithFrameworkLoaders() {
+ doTestConnectContentActivators(false);
+ }
+
+ public void testConnectContentActivatorsWithProvidedLoaders() {
+ doTestConnectContentActivators(true);
+ }
+
+ void doTestConnectContentActivators(boolean provideLoader) {
+ TestCountingConnectFactory connectFactory = new TestCountingConnectFactory();
+ final List<Integer> ids = Arrays.asList(1, 2, 3);
+ for (Integer id : ids) {
+ connectFactory.setModule(id.toString(), createAdvancedModule(id, provideLoader));
+ }
+
+ doTestConnect(connectFactory, new HashMap<>(), (f) -> {
+ try {
+ f.start();
+ for (Integer id : ids) {
+ Bundle b = f.getBundleContext().installBundle(id.toString());
+ assertEquals("Wrong symbolic name.", id.toString(), b.getSymbolicName());
+ b.start();
+ ServiceReference<?>[] registered = b.getRegisteredServices();
+ assertNotNull("No services found.", registered);
+ assertEquals("Wrong number of services.", 1, registered.length);
+ assertEquals("Wrong service property.", Activator.class.getSimpleName() + id, (String) registered[0].getProperty("activator"));
+ if (provideLoader) {
+ assertTrue("Expected the same classes.", Activator.class.equals(b.loadClass(Activator.class.getName())));
+ } else {
+ assertFalse("Expected different classes.", Activator.class.equals(b.loadClass(Activator.class.getName())));
+ }
+ }
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ }
+
+ public void testConnectContentEntriesWithFrameworkLoaders() {
+ doTestConnectContentEntries(false);
+ }
+
+ public void testConnectContentEntriesWithProvidedLoaders() {
+ doTestConnectContentEntries(true);
+ }
+
+ void doTestConnectContentEntries(boolean provideLoader) {
+ TestCountingConnectFactory connectFactory = new TestCountingConnectFactory();
+ final List<Integer> ids = Arrays.asList(1, 2, 3);
+ final Map<Integer, TestConnectModule> modules = new HashMap<>();
+ for (Integer id : ids) {
+ TestConnectModule m = createAdvancedModule(id, provideLoader);
+ modules.put(id, m);
+ connectFactory.setModule(id.toString(), m);
+ }
+
+ doTestConnect(connectFactory, new HashMap<>(), (f) -> {
+ try {
+ f.start();
+ for (Integer id : ids) {
+ Bundle b = f.getBundleContext().installBundle(id.toString());
+ assertEquals("Wrong symbolic name.", id.toString(), b.getSymbolicName());
+ TestConnectModule m = modules.get(id);
+ List<String> entries = new ArrayList<>();
+ for (String entry : m.getContent().getEntries()) {
+ entries.add(entry);
+ }
+
+ Set<String> bundleEntryUrls = new HashSet<>();
+ for (Enumeration<URL> eUrls = b.findEntries("/", "*", true); eUrls.hasMoreElements();) {
+ // URL paths always begin with '/', remove it
+ bundleEntryUrls.add(eUrls.nextElement().getPath().substring(1));
+ }
+ assertEquals("Wrong number of bundle entry URLs.", entries.size(), bundleEntryUrls.size());
+ assertTrue("Wrong bundle entry URLs: " + bundleEntryUrls, entries.containsAll(bundleEntryUrls));
+
+ List<String> bundleEntryPaths = new ArrayList<>();
+ for (Enumeration<String> ePaths = b.getEntryPaths("org/eclipse/osgi/tests/bundles/resources"); ePaths.hasMoreElements();) {
+ bundleEntryPaths.add(ePaths.nextElement());
+ }
+ assertEquals("Wrong number of bundle entry paths from root.", 1, bundleEntryPaths.size());
+ assertEquals("Wrong bundle entry found at root.", "org/eclipse/osgi/tests/bundles/resources/" + id + ".txt", bundleEntryPaths.get(0));
+
+ BundleWiring wiring = b.adapt(BundleWiring.class);
+ assertNotNull("No wiring.", wiring);
+ Collection<String> wiringResourcePaths = wiring.listResources("/", "*", BundleWiring.LISTRESOURCES_LOCAL | BundleWiring.LISTRESOURCES_RECURSE);
+ assertEquals("Wrong number of resource paths.", entries.size(), wiringResourcePaths.size());
+ assertTrue("Wrong resource paths: " + wiringResourcePaths, entries.containsAll(wiringResourcePaths));
+
+ Set<String> wiringEntryUrls = new HashSet<>();
+ for (URL url : wiring.findEntries("/", "*", BundleWiring.FINDENTRIES_RECURSE)) {
+ // URL paths always begin with '/', remove it
+ wiringEntryUrls.add(url.getPath().substring(1));
+ }
+ assertEquals("Wrong number of wiring entry URLs.", entries.size(), wiringEntryUrls.size());
+ assertTrue("Wrong wiring entry URLs: " + wiringEntryUrls, entries.containsAll(wiringEntryUrls));
+
+ String txtPath = "org/eclipse/osgi/tests/bundles/resources/" + id + ".txt";
+ Optional<ConnectEntry> txtConnectEntry = m.getContent().getEntry(txtPath);
+ assertTrue("Could not find text entry.", txtConnectEntry.isPresent());
+ checkEntry(txtConnectEntry.get(), b.getEntry(txtPath), id);
+ checkEntry(txtConnectEntry.get(), b.getResource(txtPath), id);
+ }
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ }
+
+ public void testOpenCloseUpdateConnectContent() {
+ final String NAME1 = "testUpdate.1";
+ final String NAME2 = "testUpdate.2";
+ TestCountingConnectFactory connectFactory = new TestCountingConnectFactory();
+ TestConnectModule m = createSimpleHeadersModule(NAME1);
+ connectFactory.setModule(NAME1, m);
+
+ doTestConnect(connectFactory, new HashMap<>(), (f) -> {
+ try {
+ f.start();
+ Bundle b = f.getBundleContext().installBundle(NAME1);
+ assertEquals("Wrong name.", NAME1, b.getSymbolicName());
+ // make sure to open the bundle file
+ assertNull(b.getEntry("doesNotExist.txt"));
+ TestConnectContent original = m.getContent();
+ assertTrue("Original content is not open.", original.isOpen());
+
+ // set the new content but don't update
+ m.setContent(createSimpleHeadersContent(NAME2));
+
+ FrameworkWiring fwkWiring = f.adapt(FrameworkWiring.class);
+ CountDownLatch refreshDone = new CountDownLatch(1);
+ fwkWiring.refreshBundles(Collections.singletonList(b), (e) -> refreshDone.countDown());
+ refreshDone.await();
+
+ // should still be NAME1
+ assertEquals("Wrong name.", NAME1, b.getSymbolicName());
+ assertTrue("Original content is not open.", original.isOpen());
+
+ // now update should stage in the new content
+ b.update();
+ assertEquals("Wrong name.", NAME2, b.getSymbolicName());
+ // make sure to open the bundle file
+ assertNull(b.getEntry("doesNotExist.txt"));
+ TestConnectContent newContent = m.getContent();
+ assertTrue("New content is not open.", newContent.isOpen());
+ assertFalse("Original content is open.", original.isOpen());
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ }
+
+ void checkEntry(ConnectEntry expected, URL actual, Integer id) throws IOException {
+ assertEquals("Wring path.", expected.getName(), actual.getPath().substring(1));
+ URLConnection connection = actual.openConnection();
+ assertEquals("Wrong last modified.", expected.getLastModified(), connection.getLastModified());
+ assertEquals("Wrong content length.", expected.getContentLength(), connection.getContentLengthLong());
+ byte[] expectedBytes = getBytes(expected.getInputStream());
+ byte[] actualBytes = getBytes(connection.getInputStream());
+ assertEquals("Wrong input steam size.", expectedBytes.length, actualBytes.length);
+ for (int i = 0; i < expectedBytes.length; i++) {
+ assertEquals("Wrong byte at: " + i, expectedBytes[i], actualBytes[i]);
+ }
+ String actualString = new String(actualBytes);
+ assertEquals("Wrong entry string.", id.toString(), actualString);
+ }
+
+ TestConnectModule createSimpleHeadersModule(String name) {
+ return new TestConnectModule(createSimpleHeadersContent(name));
+ }
+
+ TestConnectContent createSimpleHeadersContent(String name) {
+ Map<String, String> headers = new HashMap<>();
+ headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, name);
+ headers.put(Constants.IMPORT_PACKAGE, "org.osgi.framework");
+ return new TestConnectContent(headers, null);
+ }
+
+ TestConnectModule createSimpleManifestModule(String name) throws IOException {
+ Manifest manifest = new Manifest();
+ Attributes headers = manifest.getMainAttributes();
+ headers.putValue("Manifest-Version", "1");
+ headers.putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
+ headers.putValue(Constants.BUNDLE_SYMBOLICNAME, name);
+ headers.putValue(Constants.IMPORT_PACKAGE, "org.osgi.framework");
+ ByteArrayOutputStream manifestBytes = new ByteArrayOutputStream();
+ manifest.write(manifestBytes);
+ TestConnectContent c = new TestConnectContent(null, null);
+ addEntry("META-INF/MANIFEST.MF", manifestBytes.toByteArray(), c);
+ return new TestConnectModule(c);
+ }
+
+ TestConnectModule createAdvancedModule(Integer id, boolean provideLoader) {
+ Map<String, String> headers = new HashMap<>();
+ headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, id.toString());
+ headers.put(Constants.IMPORT_PACKAGE, "org.osgi.framework");
+ headers.put(Constants.BUNDLE_ACTIVATOR, Activator.class.getName() + id);
+ TestConnectContent c = new TestConnectContent(headers, provideLoader ? getClass().getClassLoader() : null);
+ addEntry("org/", c);
+ addEntry("org/eclipse/", c);
+ addEntry("org/eclipse/osgi/", c);
+ addEntry("org/eclipse/osgi/tests/", c);
+ addEntry("org/eclipse/osgi/tests/bundles/", c);
+ addEntry("org/eclipse/osgi/tests/bundles/classes/", c);
+ addEntry("org/eclipse/osgi/tests/bundles/classes/Activator.class", c);
+ addEntry("org/eclipse/osgi/tests/bundles/classes/Activator" + id + ".class", c);
+ addEntry("org/eclipse/osgi/tests/bundles/resources/", c);
+ addEntry("org/eclipse/osgi/tests/bundles/resources/" + id + ".txt", c);
+ return new TestConnectModule(c);
+ }
+
+ void addEntry(String name, TestConnectContent content) {
+ content.addEntry(name, new TestConnectEntryURL(name, getClass().getResource("/" + name)));
+ }
+
+ void addEntry(String name, byte[] bytes, TestConnectContent content) {
+ content.addEntry(name, new TestConnectEntryBytes(name, bytes));
+ }
+
+ static byte[] getBytes(InputStream in) throws IOException {
+ byte[] classbytes;
+ int bytesread = 0;
+ int readcount;
+ try {
+ int length = 1024;
+ classbytes = new byte[length];
+ readloop: while (true) {
+ for (; bytesread < length; bytesread += readcount) {
+ readcount = in.read(classbytes, bytesread, length - bytesread);
+ if (readcount <= 0) /* if we didn't read anything */
+ break readloop; /* leave the loop */
+ }
+ byte[] oldbytes = classbytes;
+ length += 1024;
+ classbytes = new byte[length];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+
+ if (classbytes.length > bytesread) {
+ byte[] oldbytes = classbytes;
+ classbytes = new byte[bytesread];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (IOException ee) {
+ // nothing to do here
+ }
+ }
+ return classbytes;
+ }
+
+ public static <E extends Throwable> void sneakyThrow(Throwable e) throws E {
+ throw (E) e;
+ }
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator.java
new file mode 100644
index 000000000..129445301
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles.classes;
+
+import java.util.Collections;
+import java.util.Hashtable;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+ @Override
+ public void start(BundleContext context) throws Exception {
+ context.registerService(Activator.class, this, new Hashtable<>(Collections.singletonMap("activator", this.getClass().getSimpleName())));
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ // do nothing
+ }
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator1.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator1.java
new file mode 100644
index 000000000..527a559fd
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator1.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles.classes;
+
+public class Activator1 extends Activator {
+ // nothing
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator2.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator2.java
new file mode 100644
index 000000000..a223183f0
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator2.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles.classes;
+
+public class Activator2 extends Activator {
+ // nothing
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator3.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator3.java
new file mode 100644
index 000000000..272821d47
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator3.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles.classes;
+
+public class Activator3 extends Activator {
+ // nothing
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/1.txt b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/1.txt
new file mode 100644
index 000000000..56a6051ca
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/1.txt
@@ -0,0 +1 @@
+1 \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/2.txt b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/2.txt
new file mode 100644
index 000000000..d8263ee98
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/2.txt
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/3.txt b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/3.txt
new file mode 100644
index 000000000..e440e5c84
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/3.txt
@@ -0,0 +1 @@
+3 \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java
index f7726f3ee..e77c2f0be 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java
@@ -29,6 +29,7 @@ import org.eclipse.osgi.tests.OSGiTestsActivator;
import org.eclipse.osgi.tests.bundles.BundleInstaller;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.connect.FrameworkUtilHelper;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
@@ -72,7 +73,7 @@ public abstract class AbstractFrameworkHookTests extends CoreTest {
throw new RuntimeException(e);
}
}
- if (name.startsWith("org.eclipse") || name.startsWith("org.osgi.framework.FrameworkUtil")) {
+ if (name.startsWith("org.eclipse") || name.startsWith("org.osgi.framework.FrameworkUtil") || name.equals(FrameworkUtilHelper.class.getName())) {
Class<?> result = findLoadedClass(name);
if (result == null)
result = findClass(name);
diff --git a/bundles/org.eclipse.osgi/.settings/.api_filters b/bundles/org.eclipse.osgi/.settings/.api_filters
new file mode 100644
index 000000000..8b4d46a15
--- /dev/null
+++ b/bundles/org.eclipse.osgi/.settings/.api_filters
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.osgi" version="2">
+ <resource path="container/src/org/eclipse/osgi/launch/EquinoxFactory.java" type="org.eclipse.osgi.launch.EquinoxFactory">
+ <filter comment="Not for OSGi API" id="1143996420">
+ <message_arguments>
+ <message_argument value="newFramework(Map&lt;String,String&gt;, ConnectFactory)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/ConnectContent.java" type="org.osgi.framework.connect.ConnectContent">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.ConnectContent"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/ConnectFactory.java" type="org.osgi.framework.connect.ConnectFactory">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.ConnectFactory"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/ConnectModule.java" type="org.osgi.framework.connect.ConnectModule">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.ConnectModule"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java" type="org.osgi.framework.connect.FrameworkUtilHelper">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.FrameworkUtilHelper"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/launch/FrameworkFactory.java" type="org.osgi.framework.launch.FrameworkFactory">
+ <filter comment="Not for OSGi packages" id="403804204">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.launch.FrameworkFactory"/>
+ <message_argument value="newFramework(Map&lt;String,String&gt;, ConnectFactory)"/>
+ </message_arguments>
+ </filter>
+ <filter comment="Not for OSGi packages" id="1209008130">
+ <message_arguments>
+ <message_argument value="1.3"/>
+ <message_argument value="3.16"/>
+ <message_argument value="newFramework(Map&lt;String,String&gt;, ConnectFactory)"/>
+ </message_arguments>
+ </filter>
+ <filter comment="Not for OSGi packages" id="1211105284">
+ <message_arguments>
+ <message_argument value="newFramework(Map&lt;String,String&gt;, ConnectFactory)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs b/bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs
index 5b3c8e014..8dd4a28d9 100644
--- a/bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs
+++ b/bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs
@@ -1,11 +1,17 @@
-#Thu Oct 08 09:47:30 CDT 2009
+ANNOTATION_ELEMENT_TYPE_ADDED_FIELD=Error
ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_FIELD=Error
CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
@@ -45,6 +51,7 @@ ILLEGAL_IMPLEMENT=Warning
ILLEGAL_INSTANTIATE=Warning
ILLEGAL_OVERRIDE=Warning
ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Error
INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
@@ -56,6 +63,7 @@ INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Ignore
INVALID_JAVADOC_TAG=Ignore
INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
LEAK_EXTEND=Warning
@@ -73,6 +81,7 @@ METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Warning
TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
@@ -80,10 +89,14 @@ TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+changed_execution_env=Error
eclipse.preferences.version=1
incompatible_api_component_version=Error
incompatible_api_component_version_include_major_without_breaking_change=Disabled
incompatible_api_component_version_include_minor_without_api_change=Disabled
+incompatible_api_component_version_report_major_without_breaking_change=Warning
+incompatible_api_component_version_report_minor_without_api_change=Warning
invalid_since_tag_version=Error
malformed_since_tag=Error
missing_since_tag=Error
diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
index 67e3be796..f784484e0 100644
--- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
@@ -34,7 +34,7 @@ Export-Package: org.eclipse.core.runtime.adaptor;x-friends:="org.eclipse.core.ru
org.eclipse.osgi.internal.serviceregistry;x-internal:=true,
org.eclipse.osgi.internal.signedcontent;x-internal:=true,
org.eclipse.osgi.internal.url;x-internal:=true,
- org.eclipse.osgi.launch;version="1.0";uses:="org.osgi.framework,org.osgi.framework.launch",
+ org.eclipse.osgi.launch;version="1.1";uses:="org.osgi.framework,org.osgi.framework.launch,org.osgi.framework.connect",
org.eclipse.osgi.report.resolution;version="1.0";uses:="org.osgi.service.resolver,org.osgi.resource",
org.eclipse.osgi.service.datalocation;version="1.3",
org.eclipse.osgi.service.debug;version="1.2",
@@ -52,13 +52,14 @@ Export-Package: org.eclipse.core.runtime.adaptor;x-friends:="org.eclipse.core.ru
org.eclipse.osgi.storagemanager;version="1.0",
org.eclipse.osgi.util;version="1.1",
org.osgi.dto;version="1.1",
- org.osgi.framework;version="1.9",
+ org.osgi.framework;version="1.10",
+ org.osgi.framework.connect;version="1.0",
org.osgi.framework.dto;version="1.8";uses:="org.osgi.dto",
org.osgi.framework.hooks.bundle;version="1.1";uses:="org.osgi.framework",
org.osgi.framework.hooks.resolver;version="1.0";uses:="org.osgi.framework.wiring",
org.osgi.framework.hooks.service;version="1.1";uses:="org.osgi.framework",
org.osgi.framework.hooks.weaving;version="1.1";uses:="org.osgi.framework.wiring",
- org.osgi.framework.launch;version="1.2";uses:="org.osgi.framework",
+ org.osgi.framework.launch;version="1.3";uses:="org.osgi.framework,org.osgi.framework.connect",
org.osgi.framework.namespace;version="1.1";uses:="org.osgi.resource",
org.osgi.framework.startlevel;version="1.0";uses:="org.osgi.framework",
org.osgi.framework.startlevel.dto;version="1.0";uses:="org.osgi.dto",
@@ -101,7 +102,7 @@ Bundle-Activator: org.eclipse.osgi.internal.framework.SystemBundleActivator
Bundle-Description: %systemBundle
Bundle-Copyright: %copyright
Bundle-Vendor: %eclipse.org
-Bundle-Version: 3.15.100.qualifier
+Bundle-Version: 3.16.0.qualifier
Bundle-Localization: systembundle
Bundle-DocUrl: http://www.eclipse.org
Eclipse-ExtensibleAPI: true
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFile.java
new file mode 100644
index 000000000..846f7173c
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFile.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Optional;
+import org.eclipse.osgi.internal.debug.Debug;
+import org.eclipse.osgi.storage.BundleInfo;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.CloseableBundleFile;
+import org.eclipse.osgi.storage.bundlefile.MRUBundleFileList;
+import org.osgi.framework.connect.ConnectContent;
+import org.osgi.framework.connect.ConnectContent.ConnectEntry;
+import org.osgi.framework.connect.ConnectModule;
+
+public class ConnectBundleFile extends CloseableBundleFile<ConnectEntry> {
+ public class ConnectBundleEntry extends BundleEntry {
+ private final ConnectEntry connectEntry;
+
+ public ConnectBundleEntry(ConnectEntry entry) {
+ this.connectEntry = entry;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return ConnectBundleFile.this.getInputStream(connectEntry);
+ }
+
+ @Override
+ public byte[] getBytes() throws IOException {
+ return connectEntry.getBytes();
+ }
+
+ @Override
+ public long getSize() {
+ return connectEntry.getContentLength();
+ }
+
+ @Override
+ public String getName() {
+ return connectEntry.getName();
+ }
+
+ @Override
+ public long getTime() {
+ return connectEntry.getLastModified();
+ }
+
+ @Override
+ public URL getFileURL() {
+ File file = ConnectBundleFile.this.getFile(getName(), false);
+ if (file != null) {
+ try {
+ return file.toURI().toURL();
+ } catch (MalformedURLException e) {
+ // should never happen
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public URL getLocalURL() {
+ // TODO Not sure what to do here
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private final ConnectContent content;
+
+ public ConnectBundleFile(ConnectModule module, File basefile, BundleInfo.Generation generation, MRUBundleFileList mruList, Debug debug) throws IOException {
+ super(basefile, generation, mruList, debug);
+ this.content = module.getContent();
+ }
+
+ @Override
+ protected void doOpen() throws IOException {
+ content.open();
+ }
+
+ @Override
+ protected Iterable<String> getPaths() {
+ try {
+ return content.getEntries();
+ } catch (IOException e) {
+ return Collections.emptyList();
+ }
+ }
+
+ @Override
+ protected BundleEntry findEntry(String path) {
+ return content.getEntry(path).map(ConnectBundleEntry::new).orElse(null);
+ }
+
+ @Override
+ protected void doClose() throws IOException {
+ content.close();
+ }
+
+ @Override
+ protected void postClose() {
+ // do nothing
+ }
+
+ @Override
+ protected InputStream doGetInputStream(ConnectEntry entry) throws IOException {
+ return entry.getInputStream();
+ }
+
+ Optional<ClassLoader> getClassLoader() {
+ return content.getClassLoader();
+ }
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFileFactory.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFileFactory.java
new file mode 100644
index 000000000..a5cae1bb8
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFileFactory.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import org.eclipse.osgi.internal.connect.ConnectHookConfigurator.ConnectModules;
+import org.eclipse.osgi.internal.debug.Debug;
+import org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook;
+import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
+import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
+import org.eclipse.osgi.storage.bundlefile.MRUBundleFileList;
+import org.osgi.framework.connect.ConnectModule;
+
+public class ConnectBundleFileFactory implements BundleFileWrapperFactoryHook {
+ final ConnectModules connectModules;
+ final Debug debug;
+
+ public ConnectBundleFileFactory(ConnectModules connectModules, Debug debug) {
+ this.connectModules = connectModules;
+ this.debug = debug;
+ }
+
+ @Override
+ public BundleFileWrapper wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base) {
+ ConnectModule m = connectModules.getConnectModule(generation.getBundleInfo().getLocation());
+ if (m == null) {
+ return null;
+ }
+ MRUBundleFileList mruList = generation.getBundleInfo().getStorage().getMRUBundleFileList();
+ try {
+ ConnectBundleFile connectBundleFile = new ConnectBundleFile(m, bundleFile.getBaseFile(), generation, mruList, debug);
+ return new ConnectBundleFileWrapper(bundleFile, connectBundleFile);
+ } catch (IOException e) {
+ // TODO should log this
+ }
+ return null;
+ }
+
+ public static class ConnectBundleFileWrapper extends BundleFileWrapper {
+ private final ConnectBundleFile connectBundleFile;
+
+ public ConnectBundleFileWrapper(BundleFile bundleFile, ConnectBundleFile connectBundleFile) {
+ super(bundleFile);
+ this.connectBundleFile = connectBundleFile;
+ }
+
+ @Override
+ public BundleEntry getEntry(final String path) {
+ return connectBundleFile.getEntry(path);
+ }
+
+ @Override
+ public File getFile(String path, boolean nativeCode) {
+ return connectBundleFile.getFile(path, nativeCode);
+ }
+
+ @Override
+ public Enumeration<String> getEntryPaths(String path) {
+ return connectBundleFile.getEntryPaths(path);
+ }
+
+ @Override
+ public Enumeration<String> getEntryPaths(String path, boolean recurse) {
+ return connectBundleFile.getEntryPaths(path, recurse);
+ }
+
+ @Override
+ public boolean containsDir(String dir) {
+ return connectBundleFile.containsDir(dir);
+ }
+
+ @Override
+ public void open() throws IOException {
+ connectBundleFile.open();
+ super.open();
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ connectBundleFile.close();
+ }
+
+ ConnectBundleFile getConnectBundleFile() {
+ return connectBundleFile;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java
new file mode 100644
index 000000000..c1a7646e8
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+import org.eclipse.osgi.container.Module;
+import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
+import org.eclipse.osgi.container.ModuleRevisionBuilder;
+import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory;
+import org.eclipse.osgi.internal.connect.ConnectBundleFileFactory.ConnectBundleFileWrapper;
+import org.eclipse.osgi.internal.debug.Debug;
+import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
+import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
+import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
+import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
+import org.eclipse.osgi.internal.hookregistry.HookRegistry;
+import org.eclipse.osgi.internal.hookregistry.StorageHookFactory;
+import org.eclipse.osgi.internal.hookregistry.StorageHookFactory.StorageHook;
+import org.eclipse.osgi.internal.loader.BundleLoader;
+import org.eclipse.osgi.internal.loader.ModuleClassLoader;
+import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
+import org.eclipse.osgi.storage.bundlefile.BundleFileWrapperChain;
+import org.eclipse.osgi.storage.url.reference.ReferenceInputStream;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.connect.ConnectContent;
+import org.osgi.framework.connect.ConnectFactory;
+import org.osgi.framework.connect.ConnectModule;
+
+public class ConnectHookConfigurator implements HookConfigurator {
+ static final ConnectModule NULL_MODULE = new ConnectModule() {
+ @Override
+ public ConnectContent getContent() throws IOException {
+ throw new IOException();
+ }
+ };
+
+ static final byte[] EMPTY_JAR;
+ static {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JarOutputStream jos = new JarOutputStream(baos);
+ ZipEntry bootBundlePropsEntry = new ZipEntry("ConnectBundle.properties"); //$NON-NLS-1$
+ jos.putNextEntry(bootBundlePropsEntry);
+ Properties bootBundleProps = new Properties();
+ bootBundleProps.setProperty("ConnectBundle", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+ bootBundleProps.store(jos, "ConnectBundle"); //$NON-NLS-1$
+ jos.close();
+ EMPTY_JAR = baos.toByteArray();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void addHooks(final HookRegistry hookRegistry) {
+ ConnectFactory connectFactory = hookRegistry.getContainer().getConnectFactory();
+ final ConnectModules connectModules = new ConnectModules(connectFactory);
+
+ URL configUrl = hookRegistry.getContainer().getLocations().getConfigurationLocation().getURL();
+ final File storage = new File(configUrl.getPath());
+ final File emptyJar = new File(storage, "connectEmptyBundle.jar"); //$NON-NLS-1$
+ if (connectFactory != null && !emptyJar.exists()) {
+ try {
+ Files.write(emptyJar.toPath(), EMPTY_JAR);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ hookRegistry.addStorageHookFactory(new StorageHookFactory<Object, Object, StorageHook<Object, Object>>() {
+ @Override
+ protected StorageHook<Object, Object> createStorageHook(Generation generation) {
+ final ConnectModule m = connectModules.getConnectModule(generation.getBundleInfo().getLocation());
+
+ return new StorageHook<Object, Object>(generation, this.getClass()) {
+ boolean hasModule = false;
+
+ @Override
+ public void save(Object saveContext, DataOutputStream os) throws IOException {
+ os.writeBoolean(m != null);
+ }
+
+ @Override
+ public void load(Object loadContext, DataInputStream is) throws IOException {
+ hasModule = is.readBoolean();
+ }
+
+ @Override
+ public void validate() throws IllegalStateException {
+ // make sure we have the module still from the factory
+ if (hasModule && connectModules.getConnectModule(generation.getBundleInfo().getLocation()) == null) {
+ throw new IllegalStateException("Connect Factory no longer has the module at locataion: " + generation.getBundleInfo().getLocation()); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public ModuleRevisionBuilder adaptModuleRevisionBuilder(ModuleEvent operation, Module origin, ModuleRevisionBuilder builder) {
+ if (m != null) {
+ try {
+ ConnectContent content = m.getContent();
+ return content.getHeaders().map((h) -> {
+ try {
+ return OSGiManifestBuilderFactory.createBuilder(h);
+ } catch (BundleException e) {
+ sneakyThrow(e);
+ }
+ return null; // should never get here
+ }).orElse(null);
+ } catch (IOException e) {
+ sneakyThrow(new BundleException("Error reading bundle.", BundleException.READ_ERROR, e)); //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+ @Override
+ public URLConnection handleContentConnection(Module module, String location, InputStream in) {
+ if (location == null) {
+ location = module.getLocation();
+ }
+ ConnectModule m = connectModules.getConnectModule(location);
+ if (m != null) {
+ return new URLConnection(null) {
+ @Override
+ public void connect() throws IOException {
+ connected = true;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new ReferenceInputStream(emptyJar);
+ }
+ };
+ }
+ return null;
+ }
+ });
+
+ if (connectFactory == null) {
+ return;
+ }
+
+ hookRegistry.addClassLoaderHook(new ClassLoaderHook() {
+ @Override
+ public ModuleClassLoader createClassLoader(ClassLoader parent, EquinoxConfiguration configuration, BundleLoader delegate, Generation generation) {
+ ConnectModule m = connectModules.getConnectModule(generation.getBundleInfo().getLocation());
+ if (m != null) {
+ BundleFile bundlefile = generation.getBundleFile();
+ if (bundlefile instanceof BundleFileWrapperChain) {
+ ConnectBundleFileWrapper content = ((BundleFileWrapperChain) bundlefile).getWrappedType(ConnectBundleFileWrapper.class);
+ if (content != null) {
+ return content.getConnectBundleFile().getClassLoader().map((l) //
+ -> new DelegatingConnectClassLoader(parent, configuration, delegate, generation, l)).orElse(null);
+ }
+ }
+ }
+ return null;
+ }
+ });
+
+ final Debug debug = hookRegistry.getContainer().getConfiguration().getDebug();
+ hookRegistry.addBundleFileWrapperFactoryHook(new ConnectBundleFileFactory(connectModules, debug));
+
+ hookRegistry.addActivatorHookFactory(new ActivatorHookFactory() {
+
+ @Override
+ public BundleActivator createActivator() {
+ final List<BundleActivator> activators = new ArrayList<>();
+ connectFactory.createBundleActivator().ifPresent((a) -> activators.add(a));
+ return new BundleActivator() {
+ @Override
+ public void start(BundleContext context) throws Exception {
+ for (BundleActivator activator : activators) {
+ activator.start(context);
+ }
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ for (BundleActivator activator : activators) {
+ activator.stop(context);
+ }
+ }
+ };
+ }
+ });
+ }
+
+ static class ConnectModules {
+ final ConnectFactory connectFactory;
+ private final ConcurrentMap<String, ConnectModule> connectModules = new ConcurrentHashMap<>();
+ volatile File emptyJar;
+
+ public ConnectModules(ConnectFactory connectFactory) {
+ this.connectFactory = connectFactory;
+ }
+
+ ConnectModule getConnectModule(String location) {
+ if (connectFactory == null) {
+ return null;
+ }
+ ConnectModule result = connectModules.computeIfAbsent(location, (l) -> {
+ try {
+ return connectFactory.getModule(location).orElse(NULL_MODULE);
+ } catch (IllegalStateException e) {
+ return NULL_MODULE;
+ }
+ });
+ return result == NULL_MODULE ? null : result;
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <E extends Throwable> void sneakyThrow(Throwable e) throws E {
+ throw (E) e;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/DelegatingConnectClassLoader.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/DelegatingConnectClassLoader.java
new file mode 100644
index 000000000..d9e1cf522
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/DelegatingConnectClassLoader.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
+import org.eclipse.osgi.internal.loader.BundleLoader;
+import org.eclipse.osgi.internal.loader.EquinoxClassLoader;
+import org.eclipse.osgi.storage.BundleInfo.Generation;
+
+public class DelegatingConnectClassLoader extends EquinoxClassLoader {
+ static {
+ try {
+ ClassLoader.registerAsParallelCapable();
+ } catch (Throwable t) {
+ // ignore any error
+ }
+ }
+ private final ClassLoader connectClassLoader;
+
+ public DelegatingConnectClassLoader(ClassLoader parent, EquinoxConfiguration configuration, BundleLoader delegate, Generation generation, ClassLoader connectClassLoader) {
+ super(parent, configuration, delegate, generation);
+ this.connectClassLoader = connectClassLoader;
+ }
+
+ @Override
+ public Class<?> findLocalClass(String classname) throws ClassNotFoundException {
+ if (connectClassLoader == null) {
+ throw new ClassNotFoundException();
+ }
+ return connectClassLoader.loadClass(classname);
+ }
+
+ @Override
+ public URL findLocalResource(String resource) {
+ if (connectClassLoader == null) {
+ return null;
+ }
+ return connectClassLoader.getResource(resource);
+ }
+
+ @Override
+ public Enumeration<URL> findLocalResources(String resource) {
+ if (connectClassLoader == null) {
+ return Collections.enumeration(Collections.<URL> emptyList());
+ }
+ try {
+ return connectClassLoader.getResources(resource);
+ } catch (IOException e) {
+ return Collections.enumeration(Collections.<URL> emptyList());
+ }
+ }
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
index d728c9fa9..bd06d5f1a 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
@@ -13,10 +13,13 @@
*******************************************************************************/
package org.eclipse.osgi.internal.framework;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
+import java.net.URL;
import java.security.AccessController;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -44,6 +47,7 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
+import org.osgi.framework.connect.ConnectFactory;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
import org.osgi.util.tracker.ServiceTracker;
@@ -53,6 +57,7 @@ public class EquinoxContainer implements ThreadFactory, Runnable {
public static final String NAME = "org.eclipse.osgi"; //$NON-NLS-1$
static final SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction());
+ private final ConnectFactory connectFactory;
private final EquinoxConfiguration equinoxConfig;
private final EquinoxLogServices logServices;
private final Storage storage;
@@ -75,7 +80,7 @@ public class EquinoxContainer implements ThreadFactory, Runnable {
private ScheduledExecutorService executor;
private StorageSaver storageSaver;
- public EquinoxContainer(Map<String, ?> configuration) {
+ public EquinoxContainer(Map<String, ?> configuration, ConnectFactory connectFactory) {
ClassLoader platformClassLoader = null;
try {
Method getPlatformClassLoader = ClassLoader.class.getMethod("getPlatformClassLoader"); //$NON-NLS-1$
@@ -86,9 +91,13 @@ public class EquinoxContainer implements ThreadFactory, Runnable {
/* boot class loader */};
}
this.bootLoader = platformClassLoader;
+ this.connectFactory = connectFactory;
this.equinoxConfig = new EquinoxConfiguration(configuration, new HookRegistry(this));
this.logServices = new EquinoxLogServices(this.equinoxConfig);
this.equinoxConfig.logMessages(this.logServices);
+
+ initConnectFactory(connectFactory, this.equinoxConfig);
+
this.equinoxConfig.getHookRegistry().initialize();
try {
this.storage = Storage.createStorage(this);
@@ -133,6 +142,21 @@ public class EquinoxContainer implements ThreadFactory, Runnable {
isProcessClassRecursionSupportedByAll = supportRecursion;
}
+ private static void initConnectFactory(ConnectFactory connectFactory, EquinoxConfiguration equinoxConfig) {
+ if (connectFactory == null) {
+ return;
+ }
+ URL configUrl = equinoxConfig.getEquinoxLocations().getConfigurationLocation().getURL();
+ final File fwkStore = new File(configUrl.getPath());
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ Map<String, String> config = (Map) equinoxConfig.getInitialConfig();
+ connectFactory.initialize(fwkStore, Collections.unmodifiableMap(config));
+ }
+
+ public ConnectFactory getConnectFactory() {
+ return connectFactory;
+ }
+
public Storage getStorage() {
return storage;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/FrameworkUtilHelper.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/FrameworkUtilHelper.java
deleted file mode 100644
index 80bc1a80c..000000000
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/FrameworkUtilHelper.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.internal.hookregistry;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
-
-/**
- * The helper provides alternative implementations for methods in the
- * {@link FrameworkUtil} class. While this is not a hook, it is possible
- * for framework fragments to provide a META-INF/services configuration
- * to allow their own implementation to be loaded by the {@link FrameworkUtil}
- * class.
- */
-public class FrameworkUtilHelper {
- /**
- * See {@link FrameworkUtil#getBundle(Class)}
- * @param classFromBundle a class defined by a bundle class loader.
- * @return A Bundle for the specified bundle class or null if the
- * specified class was not defined by a bundle class loader.
- */
- public Bundle getBundle(Class<?> classFromBundle) {
- return null;
- }
-}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java
index a2c9f3969..8d7fba963 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Properties;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.internal.cds.CDSHookConfigurator;
+import org.eclipse.osgi.internal.connect.ConnectHookConfigurator;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.hooks.DevClassLoadingHook;
@@ -106,6 +107,8 @@ public final class HookRegistry {
List<FrameworkLogEntry> errors = new ArrayList<>(0); // optimistic that no errors will occur
mergeFileHookConfigurators(configurators, errors);
mergePropertyHookConfigurators(configurators);
+ // make sure to add connect configurator first always
+ configurators.add(0, ConnectHookConfigurator.class.getName());
synchronized (this) {
addClassLoaderHook(new DevClassLoadingHook(container.getConfiguration()));
addClassLoaderHook(new EclipseLazyStarter(container));
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java
index 40d7bad54..f960f8707 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java
@@ -13,12 +13,24 @@
*******************************************************************************/
package org.eclipse.osgi.launch;
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.security.cert.X509Certificate;
-import java.util.*;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.framework.connect.ConnectFactory;
import org.osgi.framework.launch.Framework;
/**
@@ -31,7 +43,14 @@ public class Equinox implements Framework {
private final Framework systemBundle;
public Equinox(Map<String, ?> configuration) {
- EquinoxContainer container = new EquinoxContainer(configuration);
+ this(configuration, null);
+ }
+
+ /**
+ * @since 3.16
+ */
+ public Equinox(Map<String, ?> configuration, ConnectFactory connectFactory) {
+ EquinoxContainer container = new EquinoxContainer(configuration, connectFactory);
systemBundle = (Framework) container.getStorage().getModuleContainer().getModule(0).getBundle();
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java
index c836951ab..c997d5246 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java
@@ -14,6 +14,7 @@
package org.eclipse.osgi.launch;
import java.util.Map;
+import org.osgi.framework.connect.ConnectFactory;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
@@ -25,7 +26,11 @@ public class EquinoxFactory implements FrameworkFactory {
@Override
public Framework newFramework(Map<String, String> configuration) {
- return new Equinox(configuration);
+ return newFramework(configuration, null);
}
+ @Override
+ public Framework newFramework(Map<String, String> configuration, ConnectFactory connectFactory) {
+ return new Equinox(configuration, connectFactory);
+ }
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java
index 7b0816059..cb42a54cd 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java
@@ -543,7 +543,7 @@ final class BundlePermissionCollection extends PermissionCollection {
// work our way up the tree...
int last;
int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+ while ((last = requestedName.lastIndexOf('.', offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
bp = pc.get(requestedName);
if (bp != null) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
index 8a38df04e..80f5ca350 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
@@ -714,7 +714,7 @@ final class CapabilityPermissionCollection extends PermissionCollection {
/* work our way up the tree... */
int last;
int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+ while ((last = requestedName.lastIndexOf('.', offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
cp = pc.get(requestedName);
if (cp != null) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
index 41e648afb..3d961b80d 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
@@ -1574,7 +1574,7 @@ public interface Constants {
String SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
/**
- * Service property identifying the intents that this service implement.
+ * Service property identifying the intents that this service implements.
* This property has a dual purpose:
* <ul>
* <li>A bundle can use this service property to notify the distribution
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java
index 8003880aa..85575dfce 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2005, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2018). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,30 @@
package org.osgi.framework;
+import static java.lang.invoke.MethodHandles.publicLookup;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.AbstractMap;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.ServiceLoader;
+import java.util.Set;
+
import javax.security.auth.x500.X500Principal;
import org.eclipse.osgi.internal.framework.FilterImpl;
-import org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper;
+import org.osgi.framework.connect.FrameworkUtilHelper;
/**
* Framework Utility class.
@@ -185,26 +199,6 @@ public class FrameworkUtil {
return DNChainMatching.match(matchPattern, dnChain);
}
- private final static List<FrameworkUtilHelper> helpers;
- static {
- List<FrameworkUtilHelper> l = new ArrayList<>();
- try {
- ServiceLoader<FrameworkUtilHelper> helperLoader = AccessController.doPrivileged(new PrivilegedAction<ServiceLoader<FrameworkUtilHelper>>() {
- @Override
- public ServiceLoader<FrameworkUtilHelper> run() {
- return ServiceLoader.load(FrameworkUtilHelper.class, FrameworkUtilHelper.class.getClassLoader());
- }
- });
- for (Iterator<FrameworkUtilHelper> iHelpers = helperLoader.iterator(); iHelpers.hasNext();) {
- l.add(iHelpers.next());
- }
- } catch (Throwable t) {
- // should not fail out of static initializers
- t.printStackTrace();
- }
- helpers = Collections.unmodifiableList(l);
- }
-
/**
* Return a {@code Bundle} for the specified bundle class. The returned
* {@code Bundle} is the bundle associated with the bundle class loader
@@ -218,12 +212,9 @@ public class FrameworkUtil {
public static Bundle getBundle(final Class<?> classFromBundle) {
// We use doPriv since the caller may not have permission
// to call getClassLoader.
- Object cl = AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- return classFromBundle.getClassLoader();
- }
- });
+ ClassLoader cl = AccessController
+ .doPrivileged( (PrivilegedAction<ClassLoader>)
+ () -> classFromBundle.getClassLoader());
if (cl instanceof BundleReference) {
return ((BundleReference) cl).getBundle();
@@ -238,6 +229,29 @@ public class FrameworkUtil {
return null;
}
+ private final static List<FrameworkUtilHelper> helpers;
+ static {
+ List<FrameworkUtilHelper> l = new ArrayList<>();
+ try {
+ ServiceLoader<FrameworkUtilHelper> helperLoader = AccessController
+ .doPrivileged(
+ (PrivilegedAction<ServiceLoader<FrameworkUtilHelper>>) () -> ServiceLoader
+ .load(FrameworkUtilHelper.class,
+ FrameworkUtilHelper.class.getClassLoader()));
+
+ helperLoader.forEach((h) -> l.add(h));
+ } catch (Throwable error) {
+ // try hard not to fail static <clinit>
+ try {
+ Thread t = Thread.currentThread();
+ t.getUncaughtExceptionHandler().uncaughtException(t, error);
+ } catch (Throwable ignored) {
+ // we ignore this
+ }
+ }
+ helpers = Collections.unmodifiableList(l);
+ }
+
/**
* This class contains a method to match a distinguished name (DN) chain
* against and DN chain pattern.
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java
index 264ccd683..2936b490d 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java
@@ -713,7 +713,7 @@ final class PackagePermissionCollection extends PermissionCollection {
/* work our way up the tree... */
int last;
int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+ while ((last = requestedName.lastIndexOf('.', offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
pp = pc.get(requestedName);
if (pp != null) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java
index 8db61d0b1..d8ab61f5f 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java
@@ -866,7 +866,7 @@ final class ServicePermissionCollection extends PermissionCollection {
// work our way up the tree...
int last;
int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+ while ((last = requestedName.lastIndexOf('.', offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
sp = pc.get(requestedName);
if (sp != null) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectContent.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectContent.java
new file mode 100644
index 000000000..29004a988
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectContent.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) OSGi Alliance (2019). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.framework.connect;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Optional;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.wiring.BundleRevisions;
+
+/**
+ * A connect content provides a {@link Framework framework} access to the
+ * content of a connect {@link ConnectModule module}. A framework may
+ * {@link #open() open} and {@link #close() close} the content for a connect
+ * module multiple times while the connect content is in use by the framework
+ * instance. The framework must close the connect content once the connect
+ * content is no longer used as the content of a current bundle revision or an
+ * in use bundle revision.
+ *
+ * @see BundleRevisions
+ * @ThreadSafe
+ * @author $Id$
+ */
+public interface ConnectContent {
+ /**
+ * Returns this connect content Manifest headers and values. The
+ * {@link Optional#empty() empty} value is returned if the framework should
+ * handle parsing the Manifest of the content itself.
+ *
+ * @return This connect content Manifest headers and values.
+ * @throws IllegalStateException if the connect content has been closed
+ */
+ Optional<Map<String,String>> getHeaders();
+
+ /**
+ * Returns an iterable with all the entry names available in this
+ * ConnectContent
+ *
+ * @return the entry names
+ * @throws IOException if an error occurs reading the ConnectContent
+ * @throws IllegalStateException if the connect content has been closed
+ */
+ Iterable<String> getEntries() throws IOException;
+
+ /**
+ * Returns the connect entry for the specified name. The
+ * {@link Optional#empty() empty} value is returned if an entry with the
+ * specified name does not exist.
+ *
+ * @param name the name of the entry
+ * @return the connect entry, or {@link Optional#empty() empty} if not
+ * found.
+ * @throws IllegalStateException if the connect content has been closed
+ */
+ Optional<ConnectEntry> getEntry(String name);
+
+ /**
+ * Returns a class loader for this connect content. The
+ * {@link Optional#empty() empty} value is returned if the framework should
+ * handle creating a class loader for the bundle revision associated with
+ * this connect content.
+ * <p>
+ * This method is called by the framework for {@link Bundle#RESOLVED
+ * resolved} bundles only and will be called at most once while a bundle is
+ * resolved. If a bundle associated with a connect module is refreshed and
+ * resolved again the framework will ask the content for the class loader
+ * again. This allows for a connect content to reuse or create a new class
+ * loader each time the bundle revision is resolved.
+ *
+ * @return a class loader for the module.
+ */
+ Optional<ClassLoader> getClassLoader();
+
+ /**
+ * Opens this connect content. The framework will open the content when it
+ * needs to access the content for a bundle revision associated with the
+ * connect content. The framework may lazily open the content until the
+ * first request is made to access the bundle revision content.
+ *
+ * @throws IOException if an error occurred opening the content
+ */
+ void open() throws IOException;
+
+ /**
+ * Closes this connect content.
+ *
+ * @throws IOException if an error occurred closing the connect content
+ */
+ void close() throws IOException;
+
+ /**
+ * Represents the entry of a connect module
+ */
+ public interface ConnectEntry {
+ /**
+ * Returns the name of the entry
+ *
+ * @return the name of the entry
+ */
+ String getName();
+
+ /**
+ * Returns the size of the entry. The value {@code -1} is returned if
+ * the content length is not known.
+ *
+ * @return the size of the entry, or {@code -1} if the content length is
+ * not known.
+ */
+ public long getContentLength();
+
+ /**
+ * Returns the last modification time of the entry
+ *
+ * @return the last modification time of the entry
+ */
+ public long getLastModified();
+
+ /**
+ * Returns the content of the entry as a byte array.
+ *
+ * @return the content bytes
+ * @throws IOException if an error occurs reading the content
+ */
+ default byte[] getBytes() throws IOException {
+ long longLength = getContentLength();
+ if (longLength > Integer.MAX_VALUE - 8) {
+ throw new IOException(
+ "Entry is to big to fit into a byte[]: " + getName());
+ }
+
+ try (InputStream in = getInputStream()) {
+ int length = (int) longLength;
+ if (length > 0) {
+ int bytesread = 0;
+ byte[] result = new byte[length];
+ int readcount = 0;
+ while (bytesread < length) {
+ readcount = in.read(result, bytesread,
+ length - bytesread);
+ bytesread += readcount;
+ if (readcount <= 0) {
+ break;
+ }
+ }
+ return result;
+ } else {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ int nRead;
+ byte[] data = new byte[1024];
+ while ((nRead = in.read(data, 0, data.length)) > 0) {
+ buffer.write(data, 0, nRead);
+ }
+ buffer.flush();
+ return buffer.toByteArray();
+ }
+ }
+ }
+
+ /**
+ * Returns the content of the entry as an input stream.
+ *
+ * @return the content input stream
+ * @throws IOException if an error occurs reading the content
+ */
+ InputStream getInputStream() throws IOException;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectFactory.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectFactory.java
new file mode 100644
index 000000000..31e1a83a2
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectFactory.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) OSGi Alliance (2019). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.framework.connect;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Optional;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.Constants;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
+
+/**
+ * A connect factory creates instances of {@link ConnectModule} that are used by
+ * a {@link Framework} instance to provide content and classes for a bundle
+ * installed in the Framework. A connect factory is provided when
+ * {@link FrameworkFactory#newFramework(java.util.Map) creating} a framework
+ * instance. Because a connect factory instance can participate in the
+ * initialization of the framework and the lifecycle of a framework instance the
+ * connect factory instance should only be used with a single framework
+ * instance.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+public interface ConnectFactory {
+
+ /**
+ * Initializes the connect factory with the
+ * {@link Constants#FRAMEWORK_STORAGE framework persistent storage} file and
+ * framework properties configured for a {@link Framework} instance. This
+ * method is called once by a {@link Framework} instance and is called
+ * before any other methods on this factory are called.
+ *
+ * @param configuration The framework properties to used configure the new
+ * framework instance. An unmodifiable map of framework
+ * configuration properties that were used to create a new
+ * framework instance.
+ * @param storage the persistent storage area used by the {@link Framework}
+ * or {@code null} if the if the platform does not have file
+ * system support.
+ */
+ void initialize(File storage, Map<String,String> configuration);
+
+ /**
+ * Returns the connect module for the specified bundle location. If an
+ * {@link Optional#empty() empty} optional is returned the the framework
+ * must handle reading the content of the bundle itself. If a value is
+ * {@link Optional#isPresent() present} in the returned optional then the
+ * {@link Optional#get() value} from the optional must be used to access the
+ * content of the bundle.
+ *
+ * @param location the bundle location used to install a bundle
+ * @return the connect module for the specified bundle location
+ * @throws IllegalStateException if the location cannot be handled
+ */
+ Optional<ConnectModule> getModule(String location);
+
+ /**
+ * Creates a new activator for this factory. A new activator is created by
+ * the framework each time the framework is {@link Framework#init()
+ * initialized}. An activator allows the factory to participate in the
+ * framework lifecyle. When the framework is {@link Framework#init()
+ * initialized} the activator
+ * {@link BundleActivator#start(org.osgi.framework.BundleContext) start}
+ * method is called. When the framework is {@link Framework#stop() stopped}
+ * the activator
+ * {@link BundleActivator#stop(org.osgi.framework.BundleContext) stop}
+ * method is called
+ *
+ * @return a new activator for this factory or {@link Optional#empty()
+ * empty} if no activator is available for the factory
+ */
+ Optional<BundleActivator> createBundleActivator();
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectModule.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectModule.java
new file mode 100644
index 000000000..a1e768e76
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectModule.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) OSGi Alliance (2019). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.framework.connect;
+
+import java.io.IOException;
+
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * A connect module instance is used by a {@link Framework framework} to load
+ * content for a bundle revision installed in the framework.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+public interface ConnectModule {
+ /**
+ * Returns the current content of this connect module. The framework will
+ * get the content when it needs to access the content for the current
+ * {@link BundleRevision bundle revision} associated with this connect
+ * module. The framework may lazily open the content until the first request
+ * is made to access the bundle content.
+ *
+ * @return the current content of this connect module
+ * @throws IOException if an error occurred getting the content
+ */
+ ConnectContent getContent() throws IOException;
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java
new file mode 100644
index 000000000..8c8da1842
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) OSGi Alliance (2019). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.connect;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * A helper for the {@link FrameworkUtil} class. This helper provides
+ * alternative implementations for methods on {@link FrameworkUtil}.
+ */
+public interface FrameworkUtilHelper {
+ /**
+ * Return a {@code Bundle} associated with the specified class.
+ * <p>
+ * This helper method is called by
+ * {@link FrameworkUtil#getBundle(Class)} if the standard implementation
+ * of {@code FrameworkUtil} cannot find the bundle.
+ *
+ * @param classFromBundle A class associated with a bundle
+ * @return A {@code Bundle} for the specified class or {@code null} if
+ * the specified class is not from a bundle.
+ */
+ default Bundle getBundle(Class< ? > classFromBundle) {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/package-info.java
new file mode 100644
index 000000000..de6a85ca4
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/package-info.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Connect Package Version 1.0.
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.framework; version="[1.0,2.0)"}
+ *
+ * @author $Id$
+ */
+
+@Version("1.0")
+package org.osgi.framework.connect;
+
+import org.osgi.annotation.versioning.Version;
+
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java
index c1647bcb8..eb28dcaad 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java
@@ -17,8 +17,10 @@
package org.osgi.framework.launch;
import java.util.Map;
+
import org.osgi.annotation.versioning.ProviderType;
import org.osgi.framework.Bundle;
+import org.osgi.framework.connect.ConnectFactory;
/**
* A factory for creating {@link Framework} instances.
@@ -70,4 +72,33 @@ public interface FrameworkFactory {
* permissions.
*/
Framework newFramework(Map<String, String> configuration);
+
+ /**
+ * Create a new {@link Framework} instance using the specified
+ * {@link ConnectFactory connect factory}.
+ *
+ * @param configuration The framework properties to configure the new
+ * framework instance. If framework properties are not provided
+ * by the configuration argument, the created framework instance
+ * must use some reasonable default configuration appropriate for
+ * the current VM. For example, the system packages for the
+ * current execution environment should be properly exported. The
+ * specified configuration argument may be {@code null}. The
+ * created framework instance must copy any information needed
+ * from the specified configuration argument since the
+ * configuration argument can be changed after the framework
+ * instance has been created.
+ * @param connectFactory The connect factory that the new framework instance
+ * will use. The specified connect factory argument may be
+ * {@code null}.
+ * @return A new, configured {@link Framework} instance. The framework
+ * instance must be in the {@link Bundle#INSTALLED} state.
+ * @throws SecurityException If the caller does not have
+ * {@code AllPermission}, and the Java Runtime Environment
+ * supports permissions.
+ * @see ConnectFactory
+ * @since 1.3
+ */
+ Framework newFramework(Map<String,String> configuration,
+ ConnectFactory connectFactory);
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java
index db5e926ca..b4e9d8e0e 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java
@@ -29,7 +29,7 @@
* @author $Id$
*/
-@Version("1.2")
+@Version("1.3")
package org.osgi.framework.launch;
import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java
index 9f789ca25..05e5d1482 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2012, 2014). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2012, 2018). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,13 +54,13 @@ import org.osgi.resource.Namespace;
* </ul>
*
* <p>
- * A non-fragment resource with the with the
- * {@link IdentityNamespace#TYPE_BUNDLE osgi.bundle} type
- * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} provides zero or
- * one<sup>&#8224;</sup> host capabilities. A fragment resource with the
- * {@link IdentityNamespace#TYPE_FRAGMENT osgi.fragment} type
- * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} must not declare
- * a host capability and must declare exactly one host requirement.
+ * A non-fragment resource with the {@link IdentityNamespace#TYPE_BUNDLE
+ * osgi.bundle} type {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE
+ * identity} provides zero or one<sup>&#8224;</sup> host capabilities. A
+ * fragment resource with the {@link IdentityNamespace#TYPE_FRAGMENT
+ * osgi.fragment} type {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE
+ * identity} must not declare a host capability and must declare exactly one
+ * host requirement.
* <p>
* &#8224; A resource with no bundle symbolic name must not provide a host
* capability.
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java
index 818d4aed9..4dd0ea2d3 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java
@@ -15,19 +15,19 @@
*/
/**
- * Framework Package Version 1.9.
+ * Framework Package Version 1.10.
* <p>
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest.
* <p>
* Example import for consumers using the API in this package:
* <p>
- * {@code Import-Package: org.osgi.framework; version="[1.9,2.0)"}
+ * {@code Import-Package: org.osgi.framework; version="[1.10,2.0)"}
*
* @author $Id$
*/
-@Version("1.9")
+@Version("1.10")
package org.osgi.framework;
import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi/pom.xml b/bundles/org.eclipse.osgi/pom.xml
index 4e05da0d9..020e722bb 100644
--- a/bundles/org.eclipse.osgi/pom.xml
+++ b/bundles/org.eclipse.osgi/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
- <version>3.15.100-SNAPSHOT</version>
+ <version>3.16.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>

Back to the top