Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/tools/pack200/Utils.java
38833 views
/*1* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.nio.file.Path;24import java.io.BufferedReader;25import java.io.ByteArrayOutputStream;26import java.io.Closeable;27import java.io.File;28import java.io.FileFilter;29import java.io.FileOutputStream;30import java.io.IOException;31import java.io.InputStream;32import java.io.InputStreamReader;33import java.io.PrintStream;34import java.nio.charset.Charset;35import java.nio.file.Files;36import java.util.ArrayList;37import java.util.Arrays;38import java.util.Collections;39import java.util.List;40import java.util.Map;41import java.util.jar.JarFile;42import java.util.jar.JarOutputStream;43import java.util.jar.Pack200;44import java.util.zip.ZipEntry;45import java.util.zip.ZipFile;4647import static java.nio.file.StandardCopyOption.*;48import static java.nio.file.StandardOpenOption.*;4950/**51*52* @author ksrini53*/5455/*56* This class contains all the commonly used utilities used by various tests57* in this directory.58*/59class Utils {60static final String JavaHome = System.getProperty("test.java",61System.getProperty("java.home"));62static final boolean IsWindows =63System.getProperty("os.name").startsWith("Windows");64static final boolean Is64Bit =65System.getProperty("sun.arch.data.model", "32").equals("64");66static final File JavaSDK = new File(JavaHome).getParentFile();6768static final String PACK_FILE_EXT = ".pack";69static final String JAVA_FILE_EXT = ".java";70static final String CLASS_FILE_EXT = ".class";71static final String JAR_FILE_EXT = ".jar";7273static final File TEST_SRC_DIR = new File(System.getProperty("test.src"));74static final File TEST_CLS_DIR = new File(System.getProperty("test.classes"));75static final String VERIFIER_DIR_NAME = "pack200-verifier";76static final File VerifierJar = new File(VERIFIER_DIR_NAME + JAR_FILE_EXT);77static final File XCLASSES = new File("xclasses");7879private Utils() {} // all static8081static {82if (!JavaHome.endsWith("jre")) {83throw new RuntimeException("Error: requires an SDK to run");84}85}8687private static void init() throws IOException {88if (VerifierJar.exists()) {89return;90}91File srcDir = new File(TEST_SRC_DIR, VERIFIER_DIR_NAME);92if (!srcDir.exists()) {93// if not available try one level above94srcDir = new File(TEST_SRC_DIR.getParentFile(), VERIFIER_DIR_NAME);95}96List<File> javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT));97File tmpFile = File.createTempFile("javac", ".tmp");98XCLASSES.mkdirs();99FileOutputStream fos = null;100PrintStream ps = null;101try {102fos = new FileOutputStream(tmpFile);103ps = new PrintStream(fos);104for (File f : javaFileList) {105ps.println(f.getAbsolutePath());106}107} finally {108close(ps);109close(fos);110}111112compiler("-d",113XCLASSES.getName(),114"@" + tmpFile.getAbsolutePath());115116jar("cvfe",117VerifierJar.getName(),118"sun.tools.pack.verify.Main",119"-C",120XCLASSES.getName(),121".");122}123124static void dirlist(File dir) {125File[] files = dir.listFiles();126System.out.println("--listing " + dir.getAbsolutePath() + "---");127for (File f : files) {128StringBuffer sb = new StringBuffer();129sb.append(f.isDirectory() ? "d " : "- ");130sb.append(f.getName());131System.out.println(sb);132}133}134static void doCompareVerify(File reference, File specimen) throws IOException {135init();136List<String> cmds = new ArrayList<String>();137cmds.add(getJavaCmd());138cmds.add("-cp");139cmds.add(Utils.locateJar("tools.jar") +140System.getProperty("path.separator") + VerifierJar.getName());141cmds.add("sun.tools.pack.verify.Main");142cmds.add(reference.getAbsolutePath());143cmds.add(specimen.getAbsolutePath());144cmds.add("-O");145runExec(cmds);146}147148static void doCompareBitWise(File reference, File specimen)149throws IOException {150init();151List<String> cmds = new ArrayList<String>();152cmds.add(getJavaCmd());153cmds.add("-cp");154cmds.add(Utils.locateJar("tools.jar")155+ System.getProperty("path.separator") + VerifierJar.getName());156cmds.add("sun.tools.pack.verify.Main");157cmds.add(reference.getName());158cmds.add(specimen.getName());159cmds.add("-O");160cmds.add("-b");161runExec(cmds);162}163164static FileFilter createFilter(final String extension) {165return new FileFilter() {166@Override167public boolean accept(File pathname) {168String name = pathname.getName();169if (name.endsWith(extension)) {170return true;171}172return false;173}174};175}176177/*178* clean up all the usual suspects179*/180static void cleanup() throws IOException {181recursiveDelete(XCLASSES);182List<File> toDelete = new ArrayList<>();183toDelete.addAll(Utils.findFiles(new File("."),184Utils.createFilter(".out")));185toDelete.addAll(Utils.findFiles(new File("."),186Utils.createFilter(".bak")));187toDelete.addAll(Utils.findFiles(new File("."),188Utils.createFilter(".jar")));189toDelete.addAll(Utils.findFiles(new File("."),190Utils.createFilter(".pack")));191toDelete.addAll(Utils.findFiles(new File("."),192Utils.createFilter(".bnd")));193toDelete.addAll(Utils.findFiles(new File("."),194Utils.createFilter(".txt")));195toDelete.addAll(Utils.findFiles(new File("."),196Utils.createFilter(".idx")));197toDelete.addAll(Utils.findFiles(new File("."),198Utils.createFilter(".gidx")));199for (File f : toDelete) {200f.delete();201}202}203204static final FileFilter DIR_FILTER = new FileFilter() {205public boolean accept(File pathname) {206if (pathname.isDirectory()) {207return true;208}209return false;210}211};212213static final FileFilter FILE_FILTER = new FileFilter() {214public boolean accept(File pathname) {215if (pathname.isFile()) {216return true;217}218return false;219}220};221222static void copyFile(File src, File dst) throws IOException {223Path parent = dst.toPath().getParent();224if (parent != null) {225Files.createDirectories(parent);226}227Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);228if (dst.isDirectory() && !dst.canWrite()) {229dst.setWritable(true);230}231}232233static String baseName(File file, String extension) {234return baseName(file.getAbsolutePath(), extension);235}236237static String baseName(String name, String extension) {238int cut = name.length() - extension.length();239return name.lastIndexOf(extension) == cut240? name.substring(0, cut)241: name;242243}244static void createFile(File outFile, List<String> content) throws IOException {245Files.write(outFile.getAbsoluteFile().toPath(), content,246Charset.defaultCharset(), CREATE_NEW, TRUNCATE_EXISTING);247}248249/*250* Suppose a path is provided which consists of a full path251* this method returns the sub path for a full path ex: /foo/bar/baz/foobar.z252* and the base path is /foo/bar it will will return baz/foobar.z.253*/254private static String getEntryPath(String basePath, String fullPath) {255if (!fullPath.startsWith(basePath)) {256return null;257}258return fullPath.substring(basePath.length());259}260261static String getEntryPath(File basePathFile, File fullPathFile) {262return getEntryPath(basePathFile.toString(), fullPathFile.toString());263}264265public static void recursiveCopy(File src, File dest) throws IOException {266if (!src.exists() || !src.canRead()) {267throw new IOException("file not found or readable: " + src);268}269if (dest.exists() && !dest.isDirectory() && !dest.canWrite()) {270throw new IOException("file not found or writeable: " + dest);271}272if (!dest.exists()) {273dest.mkdirs();274}275List<File> a = directoryList(src);276for (File f : a) {277copyFile(f, new File(dest, getEntryPath(src, f)));278}279}280281static List<File> directoryList(File dirname) {282List<File> dirList = new ArrayList<File>();283return directoryList(dirname, dirList, null);284}285286private static List<File> directoryList(File dirname, List<File> dirList,287File[] dirs) {288dirList.addAll(Arrays.asList(dirname.listFiles(FILE_FILTER)));289dirs = dirname.listFiles(DIR_FILTER);290for (File f : dirs) {291if (f.isDirectory() && !f.equals(dirname)) {292dirList.add(f);293directoryList(f, dirList, dirs);294}295}296return dirList;297}298299static void recursiveDelete(File dir) throws IOException {300if (dir.isFile()) {301dir.delete();302} else if (dir.isDirectory()) {303File[] entries = dir.listFiles();304for (int i = 0; i < entries.length; i++) {305if (entries[i].isDirectory()) {306recursiveDelete(entries[i]);307}308entries[i].delete();309}310dir.delete();311}312}313314static List<File> findFiles(File startDir, FileFilter filter)315throws IOException {316List<File> list = new ArrayList<File>();317findFiles0(startDir, list, filter);318return list;319}320/*321* finds files in the start directory using the the filter, appends322* the files to the dirList.323*/324private static void findFiles0(File startDir, List<File> list,325FileFilter filter) throws IOException {326File[] foundFiles = startDir.listFiles(filter);327list.addAll(Arrays.asList(foundFiles));328File[] dirs = startDir.listFiles(DIR_FILTER);329for (File dir : dirs) {330findFiles0(dir, list, filter);331}332}333334static void close(Closeable c) {335if (c == null) {336return;337}338try {339c.close();340} catch (IOException ignore) {341}342}343344static void compiler(String... javacCmds) {345if (com.sun.tools.javac.Main.compile(javacCmds) != 0) {346throw new RuntimeException("compilation failed");347}348}349350static void jar(String... jargs) {351sun.tools.jar.Main jarTool =352new sun.tools.jar.Main(System.out, System.err, "jartool");353if (!jarTool.run(jargs)) {354throw new RuntimeException("jar command failed");355}356}357358static void testWithRepack(File inFile, String... repackOpts) throws IOException {359File cwd = new File(".");360// pack using --repack in native mode361File nativejarFile = new File(cwd, "out-n" + Utils.JAR_FILE_EXT);362repack(inFile, nativejarFile, false, repackOpts);363doCompareVerify(inFile, nativejarFile);364365// ensure bit compatibility between the unpacker variants366File javajarFile = new File(cwd, "out-j" + Utils.JAR_FILE_EXT);367repack(inFile, javajarFile, true, repackOpts);368doCompareBitWise(javajarFile, nativejarFile);369}370371static List<String> repack(File inFile, File outFile,372boolean disableNative, String... extraOpts) {373List<String> cmdList = new ArrayList<>();374cmdList.clear();375cmdList.add(Utils.getJavaCmd());376cmdList.add("-ea");377cmdList.add("-esa");378if (disableNative) {379cmdList.add("-Dcom.sun.java.util.jar.pack.disable.native=true");380}381cmdList.add("com.sun.java.util.jar.pack.Driver");382cmdList.add("--repack");383if (extraOpts != null) {384for (String opt: extraOpts) {385cmdList.add(opt);386}387}388cmdList.add(outFile.getName());389cmdList.add(inFile.getName());390return Utils.runExec(cmdList);391}392393// given a jar file foo.jar will write to foo.pack394static void pack(JarFile jarFile, File packFile) throws IOException {395Pack200.Packer packer = Pack200.newPacker();396Map<String, String> p = packer.properties();397// Take the time optimization vs. space398p.put(packer.EFFORT, "1"); // CAUTION: do not use 0.399// Make the memory consumption as effective as possible400p.put(packer.SEGMENT_LIMIT, "10000");401// ignore all JAR deflation requests to save time402p.put(packer.DEFLATE_HINT, packer.FALSE);403// save the file ordering of the original JAR404p.put(packer.KEEP_FILE_ORDER, packer.TRUE);405FileOutputStream fos = null;406try {407// Write out to a jtreg scratch area408fos = new FileOutputStream(packFile);409// Call the packer410packer.pack(jarFile, fos);411} finally {412close(fos);413}414}415416// uses java unpacker, slow but useful to discover issues with the packer417static void unpackj(File inFile, JarOutputStream jarStream)418throws IOException {419unpack0(inFile, jarStream, true);420421}422423// uses native unpacker using the java APIs424static void unpackn(File inFile, JarOutputStream jarStream)425throws IOException {426unpack0(inFile, jarStream, false);427}428429// given a packed file, create the jar file in the current directory.430private static void unpack0(File inFile, JarOutputStream jarStream,431boolean useJavaUnpack) throws IOException {432// Unpack the files433Pack200.Unpacker unpacker = Pack200.newUnpacker();434Map<String, String> props = unpacker.properties();435if (useJavaUnpack) {436props.put("com.sun.java.util.jar.pack.disable.native", "true");437}438// Call the unpacker439unpacker.unpack(inFile, jarStream);440}441442static byte[] getBuffer(ZipFile zf, ZipEntry ze) throws IOException {443ByteArrayOutputStream baos = new ByteArrayOutputStream();444byte buf[] = new byte[8192];445InputStream is = null;446try {447is = zf.getInputStream(ze);448int n = is.read(buf);449while (n > 0) {450baos.write(buf, 0, n);451n = is.read(buf);452}453return baos.toByteArray();454} finally {455close(is);456}457}458459static ArrayList<String> getZipFileEntryNames(ZipFile z) {460ArrayList<String> out = new ArrayList<String>();461for (ZipEntry ze : Collections.list(z.entries())) {462out.add(ze.getName());463}464return out;465}466static List<String> runExec(List<String> cmdsList) {467return runExec(cmdsList, null);468}469static List<String> runExec(List<String> cmdsList, Map<String, String> penv) {470ArrayList<String> alist = new ArrayList<String>();471ProcessBuilder pb =472new ProcessBuilder(cmdsList);473Map<String, String> env = pb.environment();474if (penv != null && !penv.isEmpty()) {475env.putAll(penv);476}477pb.directory(new File("."));478dirlist(new File("."));479for (String x : cmdsList) {480System.out.print(x + " ");481}482System.out.println("");483int retval = 0;484Process p = null;485InputStreamReader ir = null;486BufferedReader rd = null;487InputStream is = null;488try {489pb.redirectErrorStream(true);490p = pb.start();491is = p.getInputStream();492ir = new InputStreamReader(is);493rd = new BufferedReader(ir, 8192);494495String in = rd.readLine();496while (in != null) {497alist.add(in);498System.out.println(in);499in = rd.readLine();500}501retval = p.waitFor();502if (retval != 0) {503throw new RuntimeException("process failed with non-zero exit");504}505} catch (Exception ex) {506throw new RuntimeException(ex.getMessage());507} finally {508close(rd);509close(ir);510close(is);511if (p != null) {512p.destroy();513}514}515return alist;516}517518static String getUnpack200Cmd() {519return getAjavaCmd("unpack200");520}521522static String getPack200Cmd() {523return getAjavaCmd("pack200");524}525526static String getJavaCmd() {527return getAjavaCmd("java");528}529530static String getAjavaCmd(String cmdStr) {531File binDir = new File(JavaHome, "bin");532File unpack200File = IsWindows533? new File(binDir, cmdStr + ".exe")534: new File(binDir, cmdStr);535536String cmd = unpack200File.getAbsolutePath();537if (!unpack200File.canExecute()) {538throw new RuntimeException("please check" +539cmd + " exists and is executable");540}541return cmd;542}543544private static List<File> locaterCache = null;545// search the source dir and jdk dir for requested file and returns546// the first location it finds.547static File locateJar(String name) {548try {549if (locaterCache == null) {550locaterCache = new ArrayList<File>();551locaterCache.addAll(findFiles(TEST_SRC_DIR, createFilter(JAR_FILE_EXT)));552locaterCache.addAll(findFiles(JavaSDK, createFilter(JAR_FILE_EXT)));553}554for (File f : locaterCache) {555if (f.getName().equals(name)) {556return f;557}558}559throw new IOException("file not found: " + name);560} catch (IOException e) {561throw new RuntimeException(e);562}563}564}565566567