--- /dev/null 2012-10-30 13:53:25.609028996 -0400 +++ new/test/tools/launcher/profiles/Basic.java 2013-01-08 02:21:31.917104224 -0500 @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8003255 + * @compile -XDignore.symbol.file Basic.java Main.java Logging.java + * @run main Basic + * @summary Test the launcher checks the Profile attribute of executable JAR + * files. Also checks that libraries that specify the Profile attribute + * are not loaded if the runtime does not support the required profile. + */ + +import java.io.*; +import java.util.jar.*; +import static java.util.jar.JarFile.MANIFEST_NAME; +import java.util.zip.*; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; + +public class Basic { + + static final String MANIFEST_DIR = "META-INF/"; + + static final String JAVA_HOME = System.getProperty("java.home"); + static final String OS_NAME = System.getProperty("os.name"); + static final String OS_ARCH = System.getProperty("os.arch"); + + static final String JAVA_CMD = + OS_NAME.startsWith("Windows") ? "java.exe" : "java"; + + static final boolean NEED_D64 = + OS_NAME.equals("SunOS") && + (OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64")); + + /** + * Creates a JAR file with the given attributes and the given entries. + * Class files are assumed to be in ${test.classes}. Note that this this + * method cannot use the "jar" tool as it may not be present in the image. + */ + static void createJarFile(String jarfile, + String mainAttributes, + String... entries) + throws IOException + { + // create Manifest + Manifest manifest = new Manifest(); + Attributes jarAttrs = manifest.getMainAttributes(); + jarAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); + if (mainAttributes.length() > 0) { + for (String attr: mainAttributes.split(",")) { + String[] s = attr.split("="); + jarAttrs.put(new Attributes.Name(s[0]), s[1]); + } + } + + try (OutputStream out = Files.newOutputStream(Paths.get(jarfile)); + ZipOutputStream zos = new JarOutputStream(out)) + { + // add manifest directory and manifest file + ZipEntry e = new JarEntry(MANIFEST_DIR); + e.setTime(System.currentTimeMillis()); + e.setSize(0); + e.setCrc(0); + zos.putNextEntry(e); + e = new ZipEntry(MANIFEST_NAME); + e.setTime(System.currentTimeMillis()); + zos.putNextEntry(e); + manifest.write(zos); + zos.closeEntry(); + + // entries in JAR file + for (String entry: entries) { + e = new JarEntry(entry); + Path path; + if (entry.endsWith(".class")) { + path = Paths.get(System.getProperty("test.classes"), entry); + } else { + path = Paths.get(entry); + } + BasicFileAttributes attrs = + Files.readAttributes(path, BasicFileAttributes.class); + e.setTime(attrs.lastModifiedTime().toMillis()); + if (attrs.size() == 0) { + e.setMethod(ZipEntry.STORED); + e.setSize(0); + e.setCrc(0); + } + zos.putNextEntry(e); + if (attrs.isRegularFile()) + Files.copy(path, zos); + zos.closeEntry(); + } + } + } + + /** + * Execute the given executable JAR file with the given arguments. This + * method blocks until the launched VM terminates. Any output or error + * message from the launched VM are printed to System.out. Returns the + * exit value. + */ + static int exec(String jf, String... args) throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString()); + if (NEED_D64) + sb.append(" -d64"); + sb.append(" -jar "); + sb.append(Paths.get(jf).toAbsolutePath()); + for (String arg: args) { + sb.append(' '); + sb.append(arg); + } + String[] cmd = sb.toString().split(" "); + ProcessBuilder pb = new ProcessBuilder(cmd); + pb.redirectErrorStream(true); + Process p = pb.start(); + BufferedReader reader = + new BufferedReader(new InputStreamReader(p.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + try { + return p.waitFor(); + } catch (InterruptedException e) { + throw new RuntimeException("Should not happen"); + } + } + + static void checkRun(String jf, String... args) throws IOException { + if (exec(jf) != 0) + throw new RuntimeException(jf + " failed!!!"); + } + + static void checkRunFail(String jf, String... args) throws IOException { + if (exec(jf) == 0) + throw new RuntimeException(jf + " did not fail!!!"); + System.out.println("Failed as expected"); + } + + public static void main(String[] args) throws IOException { + // ## replace this if there is a standard way to determine the profile + String profile = sun.misc.Version.profileName(); + + int thisProfile = 4; + if ("compact1".equals(profile)) thisProfile = 1; + if ("compact2".equals(profile)) thisProfile = 2; + if ("compact3".equals(profile)) thisProfile = 3; + + // "library" JAR file used by the test + createJarFile("Logging.jar", "", "Logging.class"); + + // Executable JAR file without the Profile attribute + if (thisProfile <= 3) { + createJarFile("Main.jar", + "Main-Class=Main,Class-Path=Logging.jar", + "Main.class"); + checkRunFail("Main.jar"); + } + + // Executable JAR file with Profile attribute, Library JAR file without + for (int p=1; p<=3; p++) { + String attrs = "Main-Class=Main,Class-Path=Logging.jar" + + ",Profile=compact" + p; + createJarFile("Main.jar", attrs, "Main.class"); + if (p <= thisProfile) { + checkRun("Main.jar"); + } else { + checkRunFail("Main.jar"); + } + } + + // Executable JAR file with Profile attribute and unrecognized profile + createJarFile("Main.jar", + "Main-Class=Main,Class-Path=Logging.jar,Profile=BadName", + "Main.class"); + checkRunFail("Main.jar"); + + // Executable JAR file and Librrary JAR file with Profile attribute + createJarFile("Main.jar", + "Main-Class=Main,Class-Path=Logging.jar,Profile=compact1", + "Main.class"); + for (int p=1; p<=3; p++) { + String attrs = "Profile=compact" + p; + createJarFile("Logging.jar", attrs, "Logging.class"); + if (p <= thisProfile) { + checkRun("Main.jar"); + } else { + checkRunFail("Main.jar"); + } + } + + // Executable JAR file and Library JAR with Profile attribute, value + // of Profile not recognized + createJarFile("Logging.jar", "Profile=BadName", "Logging.class"); + createJarFile("Main.jar", + "Main-Class=Main,Class-Path=Logging.jar,Profile=compact1", + "Main.class"); + checkRunFail("Main.jar"); + + System.out.println("TEST PASSED."); + } + +}