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 8003256
  27  * @compile -XDignore.symbol.file VersionCheck.java
  28  * @run main VersionCheck
  29  * @summary Tests that "java -version" includes the name of the profile and that
  30  *     it matches the name in the release file
  31  */
  32 
  33 import java.nio.file.*;
  34 import java.io.*;
  35 import java.util.Properties;
  36 
  37 public class VersionCheck {
  38 
  39     static final String JAVA_HOME = System.getProperty("java.home");
  40     static final String OS_NAME = System.getProperty("os.name");
  41     static final String OS_ARCH = System.getProperty("os.arch");
  42 
  43     static final String JAVA_CMD =
  44             OS_NAME.startsWith("Windows") ? "java.exe" : "java";
  45 
  46     static final boolean NEED_D64 =
  47             OS_NAME.equals("SunOS") &&
  48             (OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64"));
  49 
  50     /**
  51      * Returns {@code true} if the given class is present.
  52      */
  53     static boolean isPresent(String cn) {
  54         try {
  55             Class.forName(cn);
  56             return true;
  57         } catch (ClassNotFoundException ignore) {
  58             return false;
  59         }
  60     }
  61 
  62     /**
  63      * Determines the profile by checking whether specific classes are present.
  64      * Returns the empty string if this runtime does not appear to be a profile
  65      * of Java SE.
  66      */
  67     static String probeProfile() {
  68         if (isPresent("java.awt.Window"))
  69             return "";
  70         if (isPresent("java.lang.management.ManagementFactory"))
  71             return "compact3";
  72         if (isPresent("java.sql.DriverManager"))
  73             return "compact2";
  74         return "compact1";
  75     }
  76 
  77     /**
  78      * Execs java with the given parameters. The method blocks until the
  79      * process terminates. Returns a {@code ByteArrayOutputStream} with any
  80      * stdout or stderr from the process.
  81      */
  82     static ByteArrayOutputStream execJava(String... args)
  83         throws IOException
  84     {
  85         StringBuilder sb = new StringBuilder();
  86         sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString());
  87         if (NEED_D64)
  88             sb.append(" -d64");
  89         for (String arg: args) {
  90             sb.append(' ');
  91             sb.append(arg);
  92         }
  93         String[] cmd = sb.toString().split(" ");
  94         ProcessBuilder pb = new ProcessBuilder(cmd);
  95         pb.redirectErrorStream(true);
  96         Process p = pb.start();
  97         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  98         byte[] buf = new byte[1024];
  99         int n;
 100         do {
 101             n = p.getInputStream().read(buf);
 102             if (n > 0)
 103                baos.write(buf, 0, n);
 104         } while (n > 0);
 105         try {
 106             int exitCode = p.waitFor();
 107             if (exitCode != 0)
 108                 throw new RuntimeException("Exit code: " + exitCode);
 109         } catch (InterruptedException e) {
 110             throw new RuntimeException("Should not happen");
 111         }
 112         return baos;
 113     }
 114 
 115     public static void main(String[] args) throws IOException {
 116         String reported = sun.misc.Version.profileName();
 117         String probed = probeProfile();
 118         if (!reported.equals(probed)) {
 119             throw new RuntimeException("sun.misc.Version reports: " + reported
 120                + ", but probing reports: " + probed);
 121         }
 122 
 123         String profile = probed;
 124         boolean isFullJre = (profile.length() == 0);
 125 
 126         // check that java -version includes "profile compactN"
 127         String expected = "profile " + profile;
 128         System.out.println("Checking java -version ...");
 129         ByteArrayOutputStream baos = execJava("-version");
 130         ByteArrayInputStream bain = new ByteArrayInputStream(baos.toByteArray());
 131         BufferedReader reader = new BufferedReader(new InputStreamReader(bain));
 132         boolean found = false;
 133         String line;
 134         while ((line = reader.readLine()) != null) {
 135             if (line.contains(expected)) {
 136                 found = true;
 137                 break;
 138             }
 139         }
 140         if (found && isFullJre)
 141            throw new RuntimeException(expected + " found in java -version output");
 142         if (!found && !isFullJre)
 143             throw new RuntimeException("java -version did not include " + expected);
 144 
 145         // check that the profile name matches the release file
 146         System.out.println("Checking release file ...");
 147         Properties props = new Properties();
 148 
 149         Path home = Paths.get(JAVA_HOME);
 150         if (home.getFileName().toString().equals("jre"))
 151             home = home.getParent();
 152         Path release = home.resolve("release");
 153         try (InputStream in = Files.newInputStream(release)) {
 154             props.load(in);
 155         }
 156         String value = props.getProperty("JAVA_PROFILE");
 157         if (isFullJre) {
 158             if (value != null)
 159                 throw new RuntimeException("JAVA_PROFILE should not be present");
 160         } else {
 161             if (value == null)
 162                 throw new RuntimeException("JAVA_PROFILE not present in release file");
 163             if (!value.equals("\"" + profile + "\""))
 164                 throw new RuntimeException("Unexpected value of JAVA_PROFILE: " + value);
 165         }
 166 
 167         System.out.println("Test passed.");
 168     }
 169 }