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 */
23
24 /*
25 * @test
26 * @bug 8144355 8144062 8176709 8194070 8193802
27 * @summary Test aliasing additions to ZipFileSystem for multi-release jar files
28 * @library /lib/testlibrary/java/util/jar
29 * @modules jdk.compiler
30 * jdk.jartool
31 * jdk.zipfs
32 * @build Compiler JarBuilder CreateMultiReleaseTestJars
33 * @run testng MultiReleaseJarTest
34 */
35
36 import java.io.IOException;
37 import java.lang.invoke.MethodHandle;
38 import java.lang.invoke.MethodHandles;
39 import java.lang.invoke.MethodType;
40 import java.lang.Runtime.Version;
41 import java.net.URI;
42 import java.nio.file.*;
43 import java.util.HashMap;
44 import java.util.Map;
45 import java.util.concurrent.atomic.AtomicInteger;
46
71 creator.buildShortMultiReleaseJar();
72 String ssp = Paths.get(userdir, "unversioned.jar").toUri().toString();
73 uvuri = new URI("jar", ssp , null);
74 ssp = Paths.get(userdir, "multi-release.jar").toUri().toString();
75 mruri = new URI("jar", ssp, null);
76 ssp = Paths.get(userdir, "short-multi-release.jar").toUri().toString();
77 smruri = new URI("jar", ssp, null);
78 entryName = className.replace('.', '/') + ".class";
79 }
80
81 public void close() throws IOException {
82 Files.delete(Paths.get(userdir, "unversioned.jar"));
83 Files.delete(Paths.get(userdir, "multi-release.jar"));
84 Files.delete(Paths.get(userdir, "short-multi-release.jar"));
85 }
86
87 @DataProvider(name="strings")
88 public Object[][] createStrings() {
89 return new Object[][]{
90 {"runtime", MAJOR_VERSION},
91 {"-20", 8},
92 {"0", 8},
93 {"8", 8},
94 {"9", 9},
95 {Integer.toString(MAJOR_VERSION), MAJOR_VERSION},
96 {Integer.toString(MAJOR_VERSION+1), MAJOR_VERSION},
97 {"50", MAJOR_VERSION}
98 };
99 }
100
101 @DataProvider(name="integers")
102 public Object[][] createIntegers() {
103 return new Object[][] {
104 {Integer.valueOf(-5), 8},
105 {Integer.valueOf(0), 8},
106 {Integer.valueOf(8), 8},
107 {Integer.valueOf(9), 9},
108 {Integer.valueOf(MAJOR_VERSION), MAJOR_VERSION},
109 {Integer.valueOf(MAJOR_VERSION + 1), MAJOR_VERSION},
110 {Integer.valueOf(100), MAJOR_VERSION}
111 };
112 }
113
114 @DataProvider(name="versions")
115 public Object[][] createVersions() {
116 return new Object[][] {
117 {Version.parse("8"), 8},
118 {Version.parse("9"), 9},
119 {Version.parse(Integer.toString(MAJOR_VERSION)), MAJOR_VERSION},
120 {Version.parse(Integer.toString(MAJOR_VERSION) + 1), MAJOR_VERSION},
121 {Version.parse("100"), MAJOR_VERSION}
122 };
123 }
124
125 // Not the best test but all I can do since ZipFileSystem and JarFileSystem
126 // are not public, so I can't use (fs instanceof ...)
127 @Test
128 public void testNewFileSystem() throws Exception {
129 Map<String,String> env = new HashMap<>();
130 // no configuration, treat multi-release jar as unversioned
131 try (FileSystem fs = FileSystems.newFileSystem(mruri, env)) {
132 Assert.assertTrue(readAndCompare(fs, 8));
133 }
134 env.put("multi-release", "runtime");
135 // a configuration and jar file is multi-release
136 try (FileSystem fs = FileSystems.newFileSystem(mruri, env)) {
137 Assert.assertTrue(readAndCompare(fs, MAJOR_VERSION));
138 }
139 // a configuration but jar file is unversioned
140 try (FileSystem fs = FileSystems.newFileSystem(uvuri, env)) {
141 Assert.assertTrue(readAndCompare(fs, 8));
142 }
143 }
144
145 private boolean readAndCompare(FileSystem fs, int expected) throws IOException {
146 Path path = fs.getPath("version/Version.java");
147 String src = new String(Files.readAllBytes(path));
148 return src.contains("return " + expected);
149 }
150
151 @Test(dataProvider="strings")
152 public void testStrings(String value, int expected) throws Throwable {
153 stringEnv.put("multi-release", value);
154 runTest(stringEnv, expected);
155 }
156
157 @Test(dataProvider="integers")
158 public void testIntegers(Integer value, int expected) throws Throwable {
159 integerEnv.put("multi-release", value);
160 runTest(integerEnv, expected);
161 }
162
163 @Test(dataProvider="versions")
164 public void testVersions(Version value, int expected) throws Throwable {
165 versionEnv.put("multi-release", value);
166 runTest(versionEnv, expected);
167 }
168
169 @Test
170 public void testShortJar() throws Throwable {
171 integerEnv.put("multi-release", Integer.valueOf(MAJOR_VERSION));
172 runTest(smruri, integerEnv, MAJOR_VERSION);
173 integerEnv.put("multi-release", Integer.valueOf(9));
174 runTest(smruri, integerEnv, 8);
175 }
176
177 private void runTest(Map<String,?> env, int expected) throws Throwable {
178 runTest(mruri, env, expected);
179 }
180
181 private void runTest(URI uri, Map<String,?> env, int expected) throws Throwable {
182 try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
183 Path version = fs.getPath(entryName);
184 byte [] bytes = Files.readAllBytes(version);
185 Class<?> vcls = (new ByteArrayClassLoader(fs)).defineClass(className, bytes);
186 MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt);
187 Assert.assertEquals((int)mh.invoke(vcls.getDeclaredConstructor().newInstance()), expected);
188 }
189 }
190
191 @Test
192 public void testIsMultiReleaseJar() throws Exception {
193 // Re-examine commented out tests as part of JDK-8176843
194 testCustomMultiReleaseValue("true", true);
195 testCustomMultiReleaseValue("true\r\nOther: value", true);
196 testCustomMultiReleaseValue("true\nOther: value", true);
197 //testCustomMultiReleaseValue("true\rOther: value", true);
198
199 testCustomMultiReleaseValue("false", false);
200 testCustomMultiReleaseValue(" true", false);
201 testCustomMultiReleaseValue("true ", false);
202 //testCustomMultiReleaseValue("true\n ", false);
203 //testCustomMultiReleaseValue("true\r ", false);
204 //testCustomMultiReleaseValue("true\n true", false);
205 //testCustomMultiReleaseValue("true\r\n true", false);
206 }
207
208 @Test
209 public void testMultiReleaseJarWithNonVersionDir() throws Exception {
210 String jfname = "multi-release-non-ver.jar";
211 Path jfpath = Paths.get(jfname);
212 URI uri = new URI("jar", jfpath.toUri().toString() , null);
213 JarBuilder jb = new JarBuilder(jfname);
214 jb.addAttribute("Multi-Release", "true");
215 jb.build();
216 Map<String,String> env = Map.of("multi-release", "runtime");
217 try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
218 Assert.assertTrue(true);
219 }
220 Files.delete(jfpath);
221 }
222
223 private static final AtomicInteger JAR_COUNT = new AtomicInteger(0);
224
225 private void testCustomMultiReleaseValue(String value, boolean expected)
226 throws Exception {
227 String fileName = "custom-mr" + JAR_COUNT.incrementAndGet() + ".jar";
228 creator.buildCustomMultiReleaseJar(fileName, value, Map.of(),
229 /*addEntries*/true);
230
231 Map<String,String> env = Map.of("multi-release", "runtime");
232 Path filePath = Paths.get(userdir, fileName);
233 String ssp = filePath.toUri().toString();
234 URI customJar = new URI("jar", ssp , null);
235 try (FileSystem fs = FileSystems.newFileSystem(customJar, env)) {
236 if (expected) {
237 Assert.assertTrue(readAndCompare(fs, MAJOR_VERSION));
238 } else {
239 Assert.assertTrue(readAndCompare(fs, 8));
240 }
241 }
242 Files.delete(filePath);
243 }
244
245 private static class ByteArrayClassLoader extends ClassLoader {
246 final private FileSystem fs;
247
248 ByteArrayClassLoader(FileSystem fs) {
249 super(null);
250 this.fs = fs;
251 }
|
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 */
23
24 /*
25 * @test
26 * @bug 8144355 8144062 8176709 8194070 8193802 8231093
27 * @summary Test aliasing additions to ZipFileSystem for multi-release jar files
28 * @library /lib/testlibrary/java/util/jar
29 * @modules jdk.compiler
30 * jdk.jartool
31 * jdk.zipfs
32 * @build Compiler JarBuilder CreateMultiReleaseTestJars
33 * @run testng MultiReleaseJarTest
34 */
35
36 import java.io.IOException;
37 import java.lang.invoke.MethodHandle;
38 import java.lang.invoke.MethodHandles;
39 import java.lang.invoke.MethodType;
40 import java.lang.Runtime.Version;
41 import java.net.URI;
42 import java.nio.file.*;
43 import java.util.HashMap;
44 import java.util.Map;
45 import java.util.concurrent.atomic.AtomicInteger;
46
71 creator.buildShortMultiReleaseJar();
72 String ssp = Paths.get(userdir, "unversioned.jar").toUri().toString();
73 uvuri = new URI("jar", ssp , null);
74 ssp = Paths.get(userdir, "multi-release.jar").toUri().toString();
75 mruri = new URI("jar", ssp, null);
76 ssp = Paths.get(userdir, "short-multi-release.jar").toUri().toString();
77 smruri = new URI("jar", ssp, null);
78 entryName = className.replace('.', '/') + ".class";
79 }
80
81 public void close() throws IOException {
82 Files.delete(Paths.get(userdir, "unversioned.jar"));
83 Files.delete(Paths.get(userdir, "multi-release.jar"));
84 Files.delete(Paths.get(userdir, "short-multi-release.jar"));
85 }
86
87 @DataProvider(name="strings")
88 public Object[][] createStrings() {
89 return new Object[][]{
90 {"runtime", MAJOR_VERSION},
91 {"9.0.1", 9},
92 {MAJOR_VERSION + ".0.1", MAJOR_VERSION},
93 {null, 8},
94 {"8", 8},
95 {"9", 9},
96 {Integer.toString(MAJOR_VERSION), MAJOR_VERSION},
97 {Integer.toString(MAJOR_VERSION+1), MAJOR_VERSION},
98 {"50", MAJOR_VERSION}
99 };
100 }
101
102 @DataProvider(name="integers")
103 public Object[][] createIntegers() {
104 return new Object[][] {
105 {null, 8},
106 {Integer.valueOf(8), 8},
107 {Integer.valueOf(9), 9},
108 {Integer.valueOf(MAJOR_VERSION), MAJOR_VERSION},
109 {Integer.valueOf(MAJOR_VERSION + 1), MAJOR_VERSION},
110 {Integer.valueOf(100), MAJOR_VERSION}
111 };
112 }
113
114 @DataProvider(name="versions")
115 public Object[][] createVersions() {
116 return new Object[][] {
117 {null, 8},
118 {Version.parse("8"), 8},
119 {Version.parse("9"), 9},
120 {Version.parse(Integer.toString(MAJOR_VERSION)), MAJOR_VERSION},
121 {Version.parse(Integer.toString(MAJOR_VERSION) + 1), MAJOR_VERSION},
122 {Version.parse("100"), MAJOR_VERSION}
123 };
124 }
125
126 @DataProvider(name="invalidVersions")
127 public Object[][] invalidVersions() {
128 return new Object[][] {
129 {Map.of("releaseVersion", "")},
130 {Map.of("releaseVersion", "invalid")},
131 {Map.of("releaseVersion", "0")},
132 {Map.of("releaseVersion", "-1")},
133 {Map.of("releaseVersion",Integer.valueOf(0))},
134 {Map.of("releaseVersion",Integer.valueOf(-1))}
135 };
136 }
137
138 // Not the best test but all I can do since ZipFileSystem and JarFileSystem
139 // are not public, so I can't use (fs instanceof ...)
140 @Test
141 public void testNewFileSystem() throws Exception {
142 Map<String,String> env = new HashMap<>();
143 // no configuration, treat multi-release jar as unversioned
144 try (FileSystem fs = FileSystems.newFileSystem(mruri, env)) {
145 Assert.assertTrue(readAndCompare(fs, 8));
146 }
147 env.put("releaseVersion", "runtime");
148 // a configuration and jar file is multi-release
149 try (FileSystem fs = FileSystems.newFileSystem(mruri, env)) {
150 Assert.assertTrue(readAndCompare(fs, MAJOR_VERSION));
151 }
152 // a configuration but jar file is unversioned
153 try (FileSystem fs = FileSystems.newFileSystem(uvuri, env)) {
154 Assert.assertTrue(readAndCompare(fs, 8));
155 }
156 }
157
158 private boolean readAndCompare(FileSystem fs, int expected) throws IOException {
159 Path path = fs.getPath("version/Version.java");
160 String src = new String(Files.readAllBytes(path));
161 return src.contains("return " + expected);
162 }
163
164 @Test(dataProvider="strings")
165 public void testStrings(String value, int expected) throws Throwable {
166 stringEnv.put("releaseVersion", value);
167 runTest(stringEnv, expected);
168 }
169
170 @Test(dataProvider="integers")
171 public void testIntegers(Integer value, int expected) throws Throwable {
172 integerEnv.put("releaseVersion", value);
173 runTest(integerEnv, expected);
174 }
175
176 @Test(dataProvider="versions")
177 public void testVersions(Version value, int expected) throws Throwable {
178 versionEnv.put("releaseVersion", value);
179 runTest(versionEnv, expected);
180 }
181
182 @Test
183 public void testShortJar() throws Throwable {
184 integerEnv.put("releaseVersion", Integer.valueOf(MAJOR_VERSION));
185 runTest(smruri, integerEnv, MAJOR_VERSION);
186 integerEnv.put("releaseVersion", Integer.valueOf(9));
187 runTest(smruri, integerEnv, 8);
188 }
189
190 /**
191 * Validate that an invalid value for the "releaseVersion" property throws
192 * an {@code IllegalArgumentException}
193 * @param env Zip FS map
194 * @throws Throwable Exception thrown for anything other than the expected
195 * IllegalArgumentException
196 */
197 @Test(dataProvider="invalidVersions")
198 public void testInvalidVersions(Map<String,?> env) throws Throwable {
199 Assert.assertThrows(IllegalArgumentException.class, () ->
200 FileSystems.newFileSystem(Path.of(userdir,
201 "multi-release.jar"), env));
202 }
203
204 // The following tests are for backwards compatibility to validate that
205 // the original property still works
206 @Test(dataProvider="strings")
207 public void testMRStrings(String value, int expected) throws Throwable {
208 stringEnv.clear();
209 stringEnv.put("multi-release", value);
210 runTest(stringEnv, expected);
211 }
212
213 @Test(dataProvider="integers")
214 public void testMRIntegers(Integer value, int expected) throws Throwable {
215 integerEnv.clear();
216 integerEnv.put("multi-release", value);
217 runTest(integerEnv, expected);
218 }
219
220 @Test(dataProvider="versions")
221 public void testMRVersions(Version value, int expected) throws Throwable {
222 versionEnv.clear();
223 versionEnv.put("multi-release", value);
224 runTest(versionEnv, expected);
225 }
226
227 private void runTest(Map<String,?> env, int expected) throws Throwable {
228 runTest(mruri, env, expected);
229 }
230
231 private void runTest(URI uri, Map<String,?> env, int expected) throws Throwable {
232 try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
233 Path version = fs.getPath(entryName);
234 byte [] bytes = Files.readAllBytes(version);
235 Class<?> vcls = (new ByteArrayClassLoader(fs)).defineClass(className, bytes);
236 MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt);
237 Assert.assertEquals((int)mh.invoke(vcls.getDeclaredConstructor().newInstance()), expected);
238 }
239 }
240
241 @Test
242 public void testIsMultiReleaseJar() throws Exception {
243 // Re-examine commented out tests as part of JDK-8176843
244 testCustomMultiReleaseValue("true", true);
245 testCustomMultiReleaseValue("true\r\nOther: value", true);
246 testCustomMultiReleaseValue("true\nOther: value", true);
247 //testCustomMultiReleaseValue("true\rOther: value", true);
248
249 testCustomMultiReleaseValue("false", false);
250 testCustomMultiReleaseValue(" true", false);
251 testCustomMultiReleaseValue("true ", false);
252 //testCustomMultiReleaseValue("true\n ", false);
253 //testCustomMultiReleaseValue("true\r ", false);
254 //testCustomMultiReleaseValue("true\n true", false);
255 //testCustomMultiReleaseValue("true\r\n true", false);
256 }
257
258 @Test
259 public void testMultiReleaseJarWithNonVersionDir() throws Exception {
260 String jfname = "multi-release-non-ver.jar";
261 Path jfpath = Paths.get(jfname);
262 URI uri = new URI("jar", jfpath.toUri().toString() , null);
263 JarBuilder jb = new JarBuilder(jfname);
264 jb.addAttribute("Multi-Release", "true");
265 jb.build();
266 Map<String,String> env = Map.of("releaseVersion", "runtime");
267 try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
268 Assert.assertTrue(true);
269 }
270 Files.delete(jfpath);
271 }
272
273 private static final AtomicInteger JAR_COUNT = new AtomicInteger(0);
274
275 private void testCustomMultiReleaseValue(String value, boolean expected)
276 throws Exception {
277 String fileName = "custom-mr" + JAR_COUNT.incrementAndGet() + ".jar";
278 creator.buildCustomMultiReleaseJar(fileName, value, Map.of(),
279 /*addEntries*/true);
280
281 Map<String,String> env = Map.of("releaseVersion", "runtime");
282 Path filePath = Paths.get(userdir, fileName);
283 String ssp = filePath.toUri().toString();
284 URI customJar = new URI("jar", ssp , null);
285 try (FileSystem fs = FileSystems.newFileSystem(customJar, env)) {
286 if (expected) {
287 Assert.assertTrue(readAndCompare(fs, MAJOR_VERSION));
288 } else {
289 Assert.assertTrue(readAndCompare(fs, 8));
290 }
291 }
292 Files.delete(filePath);
293 }
294
295 private static class ByteArrayClassLoader extends ClassLoader {
296 final private FileSystem fs;
297
298 ByteArrayClassLoader(FileSystem fs) {
299 super(null);
300 this.fs = fs;
301 }
|