jdk/test/com/sun/tools/attach/modules/m/p/Main.java
author alanb
Thu, 04 May 2017 07:26:55 +0000
changeset 45004 ea3137042a61
permissions -rw-r--r--
8178380: Module system implementation refresh (5/2017) Reviewed-by: mchung, alanb, sspitsyn Contributed-by: alan.bateman@oracle.com, mandy.chung@oracle.com, chris.hegarty@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     1
/*
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     2
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     4
 *
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     7
 * published by the Free Software Foundation.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     8
 *
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    13
 * accompanied this code).
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    14
 *
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    18
 *
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    21
 * questions.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    22
 */
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    23
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    24
package p;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    25
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    26
import java.io.File;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    27
import java.io.IOException;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    28
import java.io.OutputStream;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    29
import java.nio.file.Files;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    30
import java.nio.file.Path;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    31
import java.nio.file.Paths;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    32
import java.util.ArrayList;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    33
import java.util.List;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    34
import java.util.jar.Attributes;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    35
import java.util.jar.JarEntry;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    36
import java.util.jar.JarFile;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    37
import java.util.jar.JarOutputStream;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    38
import java.util.jar.Manifest;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    39
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    40
import com.sun.tools.attach.VirtualMachine;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    41
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    42
public class Main {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    43
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    44
    public static void main(String[] args) throws Exception {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    45
        System.out.println("#modules loaded: " + moduleInfoCont());
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    46
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    47
        String vmid = "" + ProcessHandle.current().pid();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    48
        VirtualMachine vm = VirtualMachine.attach(vmid);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    49
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    50
        for (String test : args) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    51
            switch (test) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    52
                case "jmx" :
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    53
                    startJMXAgent(vm);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    54
                    break;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    55
                case "javaagent" :
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    56
                    startJavaAgent(vm, createAgentJar());
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    57
                    break;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    58
            }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    59
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    60
            System.out.println("#modules loaded: " + moduleInfoCont());
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    61
        }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    62
    }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    63
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    64
    /**
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    65
     * Locates module-info.class resources to get a count of the module of system
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    66
     * modules.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    67
     */
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    68
    static long moduleInfoCont() {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    69
        ClassLoader scl = ClassLoader.getSystemClassLoader();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    70
        return scl.resources("module-info.class").count();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    71
    }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    72
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    73
    /**
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    74
     * Starts a JMX agent and checks that java.management is loaded.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    75
     */
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    76
    static void startJMXAgent(VirtualMachine vm) throws Exception {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    77
        System.out.println("Start JMX agent");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    78
        vm.startLocalManagementAgent();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    79
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    80
        // types in java.management should be visible
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    81
        Class.forName("javax.management.MXBean");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    82
    }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    83
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    84
    /**
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    85
     * Loads a java agent into the VM and checks that java.instrument is loaded.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    86
     */
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    87
    static void startJavaAgent(VirtualMachine vm, Path agent) throws Exception {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    88
        System.out.println("Load java agent ...");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    89
        vm.loadAgent(agent.toString());
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    90
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    91
        // the Agent class should be visible
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    92
        Class.forName("Agent");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    93
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    94
        // types in java.instrument should be visible
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    95
        Class.forName("java.lang.instrument.Instrumentation");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    96
    }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    97
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    98
    /**
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
    99
     * Creates a java agent, return the file path to the agent JAR file.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   100
     */
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   101
    static Path createAgentJar() throws IOException {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   102
        Manifest man = new Manifest();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   103
        Attributes attrs = man.getMainAttributes();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   104
        attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   105
        attrs.put(new Attributes.Name("Agent-Class"), "Agent");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   106
        Path agent = Paths.get("agent.jar");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   107
        Path dir = Paths.get(System.getProperty("test.classes"));
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   108
        createJarFile(agent, man, dir, "Agent.class");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   109
        return agent;
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   110
    }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   111
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   112
    /**
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   113
     * Creates a JAR file.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   114
     *
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   115
     * Equivalent to {@code jar cfm <jarfile> <manifest> -C <dir> file...}
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   116
     *
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   117
     * The input files are resolved against the given directory. Any input
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   118
     * files that are directories are processed recursively.
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   119
     */
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   120
    static void createJarFile(Path jarfile, Manifest man, Path dir, String... files)
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   121
        throws IOException
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   122
    {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   123
        // create the target directory
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   124
        Path parent = jarfile.getParent();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   125
        if (parent != null)
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   126
            Files.createDirectories(parent);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   127
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   128
        List<Path> entries = new ArrayList<>();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   129
        for (String file : files) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   130
            Files.find(dir.resolve(file), Integer.MAX_VALUE,
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   131
                    (p, attrs) -> attrs.isRegularFile())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   132
                    .map(e -> dir.relativize(e))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   133
                    .forEach(entries::add);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   134
        }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   135
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   136
        try (OutputStream out = Files.newOutputStream(jarfile);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   137
             JarOutputStream jos = new JarOutputStream(out))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   138
        {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   139
            if (man != null) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   140
                JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   141
                jos.putNextEntry(je);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   142
                man.write(jos);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   143
                jos.closeEntry();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   144
            }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   145
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   146
            for (Path entry : entries) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   147
                String name = toJarEntryName(entry);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   148
                jos.putNextEntry(new JarEntry(name));
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   149
                Files.copy(dir.resolve(entry), jos);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   150
                jos.closeEntry();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   151
            }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   152
        }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   153
    }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   154
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   155
    /**
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   156
     * Map a file path to the equivalent name in a JAR file
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   157
     */
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   158
    static String toJarEntryName(Path file) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   159
        Path normalized = file.normalize();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   160
        return normalized.subpath(0, normalized.getNameCount())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   161
                .toString()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   162
                .replace(File.separatorChar, '/');
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   163
    }
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents:
diff changeset
   164
}