jdk/test/tools/launcher/profiles/Basic.java
changeset 19448 f7bcbf987d5c
parent 19353 ee92e7cf8d35
parent 19447 f2da7f97e104
child 19450 e92c5abf8936
child 19595 4565983c4629
child 19779 fe0b98be61a0
child 20101 4d045bddfaa4
equal deleted inserted replaced
19353:ee92e7cf8d35 19448:f7bcbf987d5c
     1 /*
       
     2  * Copyright (c) 2012, 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 8003255
       
    27  * @compile -XDignore.symbol.file Basic.java Main.java Logging.java
       
    28  * @run main Basic
       
    29  * @summary Test the launcher checks the Profile attribute of executable JAR
       
    30  *     files. Also checks that libraries that specify the Profile attribute
       
    31  *     are not loaded if the runtime does not support the required profile.
       
    32  */
       
    33 
       
    34 import java.io.*;
       
    35 import java.util.jar.*;
       
    36 import static java.util.jar.JarFile.MANIFEST_NAME;
       
    37 import java.util.zip.*;
       
    38 import java.nio.file.*;
       
    39 import java.nio.file.attribute.BasicFileAttributes;
       
    40 
       
    41 public class Basic {
       
    42 
       
    43     static final String MANIFEST_DIR = "META-INF/";
       
    44 
       
    45     static final String JAVA_HOME = System.getProperty("java.home");
       
    46     static final String OS_NAME = System.getProperty("os.name");
       
    47     static final String OS_ARCH = System.getProperty("os.arch");
       
    48 
       
    49     static final String JAVA_CMD =
       
    50             OS_NAME.startsWith("Windows") ? "java.exe" : "java";
       
    51 
       
    52     static final boolean NEED_D64 =
       
    53             OS_NAME.equals("SunOS") &&
       
    54             (OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64"));
       
    55 
       
    56     /**
       
    57      * Creates a JAR file with the given attributes and the given entries.
       
    58      * Class files are assumed to be in ${test.classes}. Note that this this
       
    59      * method cannot use the "jar" tool as it may not be present in the image.
       
    60      */
       
    61     static void createJarFile(String jarfile,
       
    62                               String mainAttributes,
       
    63                               String... entries)
       
    64         throws IOException
       
    65     {
       
    66         // create Manifest
       
    67         Manifest manifest = new Manifest();
       
    68         Attributes jarAttrs = manifest.getMainAttributes();
       
    69         jarAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
       
    70         if (mainAttributes.length() > 0) {
       
    71             for (String attr: mainAttributes.split(",")) {
       
    72                 String[] s = attr.split("=");
       
    73                 jarAttrs.put(new Attributes.Name(s[0]), s[1]);
       
    74             }
       
    75         }
       
    76 
       
    77         try (OutputStream out = Files.newOutputStream(Paths.get(jarfile));
       
    78              ZipOutputStream zos = new JarOutputStream(out))
       
    79         {
       
    80             // add manifest directory and manifest file
       
    81             ZipEntry e = new JarEntry(MANIFEST_DIR);
       
    82             e.setTime(System.currentTimeMillis());
       
    83             e.setSize(0);
       
    84             e.setCrc(0);
       
    85             zos.putNextEntry(e);
       
    86             e = new ZipEntry(MANIFEST_NAME);
       
    87             e.setTime(System.currentTimeMillis());
       
    88             zos.putNextEntry(e);
       
    89             manifest.write(zos);
       
    90             zos.closeEntry();
       
    91 
       
    92             // entries in JAR file
       
    93             for (String entry: entries) {
       
    94                 e = new JarEntry(entry);
       
    95                 Path path;
       
    96                 if (entry.endsWith(".class")) {
       
    97                     path = Paths.get(System.getProperty("test.classes"), entry);
       
    98                 } else {
       
    99                     path = Paths.get(entry);
       
   100                 }
       
   101                 BasicFileAttributes attrs =
       
   102                     Files.readAttributes(path, BasicFileAttributes.class);
       
   103                 e.setTime(attrs.lastModifiedTime().toMillis());
       
   104                 if (attrs.size() == 0) {
       
   105                     e.setMethod(ZipEntry.STORED);
       
   106                     e.setSize(0);
       
   107                     e.setCrc(0);
       
   108                 }
       
   109                 zos.putNextEntry(e);
       
   110                 if (attrs.isRegularFile())
       
   111                     Files.copy(path, zos);
       
   112                 zos.closeEntry();
       
   113             }
       
   114         }
       
   115     }
       
   116 
       
   117     /**
       
   118      * Execute the given executable JAR file with the given arguments. This
       
   119      * method blocks until the launched VM terminates. Any output or error
       
   120      * message from the launched VM are printed to System.out. Returns the
       
   121      * exit value.
       
   122      */
       
   123     static int exec(String jf, String... args) throws IOException {
       
   124         StringBuilder sb = new StringBuilder();
       
   125         sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString());
       
   126         if (NEED_D64)
       
   127             sb.append(" -d64");
       
   128         sb.append(" -jar ");
       
   129         sb.append(Paths.get(jf).toAbsolutePath());
       
   130         for (String arg: args) {
       
   131             sb.append(' ');
       
   132             sb.append(arg);
       
   133         }
       
   134         String[] cmd = sb.toString().split(" ");
       
   135         ProcessBuilder pb = new ProcessBuilder(cmd);
       
   136         pb.redirectErrorStream(true);
       
   137         Process p = pb.start();
       
   138         BufferedReader reader =
       
   139             new BufferedReader(new InputStreamReader(p.getInputStream()));
       
   140         String line;
       
   141         while ((line = reader.readLine()) != null) {
       
   142             System.out.println(line);
       
   143         }
       
   144         try {
       
   145             return p.waitFor();
       
   146         } catch (InterruptedException e) {
       
   147             throw new RuntimeException("Should not happen");
       
   148         }
       
   149     }
       
   150 
       
   151     static void checkRun(String jf, String... args) throws IOException {
       
   152         if (exec(jf) != 0)
       
   153             throw new RuntimeException(jf + " failed!!!");
       
   154     }
       
   155 
       
   156     static void checkRunFail(String jf, String... args) throws IOException {
       
   157         if (exec(jf) == 0)
       
   158             throw new RuntimeException(jf + " did not fail!!!");
       
   159         System.out.println("Failed as expected");
       
   160     }
       
   161 
       
   162     public static void main(String[] args) throws IOException {
       
   163         // ## replace this if there is a standard way to determine the profile
       
   164         String profile = sun.misc.Version.profileName();
       
   165 
       
   166         int thisProfile = 4;
       
   167         if ("compact1".equals(profile)) thisProfile = 1;
       
   168         if ("compact2".equals(profile)) thisProfile = 2;
       
   169         if ("compact3".equals(profile)) thisProfile = 3;
       
   170 
       
   171         // "library" JAR file used by the test
       
   172         createJarFile("Logging.jar", "", "Logging.class");
       
   173 
       
   174         // Executable JAR file without the Profile attribute
       
   175         if (thisProfile <= 3) {
       
   176             createJarFile("Main.jar",
       
   177                           "Main-Class=Main,Class-Path=Logging.jar",
       
   178                           "Main.class");
       
   179             checkRunFail("Main.jar");
       
   180         }
       
   181 
       
   182         // Executable JAR file with Profile attribute, Library JAR file without
       
   183         for (int p=1; p<=3; p++) {
       
   184             String attrs = "Main-Class=Main,Class-Path=Logging.jar" +
       
   185                  ",Profile=compact" + p;
       
   186             createJarFile("Main.jar", attrs,  "Main.class");
       
   187             if (p <= thisProfile) {
       
   188                 checkRun("Main.jar");
       
   189             } else {
       
   190                 checkRunFail("Main.jar");
       
   191             }
       
   192         }
       
   193 
       
   194         // Executable JAR file with Profile attribute that has invalid profile
       
   195         // name, including incorrect case.
       
   196         createJarFile("Main.jar",
       
   197                       "Main-Class=Main,Class-Path=Logging.jar,Profile=BadName",
       
   198                       "Main.class");
       
   199         checkRunFail("Main.jar");
       
   200 
       
   201         createJarFile("Main.jar",
       
   202                       "Main-Class=Main,Class-Path=Logging.jar,Profile=Compact1",
       
   203                       "Main.class");
       
   204         checkRunFail("Main.jar");
       
   205 
       
   206         // Executable JAR file and Librrary JAR file with Profile attribute
       
   207         createJarFile("Main.jar",
       
   208                       "Main-Class=Main,Class-Path=Logging.jar,Profile=compact1",
       
   209                       "Main.class");
       
   210         for (int p=1; p<=3; p++) {
       
   211             String attrs = "Profile=compact" + p;
       
   212             createJarFile("Logging.jar", attrs, "Logging.class");
       
   213             if (p <= thisProfile) {
       
   214                 checkRun("Main.jar");
       
   215             } else {
       
   216                 checkRunFail("Main.jar");
       
   217             }
       
   218         }
       
   219 
       
   220         // Executable JAR file and Library JAR with Profile attribute, value
       
   221         // of Profile not recognized
       
   222         createJarFile("Logging.jar", "Profile=BadName", "Logging.class");
       
   223         createJarFile("Main.jar",
       
   224                       "Main-Class=Main,Class-Path=Logging.jar,Profile=compact1",
       
   225                       "Main.class");
       
   226         checkRunFail("Main.jar");
       
   227 
       
   228         System.out.println("TEST PASSED.");
       
   229     }
       
   230 
       
   231 }