diff options
author | Thomas Watson | 2017-12-15 20:12:53 +0000 |
---|---|---|
committer | Thomas Watson | 2017-12-15 20:14:02 +0000 |
commit | 847091d8de7ec31db33fa4d3d7189eb872330eba (patch) | |
tree | 250479ac58f2212bb0c2ab0d0de1c48bc53dad1f | |
parent | 90eb309b4bf2228e6012ec868fd38f6bc550ddb3 (diff) | |
download | rt.equinox.framework-847091d8de7ec31db33fa4d3d7189eb872330eba.tar.gz rt.equinox.framework-847091d8de7ec31db33fa4d3d7189eb872330eba.tar.xz rt.equinox.framework-847091d8de7ec31db33fa4d3d7189eb872330eba.zip |
Bug 528422 - [osgi R7] Support for Multi-Release jarsI20180101-2000I20171231-2000I20171230-1500I20171229-2000I20171228-2000I20171227-2000I20171226-2000I20171225-2000I20171224-2000I20171223-1500I20171222-2000I20171221-2000I20171220-2000I20171219-2000I20171218-2000I20171217-2000I20171216-1500I20171215-2000
Add check to prevent versioning of files under META-INF
Change-Id: Ibb7afa65e0da75c012ec024cd0d79fa774cf9f51
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
8 files changed, 195 insertions, 12 deletions
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestService.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestService.java new file mode 100644 index 000000000..e9452025e --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestService.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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 interface TestService { + // Just a marker +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestService9.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestService9.java new file mode 100644 index 000000000..af5512fd1 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestService9.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 TestService9 implements TestService { + public String toString() { + return "SERVICE_9"; + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestServiceBase.java b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestServiceBase.java new file mode 100644 index 000000000..bd3dced0f --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/mrBundleInputBase/multi/release/test/TestServiceBase.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 TestServiceBase implements TestService { + public String toString() { + return "SERVICE_BASE"; + } +} 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 index 4f774b098..0b075aefc 100644 --- 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 @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.ServiceLoader; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; @@ -99,12 +100,18 @@ public class MultiReleaseJarTests extends AbstractBundleTests { 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/TestService.class", getBytes("multi/release/test/TestService.class", base)); + bundleEntries.put("multi/release/test/TestService9.class", getBytes("multi/release/test/TestService9.class", base)); + bundleEntries.put("multi/release/test/TestServiceBase.class", getBytes("multi/release/test/TestServiceBase.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/services/", null); + bundleEntries.put("META-INF/services/multi.release.test.TestService", "multi.release.test.TestServiceBase".getBytes("UTF-8")); bundleEntries.put("META-INF/versions/", null); bundleEntries.put("META-INF/versions/8/", null); bundleEntries.put("META-INF/versions/8/multi/", null); @@ -115,6 +122,12 @@ public class MultiReleaseJarTests extends AbstractBundleTests { 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/META-INF/", null); + bundleEntries.put("META-INF/versions/9/META-INF/addedFor9.txt", "added for 9".getBytes("UTF-8")); + bundleEntries.put("META-INF/versions/9/META-INF/addedDirFor9/", null); + bundleEntries.put("META-INF/versions/9/META-INF/addedDirFor9/addedFor9.txt", "added for 9".getBytes("UTF-8")); + bundleEntries.put("META-INF/versions/9/META-INF/services/", null); + bundleEntries.put("META-INF/versions/9/META-INF/services/multi.release.test.TestService", "multi.release.test.TestService9".getBytes("UTF-8")); 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); @@ -862,4 +875,76 @@ public class MultiReleaseJarTests extends AbstractBundleTests { } } + public void testMultiReleasePreventMetaInfServiceVersions() throws Exception { + System.setProperty("java.specification.version", "9"); + + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Map<String, String> configMap = Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath()); + Equinox equinox = new Equinox(configMap); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle("reference:" + mrJarBundle.toURI().toString()); + mrBundle.start(); + + Class<?> testServiceClass = mrBundle.loadClass("multi.release.test.TestService"); + ServiceLoader<?> loader = ServiceLoader.load(testServiceClass, mrBundle.adapt(BundleWiring.class).getClassLoader()); + Object testService = loader.iterator().next(); + assertEquals("Wrong service found.", "SERVICE_BASE", testService.toString()); + } finally { + equinox.stop(); + equinox.waitForStop(1000); + } + } + + public void testMultiReleasePreventMetaInfResourceURLs() throws Exception { + System.setProperty("java.specification.version", "9"); + + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Map<String, String> configMap = Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath()); + Equinox equinox = new Equinox(configMap); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle("reference:" + mrJarBundle.toURI().toString()); + mrBundle.start(); + + URL existingResource = mrBundle.getResource("multi/release/test/testResourceAdd9.txt"); + assertNotNull("Did not find Java 9 added resource.", existingResource); + URL metaInfResource = new URL(existingResource, "/META-INF/addedFor9.txt"); + try { + metaInfResource.openStream().close(); + fail("Expected error opening versioned META-INF resource."); + } catch (IOException e) { + // expected + } + + } finally { + equinox.stop(); + equinox.waitForStop(1000); + } + } + + public void testMultiReleasePreventMetaInfVersionListing() throws Exception { + System.setProperty("java.specification.version", "9"); + + File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$ + Map<String, String> configMap = Collections.singletonMap(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath()); + Equinox equinox = new Equinox(configMap); + + try { + equinox.start(); + BundleContext systemContext = equinox.getBundleContext(); + Bundle mrBundle = systemContext.installBundle("reference:" + mrJarBundle.toURI().toString()); + mrBundle.start(); + + Collection<String> list = mrBundle.adapt(BundleWiring.class).listResources("/META-INF/", "*.txt", 0); + assertTrue("Found versioned META-INF resources: " + list, list.isEmpty()); + } finally { + equinox.stop(); + equinox.waitForStop(1000); + } + } } 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 09ceba150..d627a496c 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 @@ -102,10 +102,10 @@ public class ClasspathEntry { } List<BundleFile> mrBundleFiles = new ArrayList<>(); for (int i = storage.getRuntimeVersion().getMajor(); i > 8; i--) { - String versionPath = "META-INF/versions/" + i + '/'; //$NON-NLS-1$ + String versionPath = BundleInfo.MULTI_RELEASE_VERSIONS + i + '/'; BundleEntry versionEntry = bundlefile.getEntry(versionPath); if (versionEntry != null) { - mrBundleFiles.add(storage.createNestedBundleFile(versionPath, bundlefile, generation)); + mrBundleFiles.add(storage.createNestedBundleFile(versionPath, bundlefile, generation, BundleInfo.MULTI_RELEASE_FILTER_PREFIXES)); } } return Collections.unmodifiableList(mrBundleFiles); 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 286bcb7d1..e4ebfd822 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 @@ -53,6 +53,8 @@ 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 static final String MULTI_RELEASE_VERSIONS = "META-INF/versions/"; //$NON-NLS-1$ + public static final Collection<String> MULTI_RELEASE_FILTER_PREFIXES = Collections.singleton("META-INF/"); //$NON-NLS-1$ public final class Generation { private final long generationId; 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 4a1156ac8..5e759f0a0 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 @@ -1045,8 +1045,12 @@ public class Storage { } public BundleFile createNestedBundleFile(String nestedDir, BundleFile bundleFile, Generation generation) { + return createNestedBundleFile(nestedDir, bundleFile, generation, Collections.<String> emptyList()); + } + + public BundleFile createNestedBundleFile(String nestedDir, BundleFile bundleFile, Generation generation, Collection<String> filterPrefixes) { // here we assume the content is a path offset into the base bundle file; create a NestedDirBundleFile - return wrapBundleFile(new NestedDirBundleFile(bundleFile, nestedDir), generation, false); + return wrapBundleFile(new NestedDirBundleFile(bundleFile, nestedDir, filterPrefixes), generation, false); } public BundleFile wrapBundleFile(BundleFile bundleFile, Generation generation, boolean isBase) { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java index 718441417..842295272 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java @@ -13,6 +13,8 @@ package org.eclipse.osgi.storage.bundlefile; import java.io.File; import java.io.IOException; +import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; /** @@ -28,46 +30,87 @@ import java.util.Enumeration; */ public class NestedDirBundleFile extends BundleFile { private final BundleFile baseBundleFile; - private final String cp; + private final String nestedDirName; + private final Collection<String> filterPrefixes; /** * Constructs a NestedDirBundleFile * @param baseBundlefile the base bundle file - * @param cp + * @param nestedDirName */ - public NestedDirBundleFile(BundleFile baseBundlefile, String cp) { + public NestedDirBundleFile(BundleFile baseBundlefile, String nestedDirName) { + this(baseBundlefile, nestedDirName, Collections.<String> emptyList()); + } + + /** + * Constructs a NestedDirBundleFile + * @param baseBundlefile the base bundle file + * @param nestedDirName + * @param filterPrefixes the prefixes to filter out for the bundle file + */ + public NestedDirBundleFile(BundleFile baseBundlefile, String nestedDirName, Collection<String> filterPrefixes) { super(baseBundlefile.getBaseFile()); this.baseBundleFile = baseBundlefile; - if (cp.charAt(cp.length() - 1) != '/') { - cp = cp + '/'; + if (nestedDirName.charAt(nestedDirName.length() - 1) != '/') { + nestedDirName = nestedDirName + '/'; } - this.cp = cp; + this.nestedDirName = nestedDirName; + this.filterPrefixes = filterPrefixes; } public void close() { // do nothing. } + private boolean filterPath(String path) { + if (path.length() > 0 && path.charAt(0) == '/') + path = path.substring(1); + for (String prefix : filterPrefixes) { + if (path.startsWith(prefix)) { + return true; + } + } + return false; + } + + private boolean filterDir(String path) { + if (filterPrefixes.isEmpty()) { + return false; + } + if (path.length() > 0 && path.charAt(path.length() - 1) != '/') { + path = path + '/'; + } + return filterPath(path); + } + public BundleEntry getEntry(String path) { + if (filterPath(path)) { + return null; + } return baseBundleFile.getEntry(prependNestedDir(path)); } public boolean containsDir(String dir) { if (dir == null) return false; - + if (filterPath(dir)) { + return false; + } return baseBundleFile.containsDir(prependNestedDir(dir)); } private String prependNestedDir(String path) { if (path.length() > 0 && path.charAt(0) == '/') path = path.substring(1); - return new StringBuffer(cp).append(path).toString(); + return new StringBuffer(nestedDirName).append(path).toString(); } public Enumeration<String> getEntryPaths(String path, boolean recurse) { + if (filterDir(path)) { + return null; + } final Enumeration<String> basePaths = baseBundleFile.getEntryPaths(prependNestedDir(path), recurse); - final int cpLength = cp.length(); + final int cpLength = nestedDirName.length(); if (basePaths == null) return null; return new Enumeration<String>() { |