< prev index next >

test/jdk/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java

Print this page


   1 /*
   2  * Copyright (c) 2015, 2016, 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  */
  23 
  24 /*
  25  * @test
  26  * @bug 8132734 8144062 8159785
  27  * @summary Test that URL connections to multi-release jars can be runtime versioned
  28  * @library /lib/testlibrary/java/util/jar
  29  * @modules jdk.compiler
  30  *          jdk.httpserver
  31  *          jdk.jartool
  32  * @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer
  33  * @run testng MultiReleaseJarURLConnection
  34  */
  35 
  36 import java.io.IOException;
  37 import java.io.InputStream;
  38 import java.lang.invoke.MethodHandle;
  39 import java.lang.invoke.MethodHandles;
  40 import java.lang.invoke.MethodType;
  41 import java.net.JarURLConnection;
  42 import java.net.URL;
  43 import java.net.URLClassLoader;
  44 import java.net.URLConnection;
  45 import java.nio.file.Files;
  46 import java.nio.file.Paths;


  79         if (server != null)
  80             server.stop();
  81         Files.delete(Paths.get(unversioned));
  82         Files.delete(Paths.get(unsigned));
  83         Files.delete(Paths.get(signed));
  84     }
  85 
  86     @DataProvider(name = "data")
  87     public Object[][] createData() {
  88         return new Object[][]{
  89                 {"unversioned", unversioned},
  90                 {"unsigned", unsigned},
  91                 {"signed", signed}
  92         };
  93     }
  94 
  95     @Test(dataProvider = "data")
  96     public void testRuntimeVersioning(String style, String file) throws Exception {
  97         String urlFile = "jar:file:" + file + "!/";
  98         String baseUrlEntry = urlFile + "version/Version.java";
  99         String rtreturn = "return " + Runtime.version().major();
 100 
 101         Assert.assertTrue(readAndCompare(new URL(baseUrlEntry), "return 8"));
 102         // #runtime is "magic" for a multi-release jar, but not for unversioned jar
 103         Assert.assertTrue(readAndCompare(new URL(baseUrlEntry + "#runtime"),
 104                 style.equals("unversioned") ? "return 8" : rtreturn));
 105         // #fragment or any other fragment is not magic
 106         Assert.assertTrue(readAndCompare(new URL(baseUrlEntry + "#fragment"), "return 8"));
 107         // cached entities not affected
 108         Assert.assertTrue(readAndCompare(new URL(baseUrlEntry), "return 8"));
 109 
 110         // the following tests will not work with unversioned jars
 111         if (style.equals("unversioned")) return;

 112 
 113         // direct access to versioned entry
 114         String versUrlEntry = urlFile + "META-INF/versions/" + Runtime.version().major()

 115                 + "/version/Version.java";
 116         Assert.assertTrue(readAndCompare(new URL(versUrlEntry), rtreturn));
 117         // adding any fragment does not change things
 118         Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#runtime"), rtreturn));
 119         Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#fragment"), rtreturn));
 120 
 121         // it really doesn't change things
 122         versUrlEntry = urlFile + "META-INF/versions/10/version/Version.java";
 123         Assert.assertTrue(readAndCompare(new URL(versUrlEntry), "return 10"));
 124         Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#runtime"), "return 10"));
 125         Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#fragment"), "return 10"));
 126     }
 127 
 128     @Test(dataProvider = "data")
 129     public void testCachedJars(String style, String file) throws Exception {
 130         String urlFile = "jar:file:" + file + "!/";
 131 
 132         URL rootUrl = new URL(urlFile);
 133         JarURLConnection juc = (JarURLConnection)rootUrl.openConnection();
 134         JarFile rootJar = juc.getJarFile();
 135         Runtime.Version root = rootJar.getVersion();
 136 
 137         URL runtimeUrl = new URL(urlFile + "#runtime");
 138         juc = (JarURLConnection)runtimeUrl.openConnection();
 139         JarFile runtimeJar = juc.getJarFile();
 140         Runtime.Version runtime = runtimeJar.getVersion();
 141         if (style.equals("unversioned")) {
 142             Assert.assertEquals(root, runtime);
 143         } else {
 144             Assert.assertNotEquals(root, runtime);
 145         }


 172                 {"unsigned", new URL("jar:file:" + unsigned + "!/")},
 173                 {"signed", new URL("jar:file:" + signed + "!/")},
 174                 // external jar received via http protocol
 175                 {"http", new URL("jar:http://localhost:" + server.getPort() + "/multi-release.jar!/")},
 176                 {"http", new URL("http://localhost:" + server.getPort() + "/multi-release.jar")},
 177 
 178         };
 179     }
 180 
 181     @Test(dataProvider = "resourcedata")
 182     public void testResources(String style, URL url) throws Throwable {
 183         //System.out.println("  testing " + style + " url: " + url);
 184         URL[] urls = {url};
 185         URLClassLoader cldr = new URLClassLoader(urls);
 186         Class<?> vcls = cldr.loadClass("version.Version");
 187 
 188         // verify we are loading a runtime versioned class
 189         MethodType mt = MethodType.methodType(int.class);
 190         MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt);
 191         Assert.assertEquals((int)mh.invoke(vcls.newInstance()),
 192                 style.equals("unversioned") ? 8 : Runtime.version().major());


 193 
 194         // now get a resource and verify that we don't have a fragment attached
 195         Enumeration<URL> vclsUrlEnum = cldr.getResources("version/Version.class");
 196         Assert.assertTrue(vclsUrlEnum.hasMoreElements());
 197         URL vclsUrls[] = new URL[] {
 198             vcls.getResource("/version/Version.class"),
 199             vcls.getResource("Version.class"),
 200             cldr.getResource("version/Version.class"),
 201             vclsUrlEnum.nextElement()
 202         };
 203         Assert.assertFalse(vclsUrlEnum.hasMoreElements());
 204         for (URL vclsUrl : vclsUrls) {
 205             String fragment = vclsUrl.getRef();
 206             Assert.assertNull(fragment);
 207 
 208             // and verify that the the url is a reified pointer to the runtime entry
 209             String rep = vclsUrl.toString();
 210             //System.out.println("    getResource(\"/version/Version.class\") returned: " + rep);
 211             if (style.equals("http")) {
 212                 Assert.assertTrue(rep.startsWith("jar:http:"));
 213             } else {
 214                 Assert.assertTrue(rep.startsWith("jar:file:"));
 215             }
 216             String suffix;
 217             if (style.equals("unversioned")) {
 218                 suffix = ".jar!/version/Version.class";
 219             } else {
 220                 suffix = ".jar!/META-INF/versions/" + Runtime.version().major()
 221                         + "/version/Version.class";
 222             }
 223             Assert.assertTrue(rep.endsWith(suffix));
 224         }
 225         cldr.close();
 226     }
 227 
 228 
 229     private boolean readAndCompare(URL url, String match) throws Exception {
 230         boolean result;
 231         // necessary to do it this way, instead of openStream(), so we can
 232         // close underlying JarFile, otherwise windows can't delete the file
 233         URLConnection conn = url.openConnection();
 234         try (InputStream is = conn.getInputStream()) {
 235             byte[] bytes = is.readAllBytes();
 236             result = (new String(bytes)).contains(match);
 237         }
 238         if (conn instanceof JarURLConnection) {
 239             ((JarURLConnection)conn).getJarFile().close();
 240         }
   1 /*
   2  * Copyright (c) 2015, 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  */
  23 
  24 /*
  25  * @test
  26  * @bug 8132734 8144062 8159785 8194070
  27  * @summary Test that URL connections to multi-release jars can be runtime versioned
  28  * @library /lib/testlibrary/java/util/jar
  29  * @modules jdk.compiler
  30  *          jdk.httpserver
  31  *          jdk.jartool
  32  * @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer
  33  * @run testng MultiReleaseJarURLConnection
  34  */
  35 
  36 import java.io.IOException;
  37 import java.io.InputStream;
  38 import java.lang.invoke.MethodHandle;
  39 import java.lang.invoke.MethodHandles;
  40 import java.lang.invoke.MethodType;
  41 import java.net.JarURLConnection;
  42 import java.net.URL;
  43 import java.net.URLClassLoader;
  44 import java.net.URLConnection;
  45 import java.nio.file.Files;
  46 import java.nio.file.Paths;


  79         if (server != null)
  80             server.stop();
  81         Files.delete(Paths.get(unversioned));
  82         Files.delete(Paths.get(unsigned));
  83         Files.delete(Paths.get(signed));
  84     }
  85 
  86     @DataProvider(name = "data")
  87     public Object[][] createData() {
  88         return new Object[][]{
  89                 {"unversioned", unversioned},
  90                 {"unsigned", unsigned},
  91                 {"signed", signed}
  92         };
  93     }
  94 
  95     @Test(dataProvider = "data")
  96     public void testRuntimeVersioning(String style, String file) throws Exception {
  97         String urlFile = "jar:file:" + file + "!/";
  98         String baseUrlEntry = urlFile + "version/Version.java";
  99         String rtreturn = "return " + Math.min(Runtime.version().major(), 10);
 100 
 101         Assert.assertTrue(readAndCompare(new URL(baseUrlEntry), "return 8"));
 102         // #runtime is "magic" for a multi-release jar, but not for unversioned jar
 103         Assert.assertTrue(readAndCompare(new URL(baseUrlEntry + "#runtime"),
 104                 style.equals("unversioned") ? "return 8" : rtreturn));
 105         // #fragment or any other fragment is not magic
 106         Assert.assertTrue(readAndCompare(new URL(baseUrlEntry + "#fragment"), "return 8"));
 107         // cached entities not affected
 108         Assert.assertTrue(readAndCompare(new URL(baseUrlEntry), "return 8"));
 109 
 110         // the following tests will not work with unversioned jars
 111         if (style.equals("unversioned"))
 112             return;
 113 
 114         // direct access to versioned entry
 115         String versUrlEntry = urlFile + "META-INF/versions/" +
 116             Math.min(Runtime.version().major(), 10)
 117                 + "/version/Version.java";
 118         Assert.assertTrue(readAndCompare(new URL(versUrlEntry), rtreturn));
 119         // adding any fragment does not change things
 120         Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#runtime"), rtreturn));
 121         Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#fragment"), rtreturn));
 122         
 123         // it really doesn't change things
 124         // versUrlEntry = urlFile + "META-INF/versions/10/version/Version.java";
 125         // Assert.assertTrue(readAndCompare(new URL(versUrlEntry), "return 10"));
 126         // Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#runtime"), "return 10"));
 127         // Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#fragment"), "return 10"));
 128     }
 129 
 130     @Test(dataProvider = "data")
 131     public void testCachedJars(String style, String file) throws Exception {
 132         String urlFile = "jar:file:" + file + "!/";
 133 
 134         URL rootUrl = new URL(urlFile);
 135         JarURLConnection juc = (JarURLConnection)rootUrl.openConnection();
 136         JarFile rootJar = juc.getJarFile();
 137         Runtime.Version root = rootJar.getVersion();
 138 
 139         URL runtimeUrl = new URL(urlFile + "#runtime");
 140         juc = (JarURLConnection)runtimeUrl.openConnection();
 141         JarFile runtimeJar = juc.getJarFile();
 142         Runtime.Version runtime = runtimeJar.getVersion();
 143         if (style.equals("unversioned")) {
 144             Assert.assertEquals(root, runtime);
 145         } else {
 146             Assert.assertNotEquals(root, runtime);
 147         }


 174                 {"unsigned", new URL("jar:file:" + unsigned + "!/")},
 175                 {"signed", new URL("jar:file:" + signed + "!/")},
 176                 // external jar received via http protocol
 177                 {"http", new URL("jar:http://localhost:" + server.getPort() + "/multi-release.jar!/")},
 178                 {"http", new URL("http://localhost:" + server.getPort() + "/multi-release.jar")},
 179 
 180         };
 181     }
 182 
 183     @Test(dataProvider = "resourcedata")
 184     public void testResources(String style, URL url) throws Throwable {
 185         //System.out.println("  testing " + style + " url: " + url);
 186         URL[] urls = {url};
 187         URLClassLoader cldr = new URLClassLoader(urls);
 188         Class<?> vcls = cldr.loadClass("version.Version");
 189 
 190         // verify we are loading a runtime versioned class
 191         MethodType mt = MethodType.methodType(int.class);
 192         MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt);
 193         Assert.assertEquals((int)mh.invoke(vcls.newInstance()),
 194                 style.equals("unversioned") ?
 195                             8 :
 196                             Math.min(Runtime.version().major(), 10));
 197 
 198         // now get a resource and verify that we don't have a fragment attached
 199         Enumeration<URL> vclsUrlEnum = cldr.getResources("version/Version.class");
 200         Assert.assertTrue(vclsUrlEnum.hasMoreElements());
 201         URL vclsUrls[] = new URL[] {
 202             vcls.getResource("/version/Version.class"),
 203             vcls.getResource("Version.class"),
 204             cldr.getResource("version/Version.class"),
 205             vclsUrlEnum.nextElement()
 206         };
 207         Assert.assertFalse(vclsUrlEnum.hasMoreElements());
 208         for (URL vclsUrl : vclsUrls) {
 209             String fragment = vclsUrl.getRef();
 210             Assert.assertNull(fragment);
 211 
 212             // and verify that the the url is a reified pointer to the runtime entry
 213             String rep = vclsUrl.toString();
 214             //System.out.println("    getResource(\"/version/Version.class\") returned: " + rep);
 215             if (style.equals("http")) {
 216                 Assert.assertTrue(rep.startsWith("jar:http:"));
 217             } else {
 218                 Assert.assertTrue(rep.startsWith("jar:file:"));
 219             }
 220             String suffix;
 221             if (style.equals("unversioned")) {
 222                 suffix = ".jar!/version/Version.class";
 223             } else {
 224                 suffix = ".jar!/META-INF/versions/" + Math.min(Runtime.version().major(), 10)
 225                         + "/version/Version.class";
 226             }
 227             Assert.assertTrue(rep.endsWith(suffix));
 228         }
 229         cldr.close();
 230     }
 231 
 232 
 233     private boolean readAndCompare(URL url, String match) throws Exception {
 234         boolean result;
 235         // necessary to do it this way, instead of openStream(), so we can
 236         // close underlying JarFile, otherwise windows can't delete the file
 237         URLConnection conn = url.openConnection();
 238         try (InputStream is = conn.getInputStream()) {
 239             byte[] bytes = is.readAllBytes();
 240             result = (new String(bytes)).contains(match);
 241         }
 242         if (conn instanceof JarURLConnection) {
 243             ((JarURLConnection)conn).getJarFile().close();
 244         }
< prev index next >