jdk/test/tools/lib/tests/JImageGenerator.java
author mchung
Wed, 12 Oct 2016 15:41:00 -0700
changeset 41484 834b7539ada3
parent 41212 54a8bb41b174
permissions -rw-r--r--
8164689: Retrofit jar, jlink, jmod as a ToolProvider Reviewed-by: alanb, lancea
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";
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 37779
diff changeset
   109
    private static final String MODULE_PATH_OPTION = "--module-path";
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 37779
diff changeset
   110
    private static final String ADD_MODULES_OPTION = "--add-modules";
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 37779
diff changeset
   111
    private static final String LIMIT_MODULES_OPTION = "--limit-modules";
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 37779
diff changeset
   112
    private static final String PLUGIN_MODULE_PATH = "--plugin-module-path";
36511
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";
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37615
diff changeset
   116
    private static final String HASH_MODULES_OPTION = "--hash-modules";
36511
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 {
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   341
        static final java.util.spi.ToolProvider JMOD_TOOL =
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   342
            java.util.spi.ToolProvider.findFirst("jmod").orElseThrow(() ->
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   343
                new RuntimeException("jmod tool not found")
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   344
            );
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   345
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   346
        private final List<Path> classpath = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   347
        private final List<Path> libs = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   348
        private final List<Path> cmds = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   349
        private final List<Path> config = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   350
        private final List<Path> jars = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   351
        private final List<Path> jmods = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   352
        private final List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   353
        private Path output;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37615
diff changeset
   354
        private String hashModules;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   355
        private String mainClass;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   356
        private String moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   357
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   358
        public JModTask addNativeLibraries(Path cp) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   359
            this.libs.add(cp);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   360
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   361
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   362
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37615
diff changeset
   363
        public JModTask hashModules(String hash) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37615
diff changeset
   364
            this.hashModules = hash;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   365
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   366
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   367
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   368
        public JModTask addCmds(Path cp) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   369
            this.cmds.add(cp);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   370
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   371
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   372
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   373
        public JModTask addClassPath(Path cp) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   374
            this.classpath.add(cp);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   375
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   376
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   377
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   378
        public JModTask addConfig(Path cp) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   379
            this.config.add(cp);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   380
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   381
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   382
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   383
        public JModTask addJars(Path jars) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   384
            this.jars.add(jars);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   385
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   386
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   387
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   388
        public JModTask addJmods(Path jmods) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   389
            this.jmods.add(jmods);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   390
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   391
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   392
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   393
        public JModTask jmod(Path output) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   394
            this.output = output;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   395
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   396
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   397
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   398
        public JModTask moduleVersion(String moduleVersion) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   399
            this.moduleVersion = moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   400
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   401
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   402
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   403
        public JModTask mainClass(String mainClass) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   404
            this.mainClass = mainClass;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   405
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   406
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   407
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   408
        public JModTask option(String o) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   409
            this.options.add(o);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   410
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   411
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   412
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   413
        private String modulePath() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   414
            // This is expect FIRST jmods THEN jars, if you change this, some tests could fail
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   415
            String jmods = toPath(this.jmods);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   416
            String jars = toPath(this.jars);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   417
            return jmods + File.pathSeparator + jars;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   418
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   419
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   420
        private String toPath(List<Path> paths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   421
            return paths.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   422
                    .map(Path::toString)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   423
                    .collect(Collectors.joining(File.pathSeparator));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   424
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   425
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   426
        private String[] optionsJMod(String cmd) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   427
            List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   428
            options.add(cmd);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   429
            if (!cmds.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   430
                options.add(CMDS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   431
                options.add(toPath(cmds));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   432
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   433
            if (!config.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   434
                options.add(CONFIG_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   435
                options.add(toPath(config));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   436
            }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37615
diff changeset
   437
            if (hashModules != null) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37615
diff changeset
   438
                options.add(HASH_MODULES_OPTION);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37615
diff changeset
   439
                options.add(hashModules);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   440
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   441
            if (mainClass != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   442
                options.add(MAIN_CLASS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   443
                options.add(mainClass);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   444
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   445
            if (!libs.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   446
                options.add(LIBS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   447
                options.add(toPath(libs));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   448
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   449
            if (!classpath.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   450
                options.add(CLASS_PATH_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   451
                options.add(toPath(classpath));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   452
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   453
            if (!jars.isEmpty() || !jmods.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   454
                options.add(MODULE_PATH_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   455
                options.add(modulePath());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   456
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   457
            if (moduleVersion != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   458
                options.add(MODULE_VERSION_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   459
                options.add(moduleVersion);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   460
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   461
            options.addAll(this.options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   462
            if (output != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   463
                options.add(output.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   464
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   465
            return options.toArray(new String[options.size()]);
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 create() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   469
            return cmd("create");
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 list() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   473
            return cmd("list");
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
        public Result call() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   477
            return cmd("");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   478
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   479
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   480
        private Result cmd(String cmd) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   481
            String[] args = optionsJMod(cmd);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   482
            System.err.println("jmod options: " + optionsPrettyPrint(args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   483
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   484
            PrintStream ps = new PrintStream(baos);
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   485
            int exitCode = JMOD_TOOL.run(ps, ps, args);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   486
            String msg = new String(baos.toByteArray());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   487
            return new Result(exitCode, msg, output);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   488
        }
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 getPackageName(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 index > 0 ? canonicalName.substring(0, index) : "";
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 String getSimpleName(String canonicalName) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   497
        int index = canonicalName.lastIndexOf('.');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   498
        return canonicalName.substring(index + 1);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   499
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   500
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   501
    public static class JImageTask {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   502
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   503
        private final List<Path> pluginModulePath = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   504
        private final List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   505
        private Path dir;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   506
        private Path image;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   507
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   508
        public JImageTask pluginModulePath(Path p) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   509
            this.pluginModulePath.add(p);
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 image(Path image) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   514
            this.image = image;
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 dir(Path dir) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   519
            this.dir = dir;
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
        public JImageTask option(String o) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   524
            this.options.add(o);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   525
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   526
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   527
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   528
        private String toPath(List<Path> paths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   529
            return paths.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   530
                    .map(Path::toString)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   531
                    .collect(Collectors.joining(File.pathSeparator));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   532
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   533
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   534
        private String[] optionsJImage(String cmd) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   535
            List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   536
            options.add(cmd);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   537
            if (dir != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   538
                options.add("--dir");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   539
                options.add(dir.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   540
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   541
            if (!pluginModulePath.isEmpty()) {
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 37779
diff changeset
   542
                options.add(PLUGIN_MODULE_PATH);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   543
                options.add(toPath(pluginModulePath));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   544
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   545
            options.addAll(this.options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   546
            options.add(image.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   547
            return options.toArray(new String[options.size()]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   548
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   549
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   550
        private Result cmd(String cmd, Path returnPath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   551
            String[] args = optionsJImage(cmd);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   552
            System.err.println("jimage options: " + optionsPrettyPrint(args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   553
            StringWriter writer = new StringWriter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   554
            int exitCode = jdk.tools.jimage.Main.run(args, new PrintWriter(writer));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   555
            return new Result(exitCode, writer.toString(), returnPath);
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 Result extract() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   559
            return cmd("extract", dir);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   560
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   561
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   562
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   563
    public static class JLinkTask {
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   564
        static final java.util.spi.ToolProvider JLINK_TOOL =
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   565
            java.util.spi.ToolProvider.findFirst("jlink").orElseThrow(() ->
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   566
                new RuntimeException("jlink tool not found")
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   567
            );
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   568
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   569
        private final List<Path> jars = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   570
        private final List<Path> jmods = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   571
        private final List<Path> pluginModulePath = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   572
        private final List<String> addMods = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   573
        private final List<String> limitMods = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   574
        private final List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   575
        private String modulePath;
41212
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   576
        // if you want to specifiy repeated --module-path option
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   577
        private String repeatedModulePath;
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   578
        // if you want to specifiy repeated --limit-modules option
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   579
        private String repeatedLimitMods;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   580
        private Path output;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   581
        private Path existing;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   582
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   583
        public JLinkTask modulePath(String modulePath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   584
            this.modulePath = modulePath;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   585
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   586
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   587
41212
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   588
        public JLinkTask repeatedModulePath(String modulePath) {
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   589
            this.repeatedModulePath = modulePath;
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   590
            return this;
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   591
        }
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   592
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   593
        public JLinkTask addJars(Path jars) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   594
            this.jars.add(jars);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   595
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   596
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   597
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   598
        public JLinkTask addJmods(Path jmods) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   599
            this.jmods.add(jmods);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   600
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   601
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   602
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   603
        public JLinkTask pluginModulePath(Path p) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   604
            this.pluginModulePath.add(p);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   605
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   606
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   607
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   608
        public JLinkTask addMods(String moduleName) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   609
            this.addMods.add(moduleName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   610
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   611
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   612
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   613
        public JLinkTask limitMods(String moduleName) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   614
            this.limitMods.add(moduleName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   615
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   616
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   617
41212
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   618
        public JLinkTask repeatedLimitMods(String modules) {
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   619
            this.repeatedLimitMods = modules;
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   620
            return this;
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   621
        }
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   622
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   623
        public JLinkTask output(Path output) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   624
            this.output = output;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   625
            return this;
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
        public JLinkTask existing(Path existing) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   629
            this.existing = existing;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   630
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   631
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   632
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   633
        public JLinkTask option(String o) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   634
            this.options.add(o);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   635
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   636
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   637
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   638
        private String modulePath() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   639
            // This is expect FIRST jmods THEN jars, if you change this, some tests could fail
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   640
            String jmods = toPath(this.jmods);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   641
            String jars = toPath(this.jars);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   642
            return jmods + File.pathSeparator + jars;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   643
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   644
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   645
        private String toPath(List<Path> paths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   646
            return paths.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   647
                    .map(Path::toString)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   648
                    .collect(Collectors.joining(File.pathSeparator));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   649
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   650
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   651
        private String[] optionsJLink() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   652
            List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   653
            if (output != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   654
                options.add(OUTPUT_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   655
                options.add(output.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   656
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   657
            if (!addMods.isEmpty()) {
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 37779
diff changeset
   658
                options.add(ADD_MODULES_OPTION);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   659
                options.add(addMods.stream().collect(Collectors.joining(",")));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   660
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   661
            if (!limitMods.isEmpty()) {
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 37779
diff changeset
   662
                options.add(LIMIT_MODULES_OPTION);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   663
                options.add(limitMods.stream().collect(Collectors.joining(",")));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   664
            }
41212
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   665
            if (repeatedLimitMods != null) {
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   666
                options.add(LIMIT_MODULES_OPTION);
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   667
                options.add(repeatedLimitMods);
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   668
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   669
            if (!jars.isEmpty() || !jmods.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   670
                options.add(MODULE_PATH_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   671
                options.add(modulePath());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   672
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   673
            if (modulePath != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   674
                options.add(MODULE_PATH_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   675
                options.add(modulePath);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   676
            }
41212
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   677
            if (repeatedModulePath != null) {
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   678
                options.add(MODULE_PATH_OPTION);
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   679
                options.add(repeatedModulePath);
54a8bb41b174 8165735: jlink incorrectly accepts multiple --module-path and --limit-modules options
sundar
parents: 40261
diff changeset
   680
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   681
            if (!pluginModulePath.isEmpty()) {
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 37779
diff changeset
   682
                options.add(PLUGIN_MODULE_PATH);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   683
                options.add(toPath(pluginModulePath));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   684
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   685
            options.addAll(this.options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   686
            return options.toArray(new String[options.size()]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   687
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   688
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   689
        private String[] optionsPostProcessJLink() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   690
            List<String> options = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   691
            if (existing != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   692
                options.add(POST_PROCESS_OPTION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   693
                options.add(existing.toString());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   694
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   695
            options.addAll(this.options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   696
            return options.toArray(new String[options.size()]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   697
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   698
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   699
        public Result call() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   700
            String[] args = optionsJLink();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   701
            System.err.println("jlink options: " + optionsPrettyPrint(args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   702
            StringWriter writer = new StringWriter();
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   703
            PrintWriter pw = new PrintWriter(writer);
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   704
            int exitCode = JLINK_TOOL.run(pw, pw, args);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   705
            return new Result(exitCode, writer.toString(), output);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   706
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   707
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   708
        public Result callPostProcess() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   709
            String[] args = optionsPostProcessJLink();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   710
            System.err.println("jlink options: " + optionsPrettyPrint(args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   711
            StringWriter writer = new StringWriter();
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   712
            PrintWriter pw = new PrintWriter(writer);
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41212
diff changeset
   713
            int exitCode = JLINK_TOOL.run(pw, pw, args);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   714
            return new Result(exitCode, writer.toString(), output);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   715
        }
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
    public static class InMemorySourceFile {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   719
        public final String packageName;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   720
        public final String className;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   721
        public final String source;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   722
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   723
        public InMemorySourceFile(String packageName, String simpleName, String source) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   724
            this.packageName = packageName;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   725
            this.className = simpleName;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   726
            this.source = source;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   727
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   728
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   729
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   730
    public static class InMemoryFile {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   731
        private final String path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   732
        private final byte[] bytes;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   733
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   734
        public String getPath() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   735
            return path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   736
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   737
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   738
        public InputStream getBytes() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   739
            return new ByteArrayInputStream(bytes);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   740
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   741
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   742
        public InMemoryFile(String path, byte[] bytes) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   743
            this.path = path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   744
            this.bytes = bytes;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   745
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   746
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   747
        public InMemoryFile(String path, InputStream is) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   748
            this(path, readAllBytes(is));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   749
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   750
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   751
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   752
    public static byte[] readAllBytes(InputStream is) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   753
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   754
        byte[] buf = new byte[1024];
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   755
        while (true) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   756
            int n = is.read(buf);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   757
            if (n < 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   758
                break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   759
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   760
            baos.write(buf, 0, n);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   761
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   762
        return baos.toByteArray();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   763
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   764
}