1 /*
2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.HashMap;
50 import java.util.Iterator;
51 import java.util.LinkedHashSet;
52 import java.util.List;
53 import java.util.Map;
54 import java.util.Set;
55 import java.util.jar.JarEntry;
56 import java.util.jar.JarFile;
57 import java.util.stream.Collectors;
58 import java.util.stream.Stream;
59 import java.util.zip.ZipFile;
60
61 import jdk.test.lib.util.FileUtils;
62
63 public class TestVersionedStream {
64 private final Path userdir;
65 private final Set<String> unversionedEntryNames;
66
67 public TestVersionedStream() throws IOException {
68 userdir = Paths.get(System.getProperty("user.dir", "."));
69
70 // These are not real class files even though they end with .class.
71 // They are resource files so jar tool validation won't reject them.
72 // But they are what we want to test, especially q/Bar.class that
73 // could be in a concealed package if this was a modular multi-release
74 // jar.
75 createFiles(
76 "base/p/Bar.class",
77 "base/p/Foo.class",
78 "base/p/Main.class",
79 "v9/p/Foo.class",
80 "v10/p/Foo.class",
81 "v10/q/Bar.class",
82 "v11/p/Bar.class",
83 "v11/p/Foo.class"
84 );
85
86 jar("cf mmr.jar -C base . --release 9 -C v9 . " +
87 "--release 10 -C v10 . --release 11 -C v11 .");
88
89 System.out.println("Contents of mmr.jar\n=======");
90
91 try(JarFile jf = new JarFile("mmr.jar")) {
92 unversionedEntryNames = jf.stream()
93 .map(je -> je.getName())
94 .peek(System.out::println)
95 .map(nm -> nm.startsWith("META-INF/versions/")
96 ? nm.replaceFirst("META-INF/versions/\\d+/", "")
97 : nm)
98 .collect(Collectors.toCollection(LinkedHashSet::new));
99 }
100
101 System.out.println("=======");
102 }
103
104 @AfterClass
105 public void close() throws IOException {
106 Files.walk(userdir, 1)
107 .filter(p -> !p.equals(userdir))
108 .forEach(p -> {
109 try {
110 if (Files.isDirectory(p)) {
111 FileUtils.deleteFileTreeWithRetry(p);
112 } else {
113 FileUtils.deleteFileIfExistsWithRetry(p);
114 }
115 } catch (IOException x) {
116 throw new UncheckedIOException(x);
117 }
118 });
119 }
120
121 @DataProvider
122 public Object[][] data() {
123 return new Object[][] {
124 {Runtime.Version.parse("8")},
125 {Runtime.Version.parse("9")},
126 {Runtime.Version.parse("10")},
127 {Runtime.Version.parse("11")},
128 {JarFile.baseVersion()},
129 {JarFile.runtimeVersion()}
130 };
131 }
132
133 @Test(dataProvider="data")
134 public void test(Runtime.Version version) throws Exception {
135 try (JarFile jf = new JarFile(new File("mmr.jar"), false, ZipFile.OPEN_READ, version);
136 Stream<JarEntry> jes = jf.versionedStream())
137 {
138 Assert.assertNotNull(jes);
139
140 // put versioned entries in list so we can reuse them
141 List<JarEntry> versionedEntries = jes.collect(Collectors.toList());
142
143 Assert.assertTrue(versionedEntries.size() > 0);
144
145 // also keep the names
146 List<String> versionedNames = new ArrayList<>(versionedEntries.size());
147
156 String name = verIt.next().getName();
157 versionedNames.add(name);
158 while (allIt.hasNext()) {
159 if (name.equals(allIt.next())) {
160 match = true;
161 break;
162 }
163 }
164 }
165 if (!match) {
166 Assert.fail("versioned entries not in same order as unversioned entries");
167 }
168
169 // verify the contents:
170 // value.[0] end of the path
171 // value.[1] versioned path/real name
172 Map<String,String[]> expected = new HashMap<>();
173
174 expected.put("p/Bar.class", new String[] { "base/p/Bar.class", "p/Bar.class" });
175 expected.put("p/Main.class", new String[] { "base/p/Main.class", "p/Main.class" });
176 switch (version.major()) {
177 case 8:
178 expected.put("p/Foo.class", new String[]
179 { "base/p/Foo.class", "p/Foo.class" });
180 break;
181 case 9:
182 expected.put("p/Foo.class", new String[]
183 { "v9/p/Foo.class", "META-INF/versions/9/p/Foo.class" });
184 break;
185 case 10:
186 expected.put("p/Foo.class", new String[]
187 { "v10/p/Foo.class", "META-INF/versions/10/p/Foo.class" });
188
189 expected.put("q/Bar.class", new String[]
190 { "v10/q/Bar.class", "META-INF/versions/10/q/Bar.class" });
191 break;
192 case 11:
193 expected.put("p/Bar.class", new String[]
194 { "v11/p/Bar.class", "META-INF/versions/11/p/Bar.class"});
195 expected.put("p/Foo.class", new String[]
196 { "v11/p/Foo.class", "META-INF/versions/11/p/Foo.class"});
197 expected.put("q/Bar.class", new String[]
198 { "q/Bar.class", "META-INF/versions/10/q/Bar.class"});
199 break;
200 default:
201 Assert.fail("Test out of date, please add more cases");
202 }
203
204 expected.entrySet().stream().forEach(e -> {
205 String name = e.getKey();
206 int i = versionedNames.indexOf(name);
207 Assert.assertTrue(i != -1, name + " not in enames");
208 JarEntry je = versionedEntries.get(i);
209 try (InputStream is = jf.getInputStream(je)) {
210 String s = new String(is.readAllBytes()).replaceAll(System.lineSeparator(), "");
211 // end of the path
212 Assert.assertTrue(s.endsWith(e.getValue()[0]), s);
213 // getRealName()
214 Assert.assertTrue(je.getRealName().equals(e.getValue()[1]));
215 } catch (IOException x) {
216 throw new UncheckedIOException(x);
217 }
218 });
219 }
220 }
221
|
1 /*
2 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.HashMap;
50 import java.util.Iterator;
51 import java.util.LinkedHashSet;
52 import java.util.List;
53 import java.util.Map;
54 import java.util.Set;
55 import java.util.jar.JarEntry;
56 import java.util.jar.JarFile;
57 import java.util.stream.Collectors;
58 import java.util.stream.Stream;
59 import java.util.zip.ZipFile;
60
61 import jdk.test.lib.util.FileUtils;
62
63 public class TestVersionedStream {
64 private final Path userdir;
65 private final Set<String> unversionedEntryNames;
66
67 private static final int LATEST_VERSION = Runtime.version().feature();
68
69 public TestVersionedStream() throws IOException {
70 userdir = Paths.get(System.getProperty("user.dir", "."));
71
72 // These are not real class files even though they end with .class.
73 // They are resource files so jar tool validation won't reject them.
74 // But they are what we want to test, especially q/Bar.class that
75 // could be in a concealed package if this was a modular multi-release
76 // jar.
77 createFiles(
78 "base/p/Bar.class",
79 "base/p/Foo.class",
80 "base/p/Main.class",
81 "v9/p/Foo.class",
82 "v10/p/Foo.class",
83 "v10/q/Bar.class",
84 "v" + LATEST_VERSION + "/p/Bar.class",
85 "v" + LATEST_VERSION + "/p/Foo.class"
86 );
87
88 jar("cf mmr.jar -C base . " +
89 "--release 9 -C v9 . " +
90 "--release 10 -C v10 . " +
91 "--release " + LATEST_VERSION + " -C v" + LATEST_VERSION + " .");
92
93 System.out.println("Contents of mmr.jar\n=======");
94
95 try(JarFile jf = new JarFile("mmr.jar")) {
96 unversionedEntryNames = jf.stream()
97 .map(je -> je.getName())
98 .peek(System.out::println)
99 .map(nm -> nm.startsWith("META-INF/versions/")
100 ? nm.replaceFirst("META-INF/versions/\\d+/", "")
101 : nm)
102 .collect(Collectors.toCollection(LinkedHashSet::new));
103 }
104
105 System.out.println("=======");
106 }
107
108 @AfterClass
109 public void close() throws IOException {
110 Files.walk(userdir, 1)
111 .filter(p -> !p.equals(userdir))
112 .forEach(p -> {
113 try {
114 if (Files.isDirectory(p)) {
115 FileUtils.deleteFileTreeWithRetry(p);
116 } else {
117 FileUtils.deleteFileIfExistsWithRetry(p);
118 }
119 } catch (IOException x) {
120 throw new UncheckedIOException(x);
121 }
122 });
123 }
124
125 @DataProvider
126 public Object[][] data() {
127 return new Object[][] {
128 {Runtime.Version.parse("8")},
129 {Runtime.Version.parse("9")},
130 {Runtime.Version.parse("10")},
131 {Runtime.Version.parse(Integer.toString(LATEST_VERSION))},
132 {JarFile.baseVersion()},
133 {JarFile.runtimeVersion()}
134 };
135 }
136
137 @Test(dataProvider="data")
138 public void test(Runtime.Version version) throws Exception {
139 try (JarFile jf = new JarFile(new File("mmr.jar"), false, ZipFile.OPEN_READ, version);
140 Stream<JarEntry> jes = jf.versionedStream())
141 {
142 Assert.assertNotNull(jes);
143
144 // put versioned entries in list so we can reuse them
145 List<JarEntry> versionedEntries = jes.collect(Collectors.toList());
146
147 Assert.assertTrue(versionedEntries.size() > 0);
148
149 // also keep the names
150 List<String> versionedNames = new ArrayList<>(versionedEntries.size());
151
160 String name = verIt.next().getName();
161 versionedNames.add(name);
162 while (allIt.hasNext()) {
163 if (name.equals(allIt.next())) {
164 match = true;
165 break;
166 }
167 }
168 }
169 if (!match) {
170 Assert.fail("versioned entries not in same order as unversioned entries");
171 }
172
173 // verify the contents:
174 // value.[0] end of the path
175 // value.[1] versioned path/real name
176 Map<String,String[]> expected = new HashMap<>();
177
178 expected.put("p/Bar.class", new String[] { "base/p/Bar.class", "p/Bar.class" });
179 expected.put("p/Main.class", new String[] { "base/p/Main.class", "p/Main.class" });
180 int majorVersion = version.major();
181 switch (majorVersion) {
182 case 8:
183 expected.put("p/Foo.class", new String[]
184 { "base/p/Foo.class", "p/Foo.class" });
185 break;
186 case 9:
187 expected.put("p/Foo.class", new String[]
188 { "v9/p/Foo.class", "META-INF/versions/9/p/Foo.class" });
189 break;
190 case 10:
191 expected.put("p/Foo.class", new String[]
192 { "v10/p/Foo.class", "META-INF/versions/10/p/Foo.class" });
193
194 expected.put("q/Bar.class", new String[]
195 { "v10/q/Bar.class", "META-INF/versions/10/q/Bar.class" });
196 break;
197 default:
198 if (majorVersion == LATEST_VERSION) {
199 expected.put("p/Bar.class",
200 new String[] { "v" + LATEST_VERSION + "/p/Bar.class",
201 "META-INF/versions/" + LATEST_VERSION + "/p/Bar.class"});
202 expected.put("p/Foo.class",
203 new String[]{ "v" + LATEST_VERSION + "/p/Foo.class",
204 "META-INF/versions/" + LATEST_VERSION + "/p/Foo.class"});
205 expected.put("q/Bar.class",
206 new String[] { "q/Bar.class", "META-INF/versions/10/q/Bar.class"});
207 } else {
208 Assert.fail("Test out of date, please add more cases");
209 }
210 }
211
212 expected.entrySet().stream().forEach(e -> {
213 String name = e.getKey();
214 int i = versionedNames.indexOf(name);
215 Assert.assertTrue(i != -1, name + " not in enames");
216 JarEntry je = versionedEntries.get(i);
217 try (InputStream is = jf.getInputStream(je)) {
218 String s = new String(is.readAllBytes()).replaceAll(System.lineSeparator(), "");
219 // end of the path
220 Assert.assertTrue(s.endsWith(e.getValue()[0]), s);
221 // getRealName()
222 Assert.assertTrue(je.getRealName().equals(e.getValue()[1]));
223 } catch (IOException x) {
224 throw new UncheckedIOException(x);
225 }
226 });
227 }
228 }
229
|