jdk/test/tools/lib/tests/JImageGenerator.java
author lana
Thu, 28 Apr 2016 08:26:43 -0700
changeset 37731 55198b0e17d5
parent 37615 d4486cdacf4e
child 37779 7c84df693837
permissions -rw-r--r--
Added tag jdk-9+116 for changeset 973b1c28c6d2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     1
/*
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     4
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     7
 * published by the Free Software Foundation.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     8
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    13
 * accompanied this code).
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    14
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    18
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    21
 * questions.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    22
 */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    23
package tests;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    24
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    25
import java.io.ByteArrayInputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    26
import java.io.ByteArrayOutputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    27
import java.io.File;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    28
import java.io.FileOutputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    29
import java.io.IOException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    30
import java.io.InputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    31
import java.io.OutputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    32
import java.io.PrintStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    33
import java.io.PrintWriter;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    34
import java.io.StringWriter;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    35
import java.nio.file.Files;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    36
import java.nio.file.Path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    37
import java.nio.file.Paths;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    38
import java.nio.file.StandardCopyOption;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    39
import java.util.ArrayList;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    40
import java.util.Arrays;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    41
import java.util.Collections;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    42
import java.util.HashSet;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    43
import java.util.List;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    44
import java.util.Objects;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    45
import java.util.Set;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    46
import java.util.jar.JarEntry;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    47
import java.util.jar.JarInputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    48
import java.util.jar.JarOutputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    49
import java.util.stream.Collectors;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    50
import java.util.stream.Stream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    51
import java.util.zip.ZipEntry;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    52
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    53
import javax.tools.JavaCompiler;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    54
import javax.tools.StandardJavaFileManager;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    55
import javax.tools.StandardLocation;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    56
import javax.tools.ToolProvider;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    57
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    58
/**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    59
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    60
 * A generator for jmods, jars and images.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    61
 */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    62
public class JImageGenerator {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    63
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    64
    public static final String LOAD_ALL_CLASSES_TEMPLATE = "package PACKAGE;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    65
            + "\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    66
            + "import java.net.URI;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    67
            + "import java.nio.file.FileSystems;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    68
            + "import java.nio.file.Files;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    69
            + "import java.nio.file.Path;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    70
            + "import java.util.function.Function;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    71
            + "\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    72
            + "public class CLASS {\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    73
            + "    private static long total_time;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    74
            + "    private static long num_classes;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    75
            + "    public static void main(String[] args) throws Exception {\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    76
            + "        Function<Path, String> formatter = (path) -> {\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    77
            + "            String clazz = path.toString().substring(\"modules/\".length()+1, path.toString().lastIndexOf(\".\"));\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    78
            + "            clazz = clazz.substring(clazz.indexOf(\"/\") + 1);\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    79
            + "            return clazz.replaceAll(\"/\", \"\\\\.\");\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    80
            + "        };\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    81
            + "        Files.walk(FileSystems.getFileSystem(URI.create(\"jrt:/\")).getPath(\"/modules/\")).\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    82
            + "                filter((p) -> {\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    83
            + "                    return Files.isRegularFile(p) && p.toString().endsWith(\".class\")\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    84
            + "                    && !p.toString().endsWith(\"module-info.class\");\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    85
            + "                }).\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    86
            + "                map(formatter).forEach((clazz) -> {\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    87
            + "                    try {\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    88
            + "                        long t = System.currentTimeMillis();\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    89
            + "                        Class.forName(clazz, false, Thread.currentThread().getContextClassLoader());\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    90
            + "                        total_time+= System.currentTimeMillis()-t;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    91
            + "                        num_classes+=1;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    92
            + "                    } catch (IllegalAccessError ex) {\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    93
            + "                        // Security exceptions can occur, this is not what we are testing\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    94
            + "                        System.err.println(\"Access error, OK \" + clazz);\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    95
            + "                    } catch (Exception ex) {\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    96
            + "                        System.err.println(\"ERROR \" + clazz);\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    97
            + "                        throw new RuntimeException(ex);\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    98
            + "                    }\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    99
            + "                });\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   100
            + "    double res = (double) total_time / num_classes;\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   101
            + "    // System.out.println(\"Total time \" + total_time + \" num classes \" + num_classes + \" average \" + res);\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   102
            + "    }\n"
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   103
            + "}\n";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   104
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   105
    private static final String OUTPUT_OPTION = "--output";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   106
    private static final String POST_PROCESS_OPTION = "--post-process-path";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   107
    private static final String MAIN_CLASS_OPTION = "--main-class";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   108
    private static final String CLASS_PATH_OPTION = "--class-path";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   109
    private static final String MODULE_PATH_OPTION = "--modulepath";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   110
    private static final String ADD_MODS_OPTION = "--addmods";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   111
    private static final String LIMIT_MODS_OPTION = "--limitmods";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   112
    private static final String PLUGINS_MODULE_PATH = "--plugin-module-path";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   113
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   114
    private static final String CMDS_OPTION = "--cmds";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   115
    private static final String CONFIG_OPTION = "--config";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   116
    private static final String HASH_DEPENDENCIES_OPTION = "--hash-dependencies";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   117
    private static final String LIBS_OPTION = "--libs";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   118
    private static final String MODULE_VERSION_OPTION = "--module-version";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   119
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   120
    private JImageGenerator() {}
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   121
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   122
    private static String optionsPrettyPrint(String... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   123
        return Stream.of(args).collect(Collectors.joining(" "));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   124
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   125
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   126
    public static File getJModsDir(File jdkHome) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   127
        File jdkjmods = new File(jdkHome, "jmods");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   128
        if (!jdkjmods.exists()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   129
            return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   130
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   131
        return jdkjmods;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   132
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   133
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   134
    public static Path addFiles(Path module, InMemoryFile... resources) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   135
        Path tempFile = Files.createTempFile("jlink-test", "");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   136
        try (JarInputStream in = new JarInputStream(Files.newInputStream(module));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   137
             JarOutputStream out = new JarOutputStream(new FileOutputStream(tempFile.toFile()))) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   138
            ZipEntry entry;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   139
            while ((entry = in.getNextEntry()) != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   140
                String name = entry.getName();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   141
                out.putNextEntry(new ZipEntry(name));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   142
                copy(in, out);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   143
                out.closeEntry();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   144
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   145
            for (InMemoryFile r : resources) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   146
                addFile(r, out);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   147
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   148
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   149
        Files.move(tempFile, module, StandardCopyOption.REPLACE_EXISTING);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   150
        return module;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   151
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   152
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   153
    private static void copy(InputStream in, OutputStream out) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   154
        int len;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   155
        byte[] buf = new byte[4096];
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   156
        while ((len = in.read(buf)) > 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   157
            out.write(buf, 0, len);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   158
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   159
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   160
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   161
    public static JModTask getJModTask() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   162
        return new JModTask();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   163
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   164
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   165
    public static JLinkTask getJLinkTask() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   166
        return new JLinkTask();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   167
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   168
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   169
    public static JImageTask getJImageTask() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   170
        return new JImageTask();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   171
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   172
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   173
    private static void addFile(InMemoryFile resource, JarOutputStream target) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   174
        String fileName = resource.getPath();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   175
        fileName = fileName.replace("\\", "/");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   176
        String[] ss = fileName.split("/");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   177
        Path p = Paths.get("");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   178
        for (int i = 0; i < ss.length; ++i) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   179
            if (i < ss.length - 1) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   180
                if (!ss[i].isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   181
                    p = p.resolve(ss[i]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   182
                    JarEntry entry = new JarEntry(p.toString() + "/");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   183
                    target.putNextEntry(entry);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   184
                    target.closeEntry();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   185
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   186
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   187
                p = p.resolve(ss[i]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   188
                JarEntry entry = new JarEntry(p.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   189
                target.putNextEntry(entry);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   190
                copy(resource.getBytes(), target);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   191
                target.closeEntry();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   192
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   193
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   194
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   195
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   196
    public static Path createNewFile(Path root, String pathName, String extension) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   197
        Path out = root.resolve(pathName + extension);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   198
        int i = 1;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   199
        while (Files.exists(out)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   200
            out = root.resolve(pathName + "-" + (++i) + extension);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   201
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   202
        return out;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   203
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   204
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   205
    public static Path generateSources(Path output, String moduleName, List<InMemorySourceFile> sources) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   206
        Path moduleDir = output.resolve(moduleName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   207
        Files.createDirectory(moduleDir);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   208
        for (InMemorySourceFile source : sources) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   209
            Path fileDir = moduleDir;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   210
            if (!source.packageName.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   211
                String dir = source.packageName.replace('.', File.separatorChar);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   212
                fileDir = moduleDir.resolve(dir);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   213
                Files.createDirectories(fileDir);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   214
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   215
            Files.write(fileDir.resolve(source.className + ".java"), source.source.getBytes());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   216
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   217
        return moduleDir;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   218
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   219
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   220
    public static Path generateSourcesFromTemplate(Path output, String moduleName, String... classNames) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   221
        List<InMemorySourceFile> sources = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   222
        for (String className : classNames) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   223
            String packageName = getPackageName(className);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   224
            String simpleName = getSimpleName(className);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   225
            String content = LOAD_ALL_CLASSES_TEMPLATE
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   226
                    .replace("CLASS", simpleName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   227
            if (packageName.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   228
                content = content.replace("package PACKAGE;", packageName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   229
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   230
                content = content.replace("PACKAGE", packageName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   231
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   232
            sources.add(new InMemorySourceFile(packageName, simpleName, content));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   233
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   234
        return generateSources(output, moduleName, sources);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   235
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   236
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   237
    public static void generateModuleInfo(Path moduleDir, List<String> packages, String... dependencies) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   238
        StringBuilder moduleInfoBuilder = new StringBuilder();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   239
        Path file = moduleDir.resolve("module-info.java");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   240
        String moduleName = moduleDir.getFileName().toString();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   241
        moduleInfoBuilder.append("module ").append(moduleName).append("{\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   242
        for (String dep : dependencies) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   243
            moduleInfoBuilder.append("requires ").append(dep).append(";\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   244
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   245
        for (String pkg : packages) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   246
            if (!pkg.trim().isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   247
                moduleInfoBuilder.append("exports ").append(pkg).append(";\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   248
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   249
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   250
        moduleInfoBuilder.append("}");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   251
        Files.write(file, moduleInfoBuilder.toString().getBytes());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   252
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   253
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   254
    public static void compileSuccess(Path source, Path destination, String... options) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   255
        if (!compile(source, destination, options)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   256
            throw new AssertionError("Compilation failed.");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   257
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   258
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   259
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   260
    public static boolean compile(Path source, Path destination, String... options) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   261
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   262
        try (StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   263
            List<Path> sources
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   264
                    = Files.find(source, Integer.MAX_VALUE,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   265
                    (file, attrs) -> file.toString().endsWith(".java"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   266
                    .collect(Collectors.toList());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   267
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   268
            Files.createDirectories(destination);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   269
            jfm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Collections.singleton(destination));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   270
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   271
            List<String> opts = Arrays.asList(options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   272
            JavaCompiler.CompilationTask task
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   273
                    = compiler.getTask(null, jfm, null, opts, null,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   274
                    jfm.getJavaFileObjectsFromPaths(sources));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   275
            List<String> list = new ArrayList<>(opts);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   276
            list.addAll(sources.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   277
                    .map(Path::toString)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   278
                    .collect(Collectors.toList()));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   279
            System.err.println("javac options: " + optionsPrettyPrint(list.toArray(new String[list.size()])));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   280
            return task.call();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   281
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   282
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   283
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   284
    public static Path createJarFile(Path jarfile, Path dir) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   285
        return createJarFile(jarfile, dir, Paths.get("."));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   286
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   287
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   288
    public static Path createJarFile(Path jarfile, Path dir, Path file) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   289
        // create the target directory
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   290
        Path parent = jarfile.getParent();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   291
        if (parent != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   292
            Files.createDirectories(parent);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   293
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   294
        List<Path> entries = Files.find(dir.resolve(file), Integer.MAX_VALUE,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   295
                (p, attrs) -> attrs.isRegularFile())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   296
                .map(dir::relativize)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   297
                .collect(Collectors.toList());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   298
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   299
        try (OutputStream out = Files.newOutputStream(jarfile);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   300
             JarOutputStream jos = new JarOutputStream(out)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   301
            for (Path entry : entries) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   302
                // map the file path to a name in the JAR file
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   303
                Path normalized = entry.normalize();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   304
                String name = normalized
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   305
                        .subpath(0, normalized.getNameCount())  // drop root
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   306
                        .toString()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   307
                        .replace(File.separatorChar, '/');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   308
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   309
                jos.putNextEntry(new JarEntry(name));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   310
                Files.copy(dir.resolve(entry), jos);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   311
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   312
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   313
        return jarfile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   314
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   315
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   316
    public static Set<String> getModuleContent(Path module) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   317
        Result result = JImageGenerator.getJModTask()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   318
                .jmod(module)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   319
                .list();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   320
        result.assertSuccess();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   321
        return Stream.of(result.getMessage().split("\r?\n"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   322
                .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   323
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   324
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   325
    public static void checkModule(Path module, Set<String> expected) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   326
        Set<String> actual = getModuleContent(module);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   327
        if (!Objects.equals(actual, expected)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   328
            Set<String> unexpected = new HashSet<>(actual);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   329
            unexpected.removeAll(expected);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   330
            Set<String> notFound = new HashSet<>(expected);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   331
            notFound.removeAll(actual);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   332
            System.err.println("Unexpected files:");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   333
            unexpected.forEach(s -> System.err.println("\t" + s));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   334
            System.err.println("Not found files:");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   335
            notFound.forEach(s -> System.err.println("\t" + s));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   336
            throw new AssertionError("Module check failed.");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   337
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   338
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   339
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   340
    public static class JModTask {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   341
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   342
        private final List<Path> classpath = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   343
        private final List<Path> libs = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   344
        private final List<Path> cmds = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   345
        private final List<Path> config = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   346
        private final List<Path> jars = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   347
        private final List<Path> jmods = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   348
        private final List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   349
        private Path output;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   350
        private String hashDependencies;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   351
        private String mainClass;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   352
        private String moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   353
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   354
        public JModTask addNativeLibraries(Path cp) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   355
            this.libs.add(cp);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   356
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   357
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   358
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   359
        public JModTask hashDependencies(String hash) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   360
            this.hashDependencies = hash;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   361
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   362
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   363
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   364
        public JModTask addCmds(Path cp) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   365
            this.cmds.add(cp);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   366
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   367
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   368
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   369
        public JModTask addClassPath(Path cp) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   370
            this.classpath.add(cp);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   371
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   372
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   373
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   374
        public JModTask addConfig(Path cp) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   375
            this.config.add(cp);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   376
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   377
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   378
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   379
        public JModTask addJars(Path jars) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   380
            this.jars.add(jars);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   381
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   382
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   383
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   384
        public JModTask addJmods(Path jmods) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   385
            this.jmods.add(jmods);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   386
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   387
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   388
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   389
        public JModTask jmod(Path output) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   390
            this.output = output;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   391
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   392
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   393
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   394
        public JModTask moduleVersion(String moduleVersion) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   395
            this.moduleVersion = moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   396
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   397
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   398
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   399
        public JModTask mainClass(String mainClass) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   400
            this.mainClass = mainClass;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   401
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   402
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   403
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   404
        public JModTask option(String o) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   405
            this.options.add(o);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   406
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   407
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   408
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   409
        private String modulePath() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   410
            // This is expect FIRST jmods THEN jars, if you change this, some tests could fail
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   411
            String jmods = toPath(this.jmods);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   412
            String jars = toPath(this.jars);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   413
            return jmods + File.pathSeparator + jars;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   414
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   415
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   416
        private String toPath(List<Path> paths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   417
            return paths.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   418
                    .map(Path::toString)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   419
                    .collect(Collectors.joining(File.pathSeparator));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   420
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   421
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   422
        private String[] optionsJMod(String cmd) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   423
            List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   424
            options.add(cmd);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   425
            if (!cmds.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   426
                options.add(CMDS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   427
                options.add(toPath(cmds));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   428
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   429
            if (!config.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   430
                options.add(CONFIG_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   431
                options.add(toPath(config));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   432
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   433
            if (hashDependencies != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   434
                options.add(HASH_DEPENDENCIES_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   435
                options.add(hashDependencies);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   436
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   437
            if (mainClass != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   438
                options.add(MAIN_CLASS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   439
                options.add(mainClass);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   440
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   441
            if (!libs.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   442
                options.add(LIBS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   443
                options.add(toPath(libs));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   444
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   445
            if (!classpath.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   446
                options.add(CLASS_PATH_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   447
                options.add(toPath(classpath));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   448
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   449
            if (!jars.isEmpty() || !jmods.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   450
                options.add(MODULE_PATH_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   451
                options.add(modulePath());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   452
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   453
            if (moduleVersion != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   454
                options.add(MODULE_VERSION_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   455
                options.add(moduleVersion);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   456
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   457
            options.addAll(this.options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   458
            if (output != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   459
                options.add(output.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   460
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   461
            return options.toArray(new String[options.size()]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   462
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   463
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   464
        public Result create() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   465
            return cmd("create");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   466
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   467
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   468
        public Result list() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   469
            return cmd("list");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   470
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   471
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   472
        public Result call() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   473
            return cmd("");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   474
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   475
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   476
        private Result cmd(String cmd) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   477
            String[] args = optionsJMod(cmd);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   478
            System.err.println("jmod options: " + optionsPrettyPrint(args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   479
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   480
            int exitCode = jdk.tools.jmod.Main.run(args, new PrintStream(baos));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   481
            String msg = new String(baos.toByteArray());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   482
            return new Result(exitCode, msg, output);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   483
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   484
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   485
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   486
    public static String getPackageName(String canonicalName) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   487
        int index = canonicalName.lastIndexOf('.');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   488
        return index > 0 ? canonicalName.substring(0, index) : "";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   489
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   490
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   491
    public static String getSimpleName(String canonicalName) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   492
        int index = canonicalName.lastIndexOf('.');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   493
        return canonicalName.substring(index + 1);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   494
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   495
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   496
    public static class JImageTask {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   497
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   498
        private final List<Path> pluginModulePath = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   499
        private final List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   500
        private Path dir;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   501
        private Path image;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   502
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   503
        public JImageTask pluginModulePath(Path p) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   504
            this.pluginModulePath.add(p);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   505
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   506
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   507
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   508
        public JImageTask image(Path image) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   509
            this.image = image;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   510
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   511
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   512
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   513
        public JImageTask dir(Path dir) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   514
            this.dir = dir;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   515
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   516
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   517
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   518
        public JImageTask option(String o) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   519
            this.options.add(o);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   520
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   521
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   522
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   523
        private String toPath(List<Path> paths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   524
            return paths.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   525
                    .map(Path::toString)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   526
                    .collect(Collectors.joining(File.pathSeparator));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   527
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   528
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   529
        private String[] optionsJImage(String cmd) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   530
            List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   531
            options.add(cmd);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   532
            if (dir != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   533
                options.add("--dir");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   534
                options.add(dir.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   535
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   536
            if (!pluginModulePath.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   537
                options.add(PLUGINS_MODULE_PATH);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   538
                options.add(toPath(pluginModulePath));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   539
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   540
            options.addAll(this.options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   541
            options.add(image.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   542
            return options.toArray(new String[options.size()]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   543
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   544
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   545
        private Result cmd(String cmd, Path returnPath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   546
            String[] args = optionsJImage(cmd);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   547
            System.err.println("jimage options: " + optionsPrettyPrint(args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   548
            StringWriter writer = new StringWriter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   549
            int exitCode = jdk.tools.jimage.Main.run(args, new PrintWriter(writer));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   550
            return new Result(exitCode, writer.toString(), returnPath);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   551
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   552
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   553
        public Result extract() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   554
            return cmd("extract", dir);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   555
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   556
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   557
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   558
    public static class JLinkTask {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   559
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   560
        private final List<Path> jars = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   561
        private final List<Path> jmods = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   562
        private final List<Path> pluginModulePath = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   563
        private final List<String> addMods = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   564
        private final List<String> limitMods = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   565
        private final List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   566
        private String modulePath;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   567
        private Path output;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   568
        private Path existing;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   569
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   570
        public JLinkTask modulePath(String modulePath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   571
            this.modulePath = modulePath;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   572
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   573
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   574
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   575
        public JLinkTask addJars(Path jars) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   576
            this.jars.add(jars);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   577
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   578
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   579
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   580
        public JLinkTask addJmods(Path jmods) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   581
            this.jmods.add(jmods);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   582
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   583
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   584
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   585
        public JLinkTask pluginModulePath(Path p) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   586
            this.pluginModulePath.add(p);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   587
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   588
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   589
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   590
        public JLinkTask addMods(String moduleName) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   591
            this.addMods.add(moduleName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   592
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   593
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   594
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   595
        public JLinkTask limitMods(String moduleName) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   596
            this.limitMods.add(moduleName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   597
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   598
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   599
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   600
        public JLinkTask output(Path output) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   601
            this.output = output;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   602
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   603
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   604
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   605
        public JLinkTask existing(Path existing) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   606
            this.existing = existing;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   607
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   608
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   609
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   610
        public JLinkTask option(String o) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   611
            this.options.add(o);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   612
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   613
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   614
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   615
        private String modulePath() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   616
            // This is expect FIRST jmods THEN jars, if you change this, some tests could fail
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   617
            String jmods = toPath(this.jmods);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   618
            String jars = toPath(this.jars);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   619
            return jmods + File.pathSeparator + jars;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   620
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   621
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   622
        private String toPath(List<Path> paths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   623
            return paths.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   624
                    .map(Path::toString)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   625
                    .collect(Collectors.joining(File.pathSeparator));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   626
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   627
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   628
        private String[] optionsJLink() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   629
            List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   630
            if (output != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   631
                options.add(OUTPUT_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   632
                options.add(output.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   633
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   634
            if (!addMods.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   635
                options.add(ADD_MODS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   636
                options.add(addMods.stream().collect(Collectors.joining(",")));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   637
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   638
            if (!limitMods.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   639
                options.add(LIMIT_MODS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   640
                options.add(limitMods.stream().collect(Collectors.joining(",")));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   641
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   642
            if (!jars.isEmpty() || !jmods.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   643
                options.add(MODULE_PATH_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   644
                options.add(modulePath());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   645
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   646
            if (modulePath != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   647
                options.add(MODULE_PATH_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   648
                options.add(modulePath);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   649
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   650
            if (!pluginModulePath.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   651
                options.add(PLUGINS_MODULE_PATH);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   652
                options.add(toPath(pluginModulePath));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   653
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   654
            options.addAll(this.options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   655
            return options.toArray(new String[options.size()]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   656
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   657
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   658
        private String[] optionsPostProcessJLink() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   659
            List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   660
            if (existing != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   661
                options.add(POST_PROCESS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   662
                options.add(existing.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   663
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   664
            options.addAll(this.options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   665
            return options.toArray(new String[options.size()]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   666
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   667
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   668
        public Result call() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   669
            String[] args = optionsJLink();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   670
            System.err.println("jlink options: " + optionsPrettyPrint(args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   671
            StringWriter writer = new StringWriter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   672
            int exitCode = jdk.tools.jlink.internal.Main.run(args, new PrintWriter(writer));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   673
            return new Result(exitCode, writer.toString(), output);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   674
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   675
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   676
        public Result callPostProcess() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   677
            String[] args = optionsPostProcessJLink();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   678
            System.err.println("jlink options: " + optionsPrettyPrint(args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   679
            StringWriter writer = new StringWriter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   680
            int exitCode = jdk.tools.jlink.internal.Main.run(args, new PrintWriter(writer));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   681
            return new Result(exitCode, writer.toString(), output);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   682
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   683
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   684
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   685
    public static class InMemorySourceFile {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   686
        public final String packageName;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   687
        public final String className;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   688
        public final String source;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   689
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   690
        public InMemorySourceFile(String packageName, String simpleName, String source) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   691
            this.packageName = packageName;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   692
            this.className = simpleName;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   693
            this.source = source;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   694
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   695
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   696
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   697
    public static class InMemoryFile {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   698
        private final String path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   699
        private final byte[] bytes;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   700
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   701
        public String getPath() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   702
            return path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   703
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   704
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   705
        public InputStream getBytes() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   706
            return new ByteArrayInputStream(bytes);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   707
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   708
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   709
        public InMemoryFile(String path, byte[] bytes) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   710
            this.path = path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   711
            this.bytes = bytes;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   712
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   713
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   714
        public InMemoryFile(String path, InputStream is) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   715
            this(path, readAllBytes(is));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   716
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   717
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   718
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   719
    public static byte[] readAllBytes(InputStream is) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   720
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   721
        byte[] buf = new byte[1024];
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   722
        while (true) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   723
            int n = is.read(buf);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   724
            if (n < 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   725
                break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   726
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   727
            baos.write(buf, 0, n);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   728
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   729
        return baos.toByteArray();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   730
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   731
}