diff options
| author | Thomas Watson | 2019-07-03 13:06:44 +0000 |
|---|---|---|
| committer | Thomas Watson | 2019-10-30 16:49:50 +0000 |
| commit | fb6258ed257d3b1263c7c7e340b44a5102b52b79 (patch) | |
| tree | 5f8bd95086baa02d6de1d512ec15c442bf555b67 | |
| parent | 8706b4088137e0949adeb3fbd527167a9aea266f (diff) | |
| download | rt.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>
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<String,String>, 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<String,String>, 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<String,String>, ConnectFactory)"/> + </message_arguments> + </filter> + <filter comment="Not for OSGi packages" id="1211105284"> + <message_arguments> + <message_argument value="newFramework(Map<String,String>, 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>†</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>†</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> * † 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> |
