From 03d4817df48f3857799ec0ec3439790e2c425bec Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Mon, 11 Dec 2017 08:05:15 -0600 Subject: Bug 528422 - [osgi R7] Support for Multi-Release jars Change-Id: Iab950e54caa6fffb3c995694c0d7762111a846a3 Signed-off-by: Thomas Watson --- bundles/org.eclipse.osgi.tests/.classpath | 1 + bundles/org.eclipse.osgi.tests/build.properties | 5 +- .../mrBundleInputBase/META-INF/MANIFEST.MF | 6 + .../mrBundleInputBase/manifests/manifest10.mf | 2 + .../mrBundleInputBase/manifests/manifest11.mf | 2 + .../mrBundleInputBase/manifests/manifest8.mf | 2 + .../mrBundleInputBase/manifests/manifest9.mf | 2 + .../multi/release/test/TestClass10.java | 17 + .../multi/release/test/TestClass11.java | 17 + .../multi/release/test/TestClass8.java | 17 + .../multi/release/test/TestClass9.java | 17 + .../multi/release/test/TestClassAdd10.java | 17 + .../multi/release/test/TestClassAdd11.java | 17 + .../multi/release/test/TestClassAdd8.java | 17 + .../multi/release/test/TestClassAdd9.java | 17 + .../multi/release/test/TestClassBase.java | 24 + .../multi/release/test/sub/TestClass10.java | 17 + .../multi/release/test/sub/TestClass11.java | 17 + .../multi/release/test/sub/TestClass8.java | 17 + .../multi/release/test/sub/TestClass9.java | 17 + .../multi/release/test/sub/TestClassAdd10.java | 17 + .../multi/release/test/sub/TestClassAdd11.java | 17 + .../multi/release/test/sub/TestClassAdd8.java | 17 + .../multi/release/test/sub/TestClassAdd9.java | 17 + .../multi/release/test/sub/TestClassBase.java | 17 + .../multi/release/test/sub/testResource10.txt | 1 + .../multi/release/test/sub/testResource11.txt | 1 + .../multi/release/test/sub/testResource8.txt | 1 + .../multi/release/test/sub/testResource9.txt | 1 + .../multi/release/test/sub/testResourceAdd10.txt | 1 + .../multi/release/test/sub/testResourceAdd11.txt | 1 + .../multi/release/test/sub/testResourceAdd8.txt | 1 + .../multi/release/test/sub/testResourceAdd9.txt | 1 + .../multi/release/test/sub/testResourceBase.txt | 1 + .../multi/release/test/sub2/TestClass10.java | 17 + .../multi/release/test/sub2/TestClass11.java | 17 + .../multi/release/test/sub2/TestClass8.java | 17 + .../multi/release/test/sub2/TestClass9.java | 17 + .../multi/release/test/sub2/TestClassAdd10.java | 17 + .../multi/release/test/sub2/TestClassAdd11.java | 17 + .../multi/release/test/sub2/TestClassAdd8.java | 17 + .../multi/release/test/sub2/TestClassAdd9.java | 17 + .../multi/release/test/sub2/TestClassBase.java | 17 + .../multi/release/test/sub2/testResource10.txt | 1 + .../multi/release/test/sub2/testResource11.txt | 1 + .../multi/release/test/sub2/testResource8.txt | 1 + .../multi/release/test/sub2/testResource9.txt | 1 + .../multi/release/test/sub2/testResourceAdd10.txt | 1 + .../multi/release/test/sub2/testResourceAdd11.txt | 1 + .../multi/release/test/sub2/testResourceAdd8.txt | 1 + .../multi/release/test/sub2/testResourceAdd9.txt | 1 + .../multi/release/test/sub2/testResourceBase.txt | 1 + .../multi/release/test/testResource10.txt | 1 + .../multi/release/test/testResource11.txt | 1 + .../multi/release/test/testResource8.txt | 1 + .../multi/release/test/testResource9.txt | 1 + .../multi/release/test/testResourceAdd10.txt | 1 + .../multi/release/test/testResourceAdd11.txt | 1 + .../multi/release/test/testResourceAdd8.txt | 1 + .../multi/release/test/testResourceAdd9.txt | 1 + .../multi/release/test/testResourceBase.txt | 1 + .../eclipse/osgi/tests/bundles/BundleTests.java | 3 +- .../osgi/tests/bundles/MultiReleaseJarTests.java | 832 +++++++++++++++++++++ .../internal/loader/classpath/ClasspathEntry.java | 96 ++- .../loader/classpath/ClasspathManager.java | 119 ++- .../loader/classpath/FragmentClasspath.java | 4 +- .../src/org/eclipse/osgi/storage/BundleInfo.java | 40 +- .../src/org/eclipse/osgi/storage/Storage.java | 95 ++- 68 files changed, 1600 insertions(+), 102 deletions(-) create mode 100755 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/META-INF/MANIFEST.MF create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest10.mf create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest11.mf create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest8.mf create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest9.mf create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass10.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass11.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass8.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass9.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd10.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd11.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd8.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd9.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassBase.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass10.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass11.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass8.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass9.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd10.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd11.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd8.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd9.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassBase.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource10.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource11.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource8.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource9.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd10.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd11.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd8.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd9.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceBase.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass10.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass11.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass8.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass9.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd10.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd11.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd8.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd9.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassBase.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource10.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource11.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource8.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource9.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd10.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd11.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd8.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd9.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceBase.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource10.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource11.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource8.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource9.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd10.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd11.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd8.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd9.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceBase.txt create mode 100644 bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/MultiReleaseJarTests.java diff --git a/bundles/org.eclipse.osgi.tests/.classpath b/bundles/org.eclipse.osgi.tests/.classpath index 5e0b83342..5c88c4282 100644 --- a/bundles/org.eclipse.osgi.tests/.classpath +++ b/bundles/org.eclipse.osgi.tests/.classpath @@ -128,5 +128,6 @@ + diff --git a/bundles/org.eclipse.osgi.tests/build.properties b/bundles/org.eclipse.osgi.tests/build.properties index a98d02072..d9b008e35 100644 --- a/bundles/org.eclipse.osgi.tests/build.properties +++ b/bundles/org.eclipse.osgi.tests/build.properties @@ -274,6 +274,8 @@ source.bundle_tests/test.bug490902.b.jar = bundles_src/test.bug490902.b/ manifest.bundle_tests/test.bug490902.b.jar = META-INF/MANIFEST.MF source.bundle_tests/test.bug490902.a.jar = bundles_src/test.bug490902.a/ manifest.bundle_tests/test.bug490902.a.jar = META-INF/MANIFEST.MF +source.bundle_tests/mrBundleInputBase.jar = bundles_src/mrBundleInputBase/ +manifest.bundle_tests/mrBundleInputBase.jar = META-INF/MANIFEST.MF jars.compile.order = bundle_tests/ext.framework.b.jar,\ .,\ @@ -407,4 +409,5 @@ jars.compile.order = bundle_tests/ext.framework.b.jar,\ bundle_tests/test.bug471551.jar,\ bundle_tests/test.dynamicimport.jar,\ bundle_tests/test.bug490902.b.jar,\ - bundle_tests/test.bug490902.a.jar + bundle_tests/test.bug490902.a.jar,\ + bundle_tests/mrBundleInputBase.jar \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/META-INF/MANIFEST.MF new file mode 100755 index 000000000..5f1515730 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/META-INF/MANIFEST.MF @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: mrBundleInputBase +Bundle-SymbolicName: mrBundleInputBase +Bundle-Version: 1.0.0 +Multi-Release: true diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest10.mf b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest10.mf new file mode 100644 index 000000000..743fa42be --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest10.mf @@ -0,0 +1,2 @@ +Import-Package: pkg10 +Require-Capability: cap10 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest11.mf b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest11.mf new file mode 100644 index 000000000..5353b7a57 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest11.mf @@ -0,0 +1,2 @@ +Import-Package: pkg11 +Require-Capability: cap11 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest8.mf b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest8.mf new file mode 100644 index 000000000..ac571d856 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest8.mf @@ -0,0 +1,2 @@ +Import-Package: pkg8 +Require-Capability: cap8 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest9.mf b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest9.mf new file mode 100644 index 000000000..e7b1cebc4 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/manifests/manifest9.mf @@ -0,0 +1,2 @@ +Import-Package: pkg9 +Require-Capability: cap9 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass10.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass10.java new file mode 100644 index 000000000..90b8b01bb --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass10.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +public class TestClass10 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass11.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass11.java new file mode 100644 index 000000000..cd818b966 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass11.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +public class TestClass11 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass8.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass8.java new file mode 100644 index 000000000..929264e0f --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass8.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +public class TestClass8 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass9.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass9.java new file mode 100644 index 000000000..ea3a8164d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClass9.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +public class TestClass9 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd10.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd10.java new file mode 100644 index 000000000..f8abd8e42 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd10.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +public class TestClassAdd10 { + public String toString() { + return "ADD10"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd11.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd11.java new file mode 100644 index 000000000..45e663eff --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd11.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +public class TestClassAdd11 { + public String toString() { + return "ADD11"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd8.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd8.java new file mode 100644 index 000000000..401f99d70 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd8.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +public class TestClassAdd8 { + public String toString() { + return "ADD08"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd9.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd9.java new file mode 100644 index 000000000..1138b2145 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassAdd9.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +public class TestClassAdd9 { + public String toString() { + return "ADD09"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassBase.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassBase.java new file mode 100644 index 000000000..ae81196ef --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestClassBase.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test; + +import java.net.MalformedURLException; +import java.net.URL; + +public class TestClassBase { + public String toString() { + return "BASEXX"; + } + + public static URL createURL(String spec) throws MalformedURLException { + return new URL(spec); + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass10.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass10.java new file mode 100644 index 000000000..cd8b890ed --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass10.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClass10 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass11.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass11.java new file mode 100644 index 000000000..e21a397e7 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass11.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClass11 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass8.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass8.java new file mode 100644 index 000000000..684afec5e --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass8.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClass8 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass9.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass9.java new file mode 100644 index 000000000..ac31b67e4 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClass9.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClass9 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd10.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd10.java new file mode 100644 index 000000000..3f81af7f3 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd10.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClassAdd10 { + public String toString() { + return "ADD10"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd11.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd11.java new file mode 100644 index 000000000..4e2a68754 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd11.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClassAdd11 { + public String toString() { + return "ADD11"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd8.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd8.java new file mode 100644 index 000000000..f8f3ce160 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd8.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClassAdd8 { + public String toString() { + return "ADD08"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd9.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd9.java new file mode 100644 index 000000000..6c74bf43c --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassAdd9.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClassAdd9 { + public String toString() { + return "ADD09"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassBase.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassBase.java new file mode 100644 index 000000000..afaa6328d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/TestClassBase.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub; + +public class TestClassBase { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource10.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource10.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource10.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource11.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource11.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource11.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource8.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource8.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource8.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource9.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource9.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResource9.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd10.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd10.txt new file mode 100644 index 000000000..3600634a5 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd10.txt @@ -0,0 +1 @@ +ADD 10 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd11.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd11.txt new file mode 100644 index 000000000..269dd9189 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd11.txt @@ -0,0 +1 @@ +ADD 11 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd8.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd8.txt new file mode 100644 index 000000000..0c66921b8 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd8.txt @@ -0,0 +1 @@ +ADD 08 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd9.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd9.txt new file mode 100644 index 000000000..c8b8c30a4 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceAdd9.txt @@ -0,0 +1 @@ +ADD 09 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceBase.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceBase.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub/testResourceBase.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass10.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass10.java new file mode 100644 index 000000000..c108724f5 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass10.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClass10 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass11.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass11.java new file mode 100644 index 000000000..c5caa2615 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass11.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClass11 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass8.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass8.java new file mode 100644 index 000000000..472d75004 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass8.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClass8 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass9.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass9.java new file mode 100644 index 000000000..8024a4b33 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClass9.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClass9 { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd10.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd10.java new file mode 100644 index 000000000..1a0562e72 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd10.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClassAdd10 { + public String toString() { + return "ADD10"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd11.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd11.java new file mode 100644 index 000000000..d8de1b1ec --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd11.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClassAdd11 { + public String toString() { + return "ADD11"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd8.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd8.java new file mode 100644 index 000000000..f0e0bfe55 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd8.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClassAdd8 { + public String toString() { + return "ADD08"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd9.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd9.java new file mode 100644 index 000000000..5e9c46688 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassAdd9.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClassAdd9 { + public String toString() { + return "ADD09"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassBase.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassBase.java new file mode 100644 index 000000000..5dfc4588e --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/TestClassBase.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package multi.release.test.sub2; + +public class TestClassBase { + public String toString() { + return "BASEXX"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource10.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource10.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource10.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource11.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource11.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource11.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource8.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource8.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource8.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource9.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource9.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResource9.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd10.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd10.txt new file mode 100644 index 000000000..3600634a5 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd10.txt @@ -0,0 +1 @@ +ADD 10 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd11.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd11.txt new file mode 100644 index 000000000..269dd9189 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd11.txt @@ -0,0 +1 @@ +ADD 11 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd8.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd8.txt new file mode 100644 index 000000000..0c66921b8 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd8.txt @@ -0,0 +1 @@ +ADD 08 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd9.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd9.txt new file mode 100644 index 000000000..c8b8c30a4 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceAdd9.txt @@ -0,0 +1 @@ +ADD 09 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceBase.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceBase.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/sub2/testResourceBase.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource10.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource10.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource10.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource11.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource11.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource11.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource8.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource8.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource8.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource9.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource9.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResource9.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd10.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd10.txt new file mode 100644 index 000000000..3600634a5 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd10.txt @@ -0,0 +1 @@ +ADD 10 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd11.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd11.txt new file mode 100644 index 000000000..269dd9189 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd11.txt @@ -0,0 +1 @@ +ADD 11 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd8.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd8.txt new file mode 100644 index 000000000..0c66921b8 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd8.txt @@ -0,0 +1 @@ +ADD 08 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd9.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd9.txt new file mode 100644 index 000000000..c8b8c30a4 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceAdd9.txt @@ -0,0 +1 @@ +ADD 09 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceBase.txt b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceBase.txt new file mode 100644 index 000000000..3e7350e3d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/testResourceBase.txt @@ -0,0 +1 @@ +RESOURCE XX \ No newline at end of file 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 01fb4ffe3..d1f5ada35 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. + * Copyright (c) 2006, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,6 +16,7 @@ import junit.framework.TestSuite; public class BundleTests { public static Test suite() { TestSuite suite = new TestSuite(BundleTests.class.getName()); + suite.addTest(MultiReleaseJarTests.suite()); suite.addTest(URLHandlerTests.suite()); suite.addTest(PersistedBundleTests.suite()); suite.addTest(CascadeConfigTests.suite()); diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/MultiReleaseJarTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/MultiReleaseJarTests.java new file mode 100644 index 000000000..5d9e8f82a --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/MultiReleaseJarTests.java @@ -0,0 +1,832 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.osgi.tests.bundles; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.eclipse.osgi.launch.Equinox; +import org.eclipse.osgi.storage.StorageUtil; +import org.eclipse.osgi.tests.OSGiTestsActivator; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.Constants; +import org.osgi.framework.namespace.PackageNamespace; +import org.osgi.framework.wiring.BundleRequirement; +import org.osgi.framework.wiring.BundleRevision; +import org.osgi.framework.wiring.BundleWire; +import org.osgi.framework.wiring.BundleWiring; +import org.osgi.resource.Namespace; + +public class MultiReleaseJarTests extends AbstractBundleTests { + + private final static String RNF = "RNF"; + private final static String CNFE = "CNFE"; + + public static Test suite() { + return new TestSuite(MultiReleaseJarTests.class); + } + + private File mrJarBundle; + private String originalSpecVersion; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mrJarBundle = createMRJarBundle(); + originalSpecVersion = System.getProperty("java.specification.version"); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + System.setProperty("java.specification.version", originalSpecVersion); + } + + private static File createMRJarBundle() throws BundleException, IOException { + BundleContext bc = OSGiTestsActivator.getContext(); + File mrJarBundle = bc.getDataFile("mrJarBundleTest.jar"); + if (mrJarBundle.exists()) { + return mrJarBundle; + } + File classpathMrJar = bc.getDataFile("classpathMrJar.jar"); + + Bundle base = installer.installBundle("mrBundleInputBase"); + + Map bundleHeaders = new LinkedHashMap(); + bundleHeaders.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + bundleHeaders.put(Constants.BUNDLE_SYMBOLICNAME, "mrBundle"); + bundleHeaders.put(Constants.BUNDLE_VERSION, "1.0.0"); + bundleHeaders.put(Constants.IMPORT_PACKAGE, "pkgbase"); + bundleHeaders.put(Constants.REQUIRE_CAPABILITY, "capbase"); + bundleHeaders.put(Constants.EXPORT_PACKAGE, "pkgbase, pkg8, pkg9, pkg10, pkg11"); + bundleHeaders.put(Constants.PROVIDE_CAPABILITY, "capbase, cap8, cap9, cap10, cap11"); + bundleHeaders.put(Constants.BUNDLE_CLASSPATH, "., " + classpathMrJar.getName() + ", classPathDir"); + + Map bundleEntries = new LinkedHashMap(); + bundleEntries.put("multi/", null); + bundleEntries.put("multi/release/", null); + bundleEntries.put("multi/release/test/", null); + bundleEntries.put("multi/release/test/TestClassBase.class", getBytes("multi/release/test/TestClassBase.class", base)); + bundleEntries.put("multi/release/test/TestClass8.class", getBytes("multi/release/test/TestClass8.class", base)); + bundleEntries.put("multi/release/test/TestClass9.class", getBytes("multi/release/test/TestClass9.class", base)); + bundleEntries.put("multi/release/test/TestClass10.class", getBytes("multi/release/test/TestClass10.class", base)); + bundleEntries.put("multi/release/test/TestClass11.class", getBytes("multi/release/test/TestClass11.class", base)); + bundleEntries.put("multi/release/test/testResourceBase.txt", getBytes("multi/release/test/testResourceBase.txt", base)); + bundleEntries.put("multi/release/test/testResource8.txt", getBytes("multi/release/test/testResource8.txt", base)); + bundleEntries.put("multi/release/test/testResource9.txt", getBytes("multi/release/test/testResource9.txt", base)); + bundleEntries.put("multi/release/test/testResource10.txt", getBytes("multi/release/test/testResource10.txt", base)); + bundleEntries.put("multi/release/test/testResource11.txt", getBytes("multi/release/test/testResource11.txt", base)); + + bundleEntries.put("META-INF/versions/", null); + bundleEntries.put("META-INF/versions/8/", null); + bundleEntries.put("META-INF/versions/8/multi/", null); + bundleEntries.put("META-INF/versions/8/multi/release/", null); + bundleEntries.put("META-INF/versions/8/multi/release/test/", null); + bundleEntries.put("META-INF/versions/8/multi/release/test/TestClass8.class", getBytes("multi/release/test/TestClass8.class", base, new byte[] {'0', '8'})); + bundleEntries.put("META-INF/versions/8/multi/release/test/TestClassAdd8.class", getBytes("multi/release/test/TestClassAdd8.class", base)); + bundleEntries.put("META-INF/versions/8/multi/release/test/testResource8.txt", getBytes("multi/release/test/testResource8.txt", base, new byte[] {'0', '8'})); + bundleEntries.put("META-INF/versions/8/multi/release/test/testResourceAdd8.txt", getBytes("multi/release/test/testResourceAdd8.txt", base)); + bundleEntries.put("META-INF/versions/9/", null); + bundleEntries.put("META-INF/versions/9/multi/", null); + bundleEntries.put("META-INF/versions/9/multi/release/", null); + bundleEntries.put("META-INF/versions/9/multi/release/test/", null); + bundleEntries.put("META-INF/versions/9/multi/release/test/TestClass9.class", getBytes("multi/release/test/TestClass9.class", base, new byte[] {'0', '9'})); + bundleEntries.put("META-INF/versions/9/multi/release/test/TestClassAdd9.class", getBytes("multi/release/test/TestClassAdd9.class", base)); + bundleEntries.put("META-INF/versions/9/multi/release/test/testResource9.txt", getBytes("multi/release/test/testResource9.txt", base, new byte[] {'0', '9'})); + bundleEntries.put("META-INF/versions/9/multi/release/test/testResourceAdd9.txt", getBytes("multi/release/test/testResourceAdd9.txt", base)); + bundleEntries.put("META-INF/versions/10/", null); + bundleEntries.put("META-INF/versions/10/multi/", null); + bundleEntries.put("META-INF/versions/10/multi/release/", null); + bundleEntries.put("META-INF/versions/10/multi/release/test/", null); + bundleEntries.put("META-INF/versions/10/multi/release/test/TestClass10.class", getBytes("multi/release/test/TestClass10.class", base, new byte[] {'1', '0'})); + bundleEntries.put("META-INF/versions/10/multi/release/test/TestClassAdd10.class", getBytes("multi/release/test/TestClassAdd10.class", base)); + bundleEntries.put("META-INF/versions/10/multi/release/test/testResource10.txt", getBytes("multi/release/test/testResource10.txt", base, new byte[] {'1', '0'})); + bundleEntries.put("META-INF/versions/10/multi/release/test/testResourceAdd10.txt", getBytes("multi/release/test/testResourceAdd10.txt", base)); + bundleEntries.put("META-INF/versions/11/", null); + bundleEntries.put("META-INF/versions/11/multi/", null); + bundleEntries.put("META-INF/versions/11/multi/release/", null); + bundleEntries.put("META-INF/versions/11/multi/release/test/", null); + bundleEntries.put("META-INF/versions/11/multi/release/test/TestClass11.class", getBytes("multi/release/test/TestClass11.class", base, new byte[] {'1', '1'})); + bundleEntries.put("META-INF/versions/11/multi/release/test/TestClassAdd11.class", getBytes("multi/release/test/TestClassAdd11.class", base)); + bundleEntries.put("META-INF/versions/11/multi/release/test/testResource11.txt", getBytes("multi/release/test/testResource11.txt", base, new byte[] {'1', '1'})); + bundleEntries.put("META-INF/versions/11/multi/release/test/testResourceAdd11.txt", getBytes("multi/release/test/testResourceAdd11.txt", base)); + + bundleEntries.put("META-INF/versions/8/OSGI-INF/", null); + bundleEntries.put("META-INF/versions/8/OSGI-INF/MANIFEST.MF", getBytes("manifests/manifest8.mf", base)); + bundleEntries.put("META-INF/versions/9/OSGI-INF/", null); + bundleEntries.put("META-INF/versions/9/OSGI-INF/MANIFEST.MF", getBytes("manifests/manifest9.mf", base)); + bundleEntries.put("META-INF/versions/10/OSGI-INF/", null); + bundleEntries.put("META-INF/versions/10/OSGI-INF/MANIFEST.MF", getBytes("manifests/manifest10.mf", base)); + bundleEntries.put("META-INF/versions/11/OSGI-INF/", null); + bundleEntries.put("META-INF/versions/11/OSGI-INF/MANIFEST.MF", getBytes("manifests/manifest11.mf", base)); + + Map classPathJarEntries = new LinkedHashMap(); + classPathJarEntries.put("multi/", null); + classPathJarEntries.put("multi/release/", null); + classPathJarEntries.put("multi/release/test/", null); + classPathJarEntries.put("multi/release/test/sub/", null); + classPathJarEntries.put("multi/release/test/sub/TestClassBase.class", getBytes("multi/release/test/sub/TestClassBase.class", base)); + classPathJarEntries.put("multi/release/test/sub/TestClass8.class", getBytes("multi/release/test/sub/TestClass8.class", base)); + classPathJarEntries.put("multi/release/test/sub/TestClass9.class", getBytes("multi/release/test/sub/TestClass9.class", base)); + classPathJarEntries.put("multi/release/test/sub/TestClass10.class", getBytes("multi/release/test/sub/TestClass10.class", base)); + classPathJarEntries.put("multi/release/test/sub/TestClass11.class", getBytes("multi/release/test/sub/TestClass11.class", base)); + classPathJarEntries.put("multi/release/test/sub/testResourceBase.txt", getBytes("multi/release/test/sub/testResourceBase.txt", base)); + classPathJarEntries.put("multi/release/test/sub/testResource8.txt", getBytes("multi/release/test/sub/testResource8.txt", base)); + classPathJarEntries.put("multi/release/test/sub/testResource9.txt", getBytes("multi/release/test/sub/testResource9.txt", base)); + classPathJarEntries.put("multi/release/test/sub/testResource10.txt", getBytes("multi/release/test/sub/testResource10.txt", base)); + classPathJarEntries.put("multi/release/test/sub/testResource11.txt", getBytes("multi/release/test/sub/testResource11.txt", base)); + + classPathJarEntries.put("META-INF/versions/", null); + classPathJarEntries.put("META-INF/versions/8/", null); + classPathJarEntries.put("META-INF/versions/8/multi/", null); + classPathJarEntries.put("META-INF/versions/8/multi/release/", null); + classPathJarEntries.put("META-INF/versions/8/multi/release/test/", null); + classPathJarEntries.put("META-INF/versions/8/multi/release/test/sub/", null); + classPathJarEntries.put("META-INF/versions/8/multi/release/test/sub/TestClass8.class", getBytes("multi/release/test/sub/TestClass8.class", base, new byte[] {'0', '8'})); + classPathJarEntries.put("META-INF/versions/8/multi/release/test/sub/TestClassAdd8.class", getBytes("multi/release/test/sub/TestClassAdd8.class", base)); + classPathJarEntries.put("META-INF/versions/8/multi/release/test/sub/testResource8.txt", getBytes("multi/release/test/sub/testResource8.txt", base, new byte[] {'0', '8'})); + classPathJarEntries.put("META-INF/versions/8/multi/release/test/sub/testResourceAdd8.txt", getBytes("multi/release/test/sub/testResourceAdd8.txt", base)); + + classPathJarEntries.put("META-INF/versions/9/", null); + classPathJarEntries.put("META-INF/versions/9/multi/", null); + classPathJarEntries.put("META-INF/versions/9/multi/release/", null); + classPathJarEntries.put("META-INF/versions/9/multi/release/test/", null); + classPathJarEntries.put("META-INF/versions/9/multi/release/test/sub/", null); + classPathJarEntries.put("META-INF/versions/9/multi/release/test/sub/TestClass9.class", getBytes("multi/release/test/sub/TestClass9.class", base, new byte[] {'0', '9'})); + classPathJarEntries.put("META-INF/versions/9/multi/release/test/sub/TestClassAdd9.class", getBytes("multi/release/test/sub/TestClassAdd9.class", base)); + classPathJarEntries.put("META-INF/versions/9/multi/release/test/sub/testResource9.txt", getBytes("multi/release/test/sub/testResource9.txt", base, new byte[] {'0', '9'})); + classPathJarEntries.put("META-INF/versions/9/multi/release/test/sub/testResourceAdd9.txt", getBytes("multi/release/test/sub/testResourceAdd9.txt", base)); + + classPathJarEntries.put("META-INF/versions/10/", null); + classPathJarEntries.put("META-INF/versions/10/multi/", null); + classPathJarEntries.put("META-INF/versions/10/multi/release/", null); + classPathJarEntries.put("META-INF/versions/10/multi/release/test/", null); + classPathJarEntries.put("META-INF/versions/10/multi/release/test/sub/", null); + classPathJarEntries.put("META-INF/versions/10/multi/release/test/sub/TestClass10.class", getBytes("multi/release/test/sub/TestClass10.class", base, new byte[] {'1', '0'})); + classPathJarEntries.put("META-INF/versions/10/multi/release/test/sub/TestClassAdd10.class", getBytes("multi/release/test/sub/TestClassAdd10.class", base)); + classPathJarEntries.put("META-INF/versions/10/multi/release/test/sub/testResource10.txt", getBytes("multi/release/test/sub/testResource10.txt", base, new byte[] {'1', '0'})); + classPathJarEntries.put("META-INF/versions/10/multi/release/test/sub/testResourceAdd10.txt", getBytes("multi/release/test/sub/testResourceAdd10.txt", base)); + + classPathJarEntries.put("META-INF/versions/11/", null); + classPathJarEntries.put("META-INF/versions/11/multi/", null); + classPathJarEntries.put("META-INF/versions/11/multi/release/", null); + classPathJarEntries.put("META-INF/versions/11/multi/release/test/", null); + classPathJarEntries.put("META-INF/versions/11/multi/release/test/sub/", null); + classPathJarEntries.put("META-INF/versions/11/multi/release/test/sub/TestClass11.class", getBytes("multi/release/test/sub/TestClass11.class", base, new byte[] {'1', '1'})); + classPathJarEntries.put("META-INF/versions/11/multi/release/test/sub/TestClassAdd11.class", getBytes("multi/release/test/sub/TestClassAdd11.class", base)); + classPathJarEntries.put("META-INF/versions/11/multi/release/test/sub/testResource11.txt", getBytes("multi/release/test/sub/testResource11.txt", base, new byte[] {'1', '1'})); + classPathJarEntries.put("META-INF/versions/11/multi/release/test/sub/testResourceAdd11.txt", getBytes("multi/release/test/sub/testResourceAdd11.txt", base)); + + createMRJar(classpathMrJar, Collections. emptyMap(), classPathJarEntries); + bundleEntries.put(classpathMrJar.getName(), StorageUtil.getBytes(new FileInputStream(classpathMrJar), -1, 4000)); + + // This will not be required by the spec, but equinox does support exploded inner jars in a bundle + bundleEntries.put("classPathDir/", null); + bundleEntries.put("classPathDir/multi/", null); + bundleEntries.put("classPathDir/multi/release/", null); + bundleEntries.put("classPathDir/multi/release/test/", null); + bundleEntries.put("classPathDir/multi/release/test/sub2/", null); + bundleEntries.put("classPathDir/multi/release/test/sub2/TestClassBase.class", getBytes("multi/release/test/sub2/TestClassBase.class", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/TestClass8.class", getBytes("multi/release/test/sub2/TestClass8.class", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/TestClass9.class", getBytes("multi/release/test/sub2/TestClass9.class", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/TestClass10.class", getBytes("multi/release/test/sub2/TestClass10.class", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/TestClass11.class", getBytes("multi/release/test/sub2/TestClass11.class", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/testResourceBase.txt", getBytes("multi/release/test/sub2/testResourceBase.txt", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/testResource8.txt", getBytes("multi/release/test/sub2/testResource8.txt", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/testResource9.txt", getBytes("multi/release/test/sub2/testResource9.txt", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/testResource10.txt", getBytes("multi/release/test/sub2/testResource10.txt", base)); + bundleEntries.put("classPathDir/multi/release/test/sub2/testResource11.txt", getBytes("multi/release/test/sub2/testResource11.txt", base)); + + String classPathDirManifest = // + "Manifest-Version: 1\n" + // + "Multi-Release: true\n\n"; + bundleEntries.put("classPathDir/META-INF/", null); + bundleEntries.put("classPathDir/META-INF/MANIFEST.MF", classPathDirManifest.getBytes(Charset.forName("UTF-8"))); + bundleEntries.put("classPathDir/META-INF/versions/", null); + bundleEntries.put("classPathDir/META-INF/versions/8/", null); + bundleEntries.put("classPathDir/META-INF/versions/8/multi/", null); + bundleEntries.put("classPathDir/META-INF/versions/8/multi/release/", null); + bundleEntries.put("classPathDir/META-INF/versions/8/multi/release/test/", null); + bundleEntries.put("classPathDir/META-INF/versions/8/multi/release/test/sub2/", null); + bundleEntries.put("classPathDir/META-INF/versions/8/multi/release/test/sub2/TestClass8.class", getBytes("multi/release/test/sub2/TestClass8.class", base, new byte[] {'0', '8'})); + bundleEntries.put("classPathDir/META-INF/versions/8/multi/release/test/sub2/TestClassAdd8.class", getBytes("multi/release/test/sub2/TestClassAdd8.class", base)); + bundleEntries.put("classPathDir/META-INF/versions/8/multi/release/test/sub2/testResource8.txt", getBytes("multi/release/test/sub2/testResource8.txt", base, new byte[] {'0', '8'})); + bundleEntries.put("classPathDir/META-INF/versions/8/multi/release/test/sub2/testResourceAdd8.txt", getBytes("multi/release/test/sub2/testResourceAdd8.txt", base)); + + bundleEntries.put("classPathDir/META-INF/versions/9/", null); + bundleEntries.put("classPathDir/META-INF/versions/9/multi/", null); + bundleEntries.put("classPathDir/META-INF/versions/9/multi/release/", null); + bundleEntries.put("classPathDir/META-INF/versions/9/multi/release/test/", null); + bundleEntries.put("classPathDir/META-INF/versions/9/multi/release/test/sub2/", null); + bundleEntries.put("classPathDir/META-INF/versions/9/multi/release/test/sub2/TestClass9.class", getBytes("multi/release/test/sub2/TestClass9.class", base, new byte[] {'0', '9'})); + bundleEntries.put("classPathDir/META-INF/versions/9/multi/release/test/sub2/TestClassAdd9.class", getBytes("multi/release/test/sub2/TestClassAdd9.class", base)); + bundleEntries.put("classPathDir/META-INF/versions/9/multi/release/test/sub2/testResource9.txt", getBytes("multi/release/test/sub2/testResource9.txt", base, new byte[] {'0', '9'})); + bundleEntries.put("classPathDir/META-INF/versions/9/multi/release/test/sub2/testResourceAdd9.txt", getBytes("multi/release/test/sub2/testResourceAdd9.txt", base)); + + bundleEntries.put("classPathDir/META-INF/versions/10/", null); + bundleEntries.put("classPathDir/META-INF/versions/10/multi/", null); + bundleEntries.put("classPathDir/META-INF/versions/10/multi/release/", null); + bundleEntries.put("classPathDir/META-INF/versions/10/multi/release/test/", null); + bundleEntries.put("classPathDir/META-INF/versions/10/multi/release/test/sub2/", null); + bundleEntries.put("classPathDir/META-INF/versions/10/multi/release/test/sub2/TestClass10.class", getBytes("multi/release/test/sub2/TestClass10.class", base, new byte[] {'1', '0'})); + bundleEntries.put("classPathDir/META-INF/versions/10/multi/release/test/sub2/TestClassAdd10.class", getBytes("multi/release/test/sub2/TestClassAdd10.class", base)); + bundleEntries.put("classPathDir/META-INF/versions/10/multi/release/test/sub2/testResource10.txt", getBytes("multi/release/test/sub2/testResource10.txt", base, new byte[] {'1', '0'})); + bundleEntries.put("classPathDir/META-INF/versions/10/multi/release/test/sub2/testResourceAdd10.txt", getBytes("multi/release/test/sub2/testResourceAdd10.txt", base)); + + bundleEntries.put("classPathDir/META-INF/versions/11/", null); + bundleEntries.put("classPathDir/META-INF/versions/11/multi/", null); + bundleEntries.put("classPathDir/META-INF/versions/11/multi/release/", null); + bundleEntries.put("classPathDir/META-INF/versions/11/multi/release/test/", null); + bundleEntries.put("classPathDir/META-INF/versions/11/multi/release/test/sub2/", null); + bundleEntries.put("classPathDir/META-INF/versions/11/multi/release/test/sub2/TestClass11.class", getBytes("multi/release/test/sub2/TestClass11.class", base, new byte[] {'1', '1'})); + bundleEntries.put("classPathDir/META-INF/versions/11/multi/release/test/sub2/TestClassAdd11.class", getBytes("multi/release/test/sub2/TestClassAdd11.class", base)); + bundleEntries.put("classPathDir/META-INF/versions/11/multi/release/test/sub2/testResource11.txt", getBytes("multi/release/test/sub2/testResource11.txt", base, new byte[] {'1', '1'})); + bundleEntries.put("classPathDir/META-INF/versions/11/multi/release/test/sub2/testResourceAdd11.txt", getBytes("multi/release/test/sub2/testResourceAdd11.txt", base)); + + createMRJar(mrJarBundle, bundleHeaders, bundleEntries); + return mrJarBundle; + } + + static void createMRJar(File file, Map headers, Map entries) throws IOException { + Manifest m = new Manifest(); + Attributes attributes = m.getMainAttributes(); + attributes.putValue("Manifest-Version", "1.0"); + attributes.putValue("Multi-Release", "true"); + for (Map.Entry entry : headers.entrySet()) { + attributes.putValue(entry.getKey(), entry.getValue()); + } + JarOutputStream jos = new JarOutputStream(new FileOutputStream(file), m); + if (entries != null) { + for (Map.Entry entry : entries.entrySet()) { + jos.putNextEntry(new JarEntry(entry.getKey())); + if (entry.getValue() != null) { + jos.write(entry.getValue()); + } + jos.closeEntry(); + } + } + jos.flush(); + jos.close(); + } + + private static byte[] getBytes(String path, Bundle b) throws IOException { + return getBytes(path, b, null); + } + + private static byte[] getBytes(String path, Bundle b, byte[] replace) throws IOException { + URL entry = b.getEntry(path); + if (entry == null) { + throw new FileNotFoundException("No entry found for: " + path); + } + byte[] result = StorageUtil.getBytes(entry.openStream(), -1, 4000); + + if (replace != null) { + for (int i = 0; i < result.length - 1; i++) { + if (result[i] == 'X' && result[i + 1] == 'X') { + result[i] = replace[0]; + result[i + 1] = replace[1]; + } + } + } + return result; + } + + public void testMultiRelease8ClassLoad() throws Exception { + doTestMultiReleaseClassLoad(8); + } + + public void testMultiRelease9ClassLoad() throws Exception { + doTestMultiReleaseClassLoad(9); + } + + public void testMultiRelease10ClassLoad() throws Exception { + doTestMultiReleaseClassLoad(10); + } + + public void testMultiRelease11ClassLoad() throws Exception { + doTestMultiReleaseClassLoad(11); + } + + private void doTestMultiReleaseClassLoad(int rv) throws Exception { + if (rv < 9) { + System.setProperty("java.specification.version", "1." + rv); + } else { + System.setProperty("java.specification.version", Integer.toString(rv)); + } + + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Equinox equinox = new Equinox(Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath())); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle(mrJarBundle.toURI().toString()); + mrBundle.start(); + assertEquals("Wrong class.", "BASEXX", loadClass("multi.release.test.TestClassBase", mrBundle, false)); + assertEquals("Wrong class.", "BASEXX", loadClass("multi.release.test.TestClass8", mrBundle, false)); + assertEquals("Wrong class.", CNFE, loadClass("multi.release.test.TestClassAdd8", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 9) ? "BASE09" : "BASEXX", loadClass("multi.release.test.TestClass9", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 9) ? "ADD09" : CNFE, loadClass("multi.release.test.TestClassAdd9", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 10) ? "BASE10" : "BASEXX", loadClass("multi.release.test.TestClass10", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 10) ? "ADD10" : CNFE, loadClass("multi.release.test.TestClassAdd10", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 11) ? "BASE11" : "BASEXX", loadClass("multi.release.test.TestClass11", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 11) ? "ADD11" : CNFE, loadClass("multi.release.test.TestClassAdd11", mrBundle, true)); + + assertEquals("Wrong class.", "BASEXX", loadClass("multi.release.test.sub.TestClassBase", mrBundle, false)); + assertEquals("Wrong class.", "BASEXX", loadClass("multi.release.test.sub.TestClass8", mrBundle, false)); + assertEquals("Wrong class.", CNFE, loadClass("multi.release.test.TestClassAdd8", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 9) ? "BASE09" : "BASEXX", loadClass("multi.release.test.sub.TestClass9", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 9) ? "ADD09" : CNFE, loadClass("multi.release.test.sub.TestClassAdd9", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 10) ? "BASE10" : "BASEXX", loadClass("multi.release.test.sub.TestClass10", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 10) ? "ADD10" : CNFE, loadClass("multi.release.test.sub.TestClassAdd10", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 11) ? "BASE11" : "BASEXX", loadClass("multi.release.test.sub.TestClass11", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 11) ? "ADD11" : CNFE, loadClass("multi.release.test.sub.TestClassAdd11", mrBundle, true)); + + assertEquals("Wrong class.", "BASEXX", loadClass("multi.release.test.sub2.TestClassBase", mrBundle, false)); + assertEquals("Wrong class.", "BASEXX", loadClass("multi.release.test.sub2.TestClass8", mrBundle, false)); + assertEquals("Wrong class.", CNFE, loadClass("multi.release.test.TestClassAdd8", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 9) ? "BASE09" : "BASEXX", loadClass("multi.release.test.sub2.TestClass9", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 9) ? "ADD09" : CNFE, loadClass("multi.release.test.sub2.TestClassAdd9", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 10) ? "BASE10" : "BASEXX", loadClass("multi.release.test.sub2.TestClass10", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 10) ? "ADD10" : CNFE, loadClass("multi.release.test.sub2.TestClassAdd10", mrBundle, true)); + assertEquals("Wrong class.", (rv >= 11) ? "BASE11" : "BASEXX", loadClass("multi.release.test.sub2.TestClass11", mrBundle, false)); + assertEquals("Wrong class.", (rv >= 11) ? "ADD11" : CNFE, loadClass("multi.release.test.sub2.TestClassAdd11", mrBundle, true)); + } finally { + try { + equinox.stop(); + equinox.waitForStop(10000); + } catch (Exception e) { + // ignore; + } + } + } + + private String loadClass(String name, Bundle mrBundle, boolean cnfeExpected) throws Exception { + try { + return mrBundle.loadClass(name).getConstructor().newInstance().toString(); + } catch (ClassNotFoundException e) { + if (cnfeExpected) { + return CNFE; + } + throw e; + } + } + + public void testMultiRelease8GetResource() throws Exception { + doTestMultiReleaseGetResource(8); + } + + public void testMultiRelease9GetResource() throws Exception { + doTestMultiReleaseGetResource(9); + } + + public void testMultiRelease10GetResource() throws Exception { + doTestMultiReleaseGetResource(10); + } + + public void testMultiRelease11GetResource() throws Exception { + doTestMultiReleaseGetResource(11); + } + + private void doTestMultiReleaseGetResource(int rv) throws Exception { + if (rv < 9) { + System.setProperty("java.specification.version", "1." + rv); + } else { + System.setProperty("java.specification.version", Integer.toString(rv)); + } + + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Equinox equinox = new Equinox(Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath())); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle(mrJarBundle.toURI().toString()); + mrBundle.start(); + + assertEquals("Wrong resource.", "RESOURCE XX", readResource("multi/release/test/testResourceBase.txt", mrBundle)); + assertEquals("Wrong resource.", "RESOURCE XX", readResource("multi/release/test/testResource8.txt", mrBundle)); + assertEquals("Wrong resource.", RNF, readResource("multi/release/test/testResourceAdd8.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "RESOURCE 09" : "RESOURCE XX", readResource("multi/release/test/testResource9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "ADD 09" : RNF, readResource("multi/release/test/testResourceAdd9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "RESOURCE 10" : "RESOURCE XX", readResource("multi/release/test/testResource10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "ADD 10" : RNF, readResource("multi/release/test/testResourceAdd10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "RESOURCE 11" : "RESOURCE XX", readResource("multi/release/test/testResource11.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "ADD 11" : RNF, readResource("multi/release/test/testResourceAdd11.txt", mrBundle)); + + assertEquals("Wrong resource.", "RESOURCE XX", readResource("multi/release/test/sub/testResourceBase.txt", mrBundle)); + assertEquals("Wrong resource.", "RESOURCE XX", readResource("multi/release/test/sub/testResource8.txt", mrBundle)); + assertEquals("Wrong resource.", RNF, readResource("multi/release/test/testResourceAdd8.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "RESOURCE 09" : "RESOURCE XX", readResource("multi/release/test/sub/testResource9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "ADD 09" : RNF, readResource("multi/release/test/sub/testResourceAdd9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "RESOURCE 10" : "RESOURCE XX", readResource("multi/release/test/sub/testResource10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "ADD 10" : RNF, readResource("multi/release/test/sub/testResourceAdd10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "RESOURCE 11" : "RESOURCE XX", readResource("multi/release/test/sub/testResource11.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "ADD 11" : RNF, readResource("multi/release/test/sub/testResourceAdd11.txt", mrBundle)); + + assertEquals("Wrong resource.", "RESOURCE XX", readResource("multi/release/test/sub2/testResourceBase.txt", mrBundle)); + assertEquals("Wrong resource.", "RESOURCE XX", readResource("multi/release/test/sub2/testResource8.txt", mrBundle)); + assertEquals("Wrong resource.", RNF, readResource("multi/release/test/testResourceAdd8.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "RESOURCE 09" : "RESOURCE XX", readResource("multi/release/test/sub2/testResource9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "ADD 09" : RNF, readResource("multi/release/test/sub2/testResourceAdd9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "RESOURCE 10" : "RESOURCE XX", readResource("multi/release/test/sub2/testResource10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "ADD 10" : RNF, readResource("multi/release/test/sub2/testResourceAdd10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "RESOURCE 11" : "RESOURCE XX", readResource("multi/release/test/sub2/testResource11.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "ADD 11" : RNF, readResource("multi/release/test/sub2/testResourceAdd11.txt", mrBundle)); + + } finally { + try { + equinox.stop(); + equinox.waitForStop(10000); + } catch (Exception e) { + // ignore; + } + } + } + + private String readResource(String name, Bundle mrBundle) throws Exception { + BundleWiring wiring = mrBundle.adapt(BundleWiring.class); + URL url = wiring.getClassLoader().getResource(name); + String result = readURL(url); + + int lastSlash = name.lastIndexOf('/'); + Collection resourcePaths = wiring.listResources(name.substring(0, lastSlash + 1), name.substring(lastSlash + 1), 0); + if (result == RNF) { + if (!resourcePaths.isEmpty()) { + fail("listResources found path for '" + name + "'"); + } + } else { + assertEquals("Found too many resource paths for '" + name + "'", 1, resourcePaths.size()); + assertEquals("Wrong path listed.", name, resourcePaths.iterator().next()); + assertURLCopy(result, url, mrBundle); + } + + return result; + } + + private void assertURLCopy(String expected, URL url, Bundle mrBundle) throws Exception { + Class testClassBase = mrBundle.loadClass("multi.release.test.TestClassBase"); + URL copy = (URL) testClassBase.getDeclaredMethod("createURL", String.class).invoke(null, url.toExternalForm()); + String copyResult = readURL(copy); + assertEquals(expected, copyResult); + } + + private String readURL(URL url) throws IOException { + if (url == null) { + return RNF; + } + BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); + try { + return br.readLine(); + } finally { + br.close(); + } + } + + public void testMultiRelease8GetResources() throws Exception { + doTestMultiReleaseGetResources(8); + } + + public void testMultiRelease9GetResources() throws Exception { + doTestMultiReleaseGetResources(9); + } + + public void testMultiRelease10GetResources() throws Exception { + doTestMultiReleaseGetResources(10); + } + + public void testMultiRelease11GetResources() throws Exception { + doTestMultiReleaseGetResources(11); + } + + private void doTestMultiReleaseGetResources(int rv) throws Exception { + if (rv < 9) { + System.setProperty("java.specification.version", "1." + rv); + } else { + System.setProperty("java.specification.version", Integer.toString(rv)); + } + + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Equinox equinox = new Equinox(Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath())); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle(mrJarBundle.toURI().toString()); + mrBundle.start(); + + assertEquals("Wrong resource.", "RESOURCE XX", readResources("multi/release/test/testResourceBase.txt", mrBundle)); + assertEquals("Wrong resource.", "RESOURCE XX", readResources("multi/release/test/testResource8.txt", mrBundle)); + assertEquals("Wrong resource.", RNF, readResources("multi/release/test/testResourceAdd8.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "RESOURCE 09" : "RESOURCE XX", readResources("multi/release/test/testResource9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "ADD 09" : RNF, readResources("multi/release/test/testResourceAdd9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "RESOURCE 10" : "RESOURCE XX", readResources("multi/release/test/testResource10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "ADD 10" : RNF, readResources("multi/release/test/testResourceAdd10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "RESOURCE 11" : "RESOURCE XX", readResources("multi/release/test/testResource11.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "ADD 11" : RNF, readResources("multi/release/test/testResourceAdd11.txt", mrBundle)); + + assertEquals("Wrong resource.", "RESOURCE XX", readResources("multi/release/test/sub/testResourceBase.txt", mrBundle)); + assertEquals("Wrong resource.", "RESOURCE XX", readResources("multi/release/test/sub/testResource8.txt", mrBundle)); + assertEquals("Wrong resource.", RNF, readResources("multi/release/test/testResourceAdd8.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "RESOURCE 09" : "RESOURCE XX", readResources("multi/release/test/sub/testResource9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "ADD 09" : RNF, readResources("multi/release/test/sub/testResourceAdd9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "RESOURCE 10" : "RESOURCE XX", readResources("multi/release/test/sub/testResource10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "ADD 10" : RNF, readResources("multi/release/test/sub/testResourceAdd10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "RESOURCE 11" : "RESOURCE XX", readResources("multi/release/test/sub/testResource11.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "ADD 11" : RNF, readResources("multi/release/test/sub/testResourceAdd11.txt", mrBundle)); + + assertEquals("Wrong resource.", "RESOURCE XX", readResources("multi/release/test/sub2/testResourceBase.txt", mrBundle)); + assertEquals("Wrong resource.", "RESOURCE XX", readResources("multi/release/test/sub2/testResource8.txt", mrBundle)); + assertEquals("Wrong resource.", RNF, readResources("multi/release/test/testResourceAdd8.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "RESOURCE 09" : "RESOURCE XX", readResources("multi/release/test/sub2/testResource9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 9) ? "ADD 09" : RNF, readResources("multi/release/test/sub2/testResourceAdd9.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "RESOURCE 10" : "RESOURCE XX", readResources("multi/release/test/sub2/testResource10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 10) ? "ADD 10" : RNF, readResources("multi/release/test/sub2/testResourceAdd10.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "RESOURCE 11" : "RESOURCE XX", readResources("multi/release/test/sub2/testResource11.txt", mrBundle)); + assertEquals("Wrong resource.", (rv >= 11) ? "ADD 11" : RNF, readResources("multi/release/test/sub2/testResourceAdd11.txt", mrBundle)); + + } finally { + try { + equinox.stop(); + equinox.waitForStop(10000); + } catch (Exception e) { + // ignore; + } + } + } + + private String readResources(String name, Bundle mrBundle) throws IOException { + BundleWiring wiring = mrBundle.adapt(BundleWiring.class); + List urls = Collections.list(wiring.getClassLoader().getResources(name)); + if (urls.isEmpty()) { + return RNF; + } + assertEquals("Wrong number of resources.", 1, urls.size()); + return readURL(urls.get(0)); + } + + public void testMultiRelease8ListResources() throws Exception { + doTestMultiReleaseListResources(8); + } + + public void testMultiRelease9ListResources() throws Exception { + doTestMultiReleaseListResources(9); + } + + public void testMultiRelease10ListResources() throws Exception { + doTestMultiReleaseListResources(10); + } + + public void testMultiRelease11ListResources() throws Exception { + doTestMultiReleaseListResources(11); + } + + private void doTestMultiReleaseListResources(int rv) throws Exception { + if (rv < 9) { + System.setProperty("java.specification.version", "1." + rv); + } else { + System.setProperty("java.specification.version", Integer.toString(rv)); + } + + Collection expected = new ArrayList(); + Collection expectedRecurse = new ArrayList(); + + expected.add("multi/release/test/testResourceBase.txt"); + expected.add("multi/release/test/testResource8.txt"); + expected.add("multi/release/test/testResource9.txt"); + expected.add("multi/release/test/testResource10.txt"); + expected.add("multi/release/test/testResource11.txt"); + + if (rv >= 9) { + expected.add("multi/release/test/testResourceAdd9.txt"); + } + if (rv >= 10) { + expected.add("multi/release/test/testResourceAdd10.txt"); + } + if (rv >= 11) { + expected.add("multi/release/test/testResourceAdd11.txt"); + } + + expectedRecurse.addAll(expected); + expectedRecurse.add("multi/release/test/sub/testResourceBase.txt"); + expectedRecurse.add("multi/release/test/sub/testResource8.txt"); + expectedRecurse.add("multi/release/test/sub/testResource9.txt"); + expectedRecurse.add("multi/release/test/sub/testResource10.txt"); + expectedRecurse.add("multi/release/test/sub/testResource11.txt"); + expectedRecurse.add("multi/release/test/sub2/testResourceBase.txt"); + expectedRecurse.add("multi/release/test/sub2/testResource8.txt"); + expectedRecurse.add("multi/release/test/sub2/testResource9.txt"); + expectedRecurse.add("multi/release/test/sub2/testResource10.txt"); + expectedRecurse.add("multi/release/test/sub2/testResource11.txt"); + + if (rv >= 9) { + expectedRecurse.add("multi/release/test/sub/testResourceAdd9.txt"); + expectedRecurse.add("multi/release/test/sub2/testResourceAdd9.txt"); + } + if (rv >= 10) { + expectedRecurse.add("multi/release/test/sub/testResourceAdd10.txt"); + expectedRecurse.add("multi/release/test/sub2/testResourceAdd10.txt"); + } + if (rv >= 11) { + expectedRecurse.add("multi/release/test/sub/testResourceAdd11.txt"); + expectedRecurse.add("multi/release/test/sub2/testResourceAdd11.txt"); + } + + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Equinox equinox = new Equinox(Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath())); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle(mrJarBundle.toURI().toString()); + mrBundle.start(); + + listResources("multi/release/test", expected, mrBundle, 0); + listResources("multi/release/test", expectedRecurse, mrBundle, BundleWiring.LISTRESOURCES_RECURSE); + } finally { + try { + equinox.stop(); + equinox.waitForStop(10000); + } catch (Exception e) { + // ignore; + } + } + } + + private void listResources(String path, Collection expected, Bundle mrBundle, int options) { + BundleWiring wiring = mrBundle.adapt(BundleWiring.class); + Collection found = wiring.listResources(path, "*.txt", options); + assertEquals("Wrong resource listing.", expected.toArray(), found.toArray(), false); + } + + public void testMultiReleaseBundleManifest8() throws Exception { + doTestMultiReleaseBundleManifest(8); + } + + public void testMultiReleaseBundleManifest9() throws Exception { + doTestMultiReleaseBundleManifest(9); + } + + public void testMultiReleaseBundleManifest10() throws Exception { + doTestMultiReleaseBundleManifest(10); + } + + public void testMultiReleaseBundleManifest11() throws Exception { + doTestMultiReleaseBundleManifest(11); + } + + private void doTestMultiReleaseBundleManifest(int rv) throws Exception { + if (rv < 9) { + System.setProperty("java.specification.version", "1." + rv); + } else { + System.setProperty("java.specification.version", Integer.toString(rv)); + } + + String expectedCap; + String expectedPkg; + if (rv < 9) { + expectedCap = "capbase"; + expectedPkg = "pkgbase"; + } else { + expectedCap = "cap" + rv; + expectedPkg = "pkg" + rv; + } + + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Equinox equinox = new Equinox(Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath())); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle(mrJarBundle.toURI().toString()); + mrBundle.start(); + + List capWires = mrBundle.adapt(BundleWiring.class).getRequiredWires(expectedCap); + assertEquals("Wrong number of capability wires.", 1, capWires.size()); + + List pkgReqs = mrBundle.adapt(BundleRevision.class).getDeclaredRequirements(PackageNamespace.PACKAGE_NAMESPACE); + assertEquals("Wrong number of package requiremens.", 1, pkgReqs.size()); + String filter = pkgReqs.get(0).getDirectives().get(Namespace.REQUIREMENT_FILTER_DIRECTIVE); + assertTrue("Wrong package filter: " + filter, filter.contains(expectedPkg)); + + } finally { + try { + equinox.stop(); + equinox.waitForStop(10000); + } catch (Exception e) { + // ignore; + } + } + } + + public void testMultiReleaseBundleManifestChangeRuntime() throws Exception { + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Map configMap = Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath() + " with space"); + Equinox equinox = new Equinox(configMap); + String location; + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle(mrJarBundle.toURI().toString()); + location = mrBundle.getLocation(); + mrBundle.start(); + } finally { + equinox.stop(); + equinox.waitForStop(1000); + } + + for (int rv = 8; rv <= 11; rv++) { + doTestMultiReleaseBundleManifestChangeRuntime(rv, configMap, location); + } + + equinox.start(); + try { + BundleContext systemContext = equinox.getBundleContext(); + Bundle toUninstall = systemContext.getBundle(location); + toUninstall.uninstall(); + Bundle mrBundle = systemContext.installBundle("reference:" + mrJarBundle.toURI().toString()); + location = mrBundle.getLocation(); + mrBundle.start(); + } finally { + equinox.stop(); + equinox.waitForStop(1000); + } + + for (int rv = 8; rv <= 11; rv++) { + doTestMultiReleaseBundleManifestChangeRuntime(rv, configMap, location); + } + } + + private void doTestMultiReleaseBundleManifestChangeRuntime(int rv, Map configMap, String location) throws BundleException { + if (rv < 9) { + System.setProperty("java.specification.version", "1." + rv); + } else { + System.setProperty("java.specification.version", Integer.toString(rv)); + } + + String expectedCap; + String expectedPkg; + if (rv < 9) { + expectedCap = "capbase"; + expectedPkg = "pkgbase"; + } else { + expectedCap = "cap" + rv; + expectedPkg = "pkg" + rv; + } + + Equinox equinox = new Equinox(configMap); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.getBundle(location); + assertNotNull("No mrBundle found: " + rv, mrBundle); + assertEquals("Wrong state of mrBundle: " + rv, Bundle.ACTIVE, mrBundle.getState()); + + List capWires = mrBundle.adapt(BundleWiring.class).getRequiredWires(expectedCap); + assertEquals("Wrong number of capability wires: " + rv, 1, capWires.size()); + + List pkgReqs = mrBundle.adapt(BundleRevision.class).getDeclaredRequirements(PackageNamespace.PACKAGE_NAMESPACE); + assertEquals("Wrong number of package requiremens: " + rv, 1, pkgReqs.size()); + String filter = pkgReqs.get(0).getDirectives().get(Namespace.REQUIREMENT_FILTER_DIRECTIVE); + assertTrue("Wrong package filter: " + rv + " " + filter, filter.contains(expectedPkg)); + + } finally { + try { + equinox.stop(); + equinox.waitForStop(10000); + } catch (Exception e) { + // ignore; + } + } + } + +} diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathEntry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathEntry.java index fc6783104..09ceba150 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathEntry.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathEntry.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2016 IBM Corporation and others. + * Copyright (c) 2005, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,16 +11,26 @@ package org.eclipse.osgi.internal.loader.classpath; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; import java.security.ProtectionDomain; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.jar.Attributes; import java.util.jar.Manifest; +import org.eclipse.osgi.container.Module; import org.eclipse.osgi.framework.util.KeyedElement; import org.eclipse.osgi.framework.util.KeyedHashSet; import org.eclipse.osgi.storage.BundleInfo; import org.eclipse.osgi.storage.BundleInfo.Generation; +import org.eclipse.osgi.storage.Storage; import org.eclipse.osgi.storage.bundlefile.BundleEntry; import org.eclipse.osgi.storage.bundlefile.BundleFile; @@ -46,6 +56,7 @@ public class ClasspathEntry { private final ProtectionDomain domain; private final ManifestPackageAttributes mainManifestPackageAttributes; private final Map perPackageManifestAttributes; + private final List mrBundleFiles; private KeyedHashSet userObjects = null; // TODO Note that PDE has internal dependency on this field type/name (bug 267238) @@ -69,6 +80,35 @@ public class ClasspathEntry { mainManifestPackageAttributes = ManifestPackageAttributes.NONE; perPackageManifestAttributes = null; } + + boolean isMRJar; + if (bundlefile == generation.getBundleFile()) { + // this is the root bundle file + isMRJar = generation.isMRJar(); + } else { + isMRJar = manifest != null ? Boolean.parseBoolean(manifest.getMainAttributes().getValue(BundleInfo.MULTI_RELEASE_HEADER)) : false; + } + if (isMRJar) { + mrBundleFiles = getMRBundleFiles(bundlefile, generation); + } else { + mrBundleFiles = Collections.emptyList(); + } + } + + private static List getMRBundleFiles(BundleFile bundlefile, Generation generation) { + Storage storage = generation.getBundleInfo().getStorage(); + if (storage.getRuntimeVersion().getMajor() < 9) { + return Collections.emptyList(); + } + List mrBundleFiles = new ArrayList<>(); + for (int i = storage.getRuntimeVersion().getMajor(); i > 8; i--) { + String versionPath = "META-INF/versions/" + i + '/'; //$NON-NLS-1$ + BundleEntry versionEntry = bundlefile.getEntry(versionPath); + if (versionEntry != null) { + mrBundleFiles.add(storage.createNestedBundleFile(versionPath, bundlefile, generation)); + } + } + return Collections.unmodifiableList(mrBundleFiles); } private static ManifestPackageAttributes manifestPackageAttributesFor(Attributes attributes, ManifestPackageAttributes defaultAttributes) { @@ -135,6 +175,50 @@ public class ClasspathEntry { userObjects.add(userObject); } + /** + * Finds the entry with the specified path. + * This handles Multi-Release searching also. + * @param path the path to find + * @return the entry with the specified path. + */ + public BundleEntry findEntry(String path) { + for (BundleFile mrFile : mrBundleFiles) { + BundleEntry mrEntry = mrFile.getEntry(path); + if (mrEntry != null) { + return mrEntry; + } + } + return bundlefile.getEntry(path); + } + + /** + * Finds the resource wiht the specified name. + * This handles Multi-Release searching also. + * @param name the resource name + * @param m the module this classpath entry is for + * @param index the index this classpath entry. + * @return the resource URL or {@code null} if the resource does not exist. + */ + public URL findResource(String name, Module m, int index) { + for (BundleFile mrFile : mrBundleFiles) { + URL mrURL = mrFile.getResourceURL(name, m, index); + if (mrURL != null) { + return mrURL; + } + } + return bundlefile.getResourceURL(name, m, index); + } + + /** + * Adds the BundleFile objects for this classpath in the proper order + * for searching for resources. This handles Multi-Release ordering also. + * @param bundlefiles + */ + public void addBundleFiles(List bundlefiles) { + bundlefiles.addAll(mrBundleFiles); + bundlefiles.add(bundlefile); + } + private static Manifest loadManifest(BundleFile cpBundleFile, Generation generation) { if (!generation.hasPackageInfo() && generation.getBundleFile() == cpBundleFile) { return null; @@ -165,4 +249,10 @@ public class ClasspathEntry { return mainManifestPackageAttributes; } + public void close() throws IOException { + bundlefile.close(); + for (BundleFile bf : mrBundleFiles) { + bf.close(); + } + } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java index 465679144..ee0377c55 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java @@ -11,11 +11,22 @@ package org.eclipse.osgi.internal.loader.classpath; -import java.io.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; import java.net.URL; -import java.util.*; -import org.eclipse.osgi.container.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.ListIterator; +import org.eclipse.osgi.container.Module; +import org.eclipse.osgi.container.ModuleCapability; import org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent; +import org.eclipse.osgi.container.ModuleRevision; +import org.eclipse.osgi.container.ModuleWire; import org.eclipse.osgi.container.namespaces.EquinoxModuleDataNamespace; import org.eclipse.osgi.framework.util.ArrayMap; import org.eclipse.osgi.internal.debug.Debug; @@ -134,7 +145,7 @@ public class ClasspathManager { for (int i = 0; i < entries.length; i++) { if (entries[i] != null) { try { - entries[i].getBundleFile().close(); + entries[i].close(); } catch (IOException e) { generation.getBundleInfo().getStorage().getAdaptor().publishContainerEvent(ContainerEvent.ERROR, generation.getRevision().getRevisions().getModule(), e); } @@ -358,24 +369,25 @@ public class ClasspathManager { } private URL findLocalResourceImpl(String resource, int classPathIndex) { + Module m = generation.getRevision().getRevisions().getModule(); URL result = null; int curIndex = 0; - for (int i = 0; i < entries.length; i++) { - if (entries[i] != null) { - result = findResourceImpl(resource, entries[i].getBundleFile(), curIndex); - if (result != null && (classPathIndex == -1 || classPathIndex == curIndex)) + for (ClasspathEntry cpEntry : entries) { + if (cpEntry != null) { + result = cpEntry.findResource(resource, m, curIndex); + if (result != null && (classPathIndex == -1 || classPathIndex == curIndex)) { return result; + } } curIndex++; } // look in fragments - FragmentClasspath[] currentFragments = getFragmentClasspaths(); - for (int i = 0; i < currentFragments.length; i++) { - ClasspathEntry[] fragEntries = currentFragments[i].getEntries(); - for (int j = 0; j < fragEntries.length; j++) { - result = findResourceImpl(resource, fragEntries[j].getBundleFile(), curIndex); - if (result != null && (classPathIndex == -1 || classPathIndex == curIndex)) + for (FragmentClasspath fragCP : getFragmentClasspaths()) { + for (ClasspathEntry cpEntry : fragCP.getEntries()) { + result = cpEntry.findResource(resource, m, curIndex); + if (result != null && (classPathIndex == -1 || classPathIndex == curIndex)) { return result; + } curIndex++; } } @@ -388,24 +400,25 @@ public class ClasspathManager { * @return an enumeration of the the requested resources */ public Enumeration findLocalResources(String resource) { + Module m = generation.getRevision().getRevisions().getModule(); List resources = new ArrayList<>(6); int classPathIndex = 0; - for (int i = 0; i < entries.length; i++) { - if (entries[i] != null) { - URL url = findResourceImpl(resource, entries[i].getBundleFile(), classPathIndex); - if (url != null) + for (ClasspathEntry cpEntry : entries) { + if (cpEntry != null) { + URL url = cpEntry.findResource(resource, m, classPathIndex); + if (url != null) { resources.add(url); + } } classPathIndex++; } // look in fragments - FragmentClasspath[] currentFragments = getFragmentClasspaths(); - for (int i = 0; i < currentFragments.length; i++) { - ClasspathEntry[] fragEntries = currentFragments[i].getEntries(); - for (int j = 0; j < fragEntries.length; j++) { - URL url = findResourceImpl(resource, fragEntries[j].getBundleFile(), classPathIndex); - if (url != null) + for (FragmentClasspath fragCP : getFragmentClasspaths()) { + for (ClasspathEntry cpEntry : fragCP.getEntries()) { + URL url = cpEntry.findResource(resource, m, classPathIndex); + if (url != null) { resources.add(url); + } classPathIndex++; } } @@ -414,10 +427,6 @@ public class ClasspathManager { return EMPTY_ENUMERATION; } - private URL findResourceImpl(String name, BundleFile bundlefile, int index) { - return bundlefile.getResourceURL(name, generation.getRevision().getRevisions().getModule(), index); - } - /** * Finds a local entry by searching the ClasspathEntry objects of the classpath manager. * @param path the requested entry path. @@ -439,7 +448,7 @@ public class ClasspathManager { int curIndex = 0; for (int i = 0; i < entries.length; i++) { if (entries[i] != null) { - result = findEntryImpl(path, entries[i].getBundleFile()); + result = entries[i].findEntry(path); if (result != null && (classPathIndex == -1 || classPathIndex == curIndex)) return result; } @@ -450,7 +459,7 @@ public class ClasspathManager { for (int i = 0; i < currentFragments.length; i++) { ClasspathEntry[] fragEntries = currentFragments[i].getEntries(); for (int j = 0; j < fragEntries.length; j++) { - result = findEntryImpl(path, fragEntries[j].getBundleFile()); + result = fragEntries[j].findEntry(path); if (result != null && (classPathIndex == -1 || classPathIndex == curIndex)) return result; curIndex++; @@ -459,39 +468,6 @@ public class ClasspathManager { return null; } - /** - * Finds the local entries by searching the ClasspathEntry objects of the classpath manager. - * @param path the requested entry path. - * @return an enumeration of the the requested entries or null if the entries do not exist - */ - public Enumeration findLocalEntries(String path) { - List objects = new ArrayList<>(6); - for (int i = 0; i < entries.length; i++) { - if (entries[i] != null) { - BundleEntry result = findEntryImpl(path, entries[i].getBundleFile()); - if (result != null) - objects.add(result); - } - } - // look in fragments - FragmentClasspath[] currentFragments = getFragmentClasspaths(); - for (int i = 0; i < currentFragments.length; i++) { - ClasspathEntry[] fragEntries = currentFragments[i].getEntries(); - for (int j = 0; j < fragEntries.length; j++) { - BundleEntry result = findEntryImpl(path, fragEntries[j].getBundleFile()); - if (result != null) - objects.add(result); - } - } - if (objects.size() > 0) - return Collections.enumeration(objects); - return null; - } - - private BundleEntry findEntryImpl(String path, BundleFile bundleFile) { - return bundleFile.getEntry(path); - } - /** * Finds a local class by searching the ClasspathEntry objects of the classpath manager. * This method will first call all the configured class loader hooks @@ -557,7 +533,8 @@ public class ClasspathManager { if (debug.DEBUG_LOADER) Debug.println("ModuleClassLoader[" + classloader.getBundleLoader() + " - " + classpathEntry.getBundleFile() + "].findClassImpl(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ String filename = name.replace('.', '/').concat(".class"); //$NON-NLS-1$ - BundleEntry entry = classpathEntry.getBundleFile().getEntry(filename); + + BundleEntry entry = classpathEntry.findEntry(filename); if (entry == null) return null; @@ -829,14 +806,14 @@ public class ClasspathManager { List bundleFiles = new ArrayList<>(); ClasspathEntry[] cpEntries = getHostClasspathEntries(); - for (ClasspathEntry cpEntry : cpEntries) - bundleFiles.add(cpEntry.getBundleFile()); + for (ClasspathEntry cpEntry : cpEntries) { + cpEntry.addBundleFiles(bundleFiles); + } - FragmentClasspath[] currentFragments = getFragmentClasspaths(); - for (FragmentClasspath fragmentClasspath : currentFragments) { - ClasspathEntry[] fragEntries = fragmentClasspath.getEntries(); - for (ClasspathEntry cpEntry : fragEntries) - bundleFiles.add(cpEntry.getBundleFile()); + for (FragmentClasspath fragmentClasspath : getFragmentClasspaths()) { + for (ClasspathEntry cpEntry : fragmentClasspath.getEntries()) { + cpEntry.addBundleFiles(bundleFiles); + } } return Storage.listEntryPaths(bundleFiles, path, filePattern, options); diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/FragmentClasspath.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/FragmentClasspath.java index 8eef94909..e04273c33 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/FragmentClasspath.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/FragmentClasspath.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2013 IBM Corporation and others. + * Copyright (c) 2005, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -53,7 +53,7 @@ public class FragmentClasspath { public void close() { for (int i = 0; i < entries.length; i++) { try { - entries[i].getBundleFile().close(); + entries[i].close(); } catch (IOException e) { generation.getBundleInfo().getStorage().getAdaptor().publishContainerEvent(ContainerEvent.ERROR, generation.getRevision().getRevisions().getModule(), e); } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java index c905d2832..286bcb7d1 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java @@ -48,9 +48,11 @@ import org.eclipse.osgi.storage.url.bundleentry.Handler; import org.eclipse.osgi.util.ManifestElement; import org.eclipse.osgi.util.NLS; import org.osgi.framework.BundleException; +import org.osgi.framework.Constants; public final class BundleInfo { public static final String OSGI_BUNDLE_MANIFEST = "META-INF/MANIFEST.MF"; //$NON-NLS-1$ + public static final String MULTI_RELEASE_HEADER = "Multi-Release"; //$NON-NLS-1$ public final class Generation { private final long generationId; @@ -68,13 +70,14 @@ public final class BundleInfo { private NativeCodeFinder nativeCodeFinder; private List> storageHooks; private long lastModified; + private boolean isMRJar; Generation(long generationId) { this.generationId = generationId; this.cachedHeaders = new CachedManifest(this, Collections. emptyMap()); } - Generation(long generationId, File content, boolean isDirectory, boolean isReference, boolean hasPackageInfo, Map cached, long lastModified) { + Generation(long generationId, File content, boolean isDirectory, boolean isReference, boolean hasPackageInfo, Map cached, long lastModified, boolean isMRJar) { this.generationId = generationId; this.content = content; this.isDirectory = isDirectory; @@ -82,6 +85,7 @@ public final class BundleInfo { this.hasPackageInfo = hasPackageInfo; this.cachedHeaders = new CachedManifest(this, cached); this.lastModified = lastModified; + this.isMRJar = isMRJar; } public BundleFile getBundleFile() { @@ -121,7 +125,28 @@ public final class BundleInfo { rawHeaders = Collections.emptyMap(); } else { try { - rawHeaders = Collections.unmodifiableMap(ManifestElement.parseBundleManifest(manifest.getInputStream(), new CaseInsensitiveDictionaryMap())); + Map merged = ManifestElement.parseBundleManifest(manifest.getInputStream(), new CaseInsensitiveDictionaryMap()); + // For MRJARs only replace Import-Package and Require-Capability if the versioned values are non-null + if (Boolean.parseBoolean(merged.get(MULTI_RELEASE_HEADER))) { + for (int i = getStorage().getRuntimeVersion().getMajor(); i > 8; i--) { + String versionManifest = "META-INF/versions/" + i + "/OSGI-INF/MANIFEST.MF"; //$NON-NLS-1$ //$NON-NLS-2$ + BundleEntry versionEntry = getBundleFile().getEntry(versionManifest); + if (versionEntry != null) { + Map versioned = ManifestElement.parseBundleManifest(versionEntry.getInputStream(), new CaseInsensitiveDictionaryMap()); + String versionedImport = versioned.get(Constants.IMPORT_PACKAGE); + String versionedRequireCap = versioned.get(Constants.REQUIRE_CAPABILITY); + if (versionedImport != null) { + merged.put(Constants.IMPORT_PACKAGE, versionedImport); + } + if (versionedRequireCap != null) { + merged.put(Constants.REQUIRE_CAPABILITY, versionedRequireCap); + } + // found a versioned entry; stop searching for more versions + break; + } + } + } + rawHeaders = Collections.unmodifiableMap(merged); } catch (Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException) e; @@ -191,6 +216,12 @@ public final class BundleInfo { } } + public boolean isMRJar() { + synchronized (this.genMonitor) { + return this.isMRJar; + } + } + public File getContent() { synchronized (this.genMonitor) { return this.content; @@ -222,6 +253,7 @@ public final class BundleInfo { this.storageHooks = storageHooks; if (install) { this.hasPackageInfo = BundleInfo.hasPackageInfo(getBundleFile()); + this.isMRJar = Boolean.parseBoolean(getRawHeaders().get(MULTI_RELEASE_HEADER)); } } } @@ -433,9 +465,9 @@ public final class BundleInfo { } } - Generation restoreGeneration(long generationId, File content, boolean isDirectory, boolean isReference, boolean hasPackageInfo, Map cached, long lastModified) { + Generation restoreGeneration(long generationId, File content, boolean isDirectory, boolean isReference, boolean hasPackageInfo, Map cached, long lastModified, boolean isMRJar) { synchronized (this.infoMonitor) { - Generation restoredGeneration = new Generation(generationId, content, isDirectory, isReference, hasPackageInfo, cached, lastModified); + Generation restoredGeneration = new Generation(generationId, content, isDirectory, isReference, hasPackageInfo, cached, lastModified, isMRJar); return restoredGeneration; } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java index 0ed4743e7..31b4b6fdb 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java @@ -45,6 +45,7 @@ import java.util.NoSuchElementException; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; +import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.runtime.adaptor.EclipseStarter; import org.eclipse.osgi.container.Module; import org.eclipse.osgi.container.ModuleCapability; @@ -109,7 +110,9 @@ import org.osgi.resource.Namespace; import org.osgi.resource.Requirement; public class Storage { - public static final int VERSION = 3; + public static final int VERSION = 4; + private static final int MR_JAR_VERSION = 4; + private static final int LOWEST_VERSION_SUPPORTED = 3; public static final String BUNDLE_DATA_DIR = "data"; //$NON-NLS-1$ public static final String BUNDLE_FILE_NAME = "bundleFile"; //$NON-NLS-1$ public static final String FRAMEWORK_INFO = "framework.info"; //$NON-NLS-1$ @@ -140,6 +143,9 @@ public class Storage { private final FrameworkExtensionInstaller extensionInstaller; private final List cachedHeaderKeys = Arrays.asList(Constants.BUNDLE_SYMBOLICNAME, Constants.BUNDLE_ACTIVATIONPOLICY, "Service-Component"); //$NON-NLS-1$ private final boolean allowRestrictedProvides; + private final AtomicBoolean refreshMRBundles = new AtomicBoolean(false); + private final Version runtimeVersion; + private final String javaSpecVersion; public static Storage createStorage(EquinoxContainer container) throws IOException, BundleException { Storage storage = new Storage(container); @@ -153,6 +159,24 @@ public class Storage { } private Storage(EquinoxContainer container) throws IOException { + // default to Java 7 since that is our min + Version javaVersion = Version.valueOf("1.7"); //$NON-NLS-1$ + // set the profile and EE based off of the java.specification.version + String javaSpecVersionProp = System.getProperty(EquinoxConfiguration.PROP_JVM_SPEC_VERSION); + StringTokenizer st = new StringTokenizer(javaSpecVersionProp, " _-"); //$NON-NLS-1$ + javaSpecVersionProp = st.nextToken(); + try { + String[] vComps = javaSpecVersionProp.split("\\."); //$NON-NLS-1$ + // only pay attention to the first three components of the version + int major = vComps.length > 0 ? Integer.parseInt(vComps[0]) : 0; + int minor = vComps.length > 1 ? Integer.parseInt(vComps[1]) : 0; + int micro = vComps.length > 2 ? Integer.parseInt(vComps[2]) : 0; + javaVersion = new Version(major, minor, micro); + } catch (IllegalArgumentException e) { + // do nothing + } + runtimeVersion = javaVersion; + javaSpecVersion = javaSpecVersionProp; mruList = new MRUBundleFileList(getBundleFileLimit(container.getConfiguration())); equinoxContainer = container; extensionInstaller = new FrameworkExtensionInstaller(container.getConfiguration()); @@ -230,6 +254,10 @@ public class Storage { } } + public Version getRuntimeVersion() { + return runtimeVersion; + } + private int getBundleFileLimit(EquinoxConfiguration configuration) { int propValue = 100; // enable to 100 open files by default try { @@ -343,6 +371,10 @@ public class Storage { moduleContainer.resolve(Collections.singleton(systemModule), true); } } + if (refreshMRBundles.get()) { + Collection toRefresh = refreshMRJarBundles(); + moduleContainer.refresh(toRefresh); + } } catch (BundleException e) { throw new IllegalStateException("Could not create a builder for the system bundle.", e); //$NON-NLS-1$ } @@ -376,6 +408,19 @@ public class Storage { } } + private Collection refreshMRJarBundles() throws BundleException { + Collection mrJarBundles = new ArrayList<>(); + for (Module m : moduleContainer.getModules()) { + Generation generation = (Generation) m.getCurrentRevision().getRevisionInfo(); + // Note that we check the raw headers here incase we are working off an old version of the persistent storage + if (Boolean.parseBoolean(generation.getRawHeaders().get(BundleInfo.MULTI_RELEASE_HEADER))) { + refresh(m); + mrJarBundles.add(m); + } + } + return mrJarBundles; + } + public void close() { try { save(); @@ -774,6 +819,20 @@ public class Storage { return result.toString(); } + private void refresh(Module module) throws BundleException { + ModuleRevision current = module.getCurrentRevision(); + Generation currentGen = (Generation) current.getRevisionInfo(); + File content = currentGen.getContent(); + String spec = (currentGen.isReference() ? "reference:" : "") + content.toURI().toString(); //$NON-NLS-1$ //$NON-NLS-2$ + URLConnection contentConn; + try { + contentConn = getContentConnection(spec); + } catch (IOException e) { + throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$ + } + update(module, contentConn); + } + public Generation update(Module module, URLConnection content) throws BundleException { if (osgiLocation.isReadOnly()) { throw new BundleException("The framework storage area is read only.", BundleException.INVALID_OPERATION); //$NON-NLS-1$ @@ -787,7 +846,6 @@ public class Storage { } boolean isReference = in instanceof ReferenceInputStream; File staged = stageContent(in, sourceURL); - ModuleRevision current = module.getCurrentRevision(); Generation currentGen = (Generation) current.getRevisionInfo(); @@ -1146,6 +1204,8 @@ public class Storage { } out.writeInt(VERSION); + out.writeUTF(runtimeVersion.toString()); + out.writeInt(cachedHeaderKeys.size()); for (String headerKey : cachedHeaderKeys) { out.writeUTF(headerKey); @@ -1184,6 +1244,8 @@ public class Storage { out.writeUTF(NUL); } } + + out.writeBoolean(generation.isMRJar()); } saveStorageHookData(out, generations); @@ -1222,9 +1284,13 @@ public class Storage { return new HashMap<>(0); } int version = in.readInt(); - if (version != VERSION) { + if (version > VERSION || version < LOWEST_VERSION_SUPPORTED) { throw new IllegalArgumentException("Found persistent version \"" + version + "\" expecting \"" + VERSION + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } + Version savedRuntimeVersion = (version >= MR_JAR_VERSION) ? Version.parseVersion(in.readUTF()) : null; + if (savedRuntimeVersion == null || !savedRuntimeVersion.equals(runtimeVersion)) { + refreshMRBundles.set(true); + } int numCachedHeaders = in.readInt(); List storedCachedHeaderKeys = new ArrayList<>(numCachedHeaders); for (int i = 0; i < numCachedHeaders; i++) { @@ -1255,6 +1321,7 @@ public class Storage { } cachedHeaders.put(headerKey, value); } + boolean isMRJar = (version >= MR_JAR_VERSION) ? in.readBoolean() : false; File content; if (infoId == 0) { @@ -1278,7 +1345,7 @@ public class Storage { } BundleInfo info = new BundleInfo(this, infoId, infoLocation, nextGenId); - Generation generation = info.restoreGeneration(generationId, content, isDirectory, isReference, hasPackageInfo, cachedHeaders, lastModified); + Generation generation = info.restoreGeneration(generationId, content, isDirectory, isReference, hasPackageInfo, cachedHeaders, lastModified, isMRJar); result.put(infoId, generation); generations.add(generation); } @@ -1428,20 +1495,8 @@ public class Storage { return result; } - // default to Java 7 since that is our min - Version javaVersion = Version.valueOf("1.7"); //$NON-NLS-1$ - // set the profile and EE based off of the java.specification.version - String javaSpecVersion = System.getProperty(EquinoxConfiguration.PROP_JVM_SPEC_VERSION); - StringTokenizer st = new StringTokenizer(javaSpecVersion, " _-"); //$NON-NLS-1$ - javaSpecVersion = st.nextToken(); - try { - javaVersion = new Version(javaSpecVersion); - } catch (IllegalArgumentException e) { - // do nothing - } - - if (Version.valueOf("9").compareTo(javaVersion) <= 0) { //$NON-NLS-1$ - result = calculateVMProfile(javaVersion); + if (Version.valueOf("9").compareTo(runtimeVersion) <= 0) { //$NON-NLS-1$ + result = calculateVMProfile(runtimeVersion); if (result != null) { return result; } @@ -1450,7 +1505,7 @@ public class Storage { String embeddedProfileName = "-"; //$NON-NLS-1$ // If javaSE 1.8 then check for release file for profile name. - if (javaVersion != null && Version.valueOf("1.8").compareTo(javaVersion) <= 0) { //$NON-NLS-1$ + if (runtimeVersion != null && Version.valueOf("1.8").compareTo(runtimeVersion) <= 0) { //$NON-NLS-1$ String javaHome = System.getProperty("java.home"); //$NON-NLS-1$ if (javaHome != null) { File release = new File(javaHome, "release"); //$NON-NLS-1$ @@ -1479,7 +1534,7 @@ public class Storage { String javaProfile = vmProfile + PROFILE_EXT; profileIn = findInSystemBundle(systemGeneration, javaProfile); if (profileIn == null) - profileIn = getNextBestProfile(systemGeneration, JAVASE, javaVersion, embeddedProfileName); + profileIn = getNextBestProfile(systemGeneration, JAVASE, runtimeVersion, embeddedProfileName); } if (profileIn == null) // the profile url is still null then use the min profile the framework can use -- cgit v1.2.3