AllModulesCommandTest.java revision 12290:8953c0318163
1/* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import java.io.IOException; 25import java.util.Arrays; 26import java.util.concurrent.CountDownLatch; 27import java.util.Set; 28import java.util.HashSet; 29import static jdk.test.lib.Asserts.assertTrue; 30 31/** 32 * @test 33 * @summary Tests the modules-related JDWP commands 34 * @library /test/lib 35 * @ignore 8170541 36 * @modules jdk.jdwp.agent 37 * @modules java.base/jdk.internal.misc 38 * @compile AllModulesCommandTestDebuggee.java 39 * @run main/othervm AllModulesCommandTest 40 */ 41public class AllModulesCommandTest implements DebuggeeLauncher.Listener { 42 43 private DebuggeeLauncher launcher; 44 private JdwpChannel channel; 45 private CountDownLatch jdwpLatch = new CountDownLatch(1); 46 private Set<String> jdwpModuleNames = new HashSet<>(); 47 private Set<String> javaModuleNames = new HashSet<>(); 48 49 public static void main(String[] args) throws Throwable { 50 new AllModulesCommandTest().doTest(); 51 } 52 53 private void doTest() throws Throwable { 54 launcher = new DebuggeeLauncher(this); 55 launcher.launchDebuggee(); 56 // Await till the debuggee sends all the necessary modules info to check against 57 // then start the JDWP session 58 jdwpLatch.await(); 59 doJdwp(); 60 } 61 62 @Override 63 public void onDebuggeeModuleInfo(String modName) { 64 // The debuggee has sent out info about a loaded module 65 javaModuleNames.add(modName); 66 } 67 68 @Override 69 public void onDebuggeeSendingCompleted() { 70 // The debuggee has completed sending all the info 71 // We can start the JDWP session 72 jdwpLatch.countDown(); 73 } 74 75 @Override 76 public void onDebuggeeError(String message) { 77 System.err.println("Debuggee error: '" + message + "'"); 78 System.exit(1); 79 } 80 81 private void doJdwp() throws Exception { 82 try { 83 // Establish JDWP socket connection 84 channel = new JdwpChannel(); 85 channel.connect(); 86 // Send out ALLMODULES JDWP command 87 // and verify the reply 88 JdwpAllModulesReply reply = new JdwpAllModulesCmd().send(channel); 89 assertReply(reply); 90 for (int i = 0; i < reply.getModulesCount(); ++i) { 91 long modId = reply.getModuleId(i); 92 // For each module reported by JDWP get its name using the JDWP NAME command 93 // and store the reply 94 String modName = getModuleName(modId); 95 System.out.println("i=" + i + ", modId=" + modId + ", modName=" + modName); 96 if (modName != null) { // JDWP reports unnamed modules, ignore them 97 jdwpModuleNames.add(modName); 98 } 99 // Assert the CLASSLOADER commands 100 assertClassLoader(modId, modName); 101 } 102 103 System.out.println("Module names reported by JDWP: " + Arrays.toString(jdwpModuleNames.toArray())); 104 System.out.println("Module names reported by Java: " + Arrays.toString(javaModuleNames.toArray())); 105 106 // Modules reported by the JDWP should be the same as reported by the Java API 107 if (!jdwpModuleNames.equals(javaModuleNames)) { 108 throw new RuntimeException("Modules info reported by Java API differs from that reported by JDWP."); 109 } else { 110 System.out.println("Test passed!"); 111 } 112 113 } finally { 114 launcher.terminateDebuggee(); 115 try { 116 new JdwpExitCmd(0).send(channel); 117 channel.disconnect(); 118 } catch (Exception x) { 119 } 120 } 121 } 122 123 private String getModuleName(long modId) throws IOException { 124 JdwpModNameReply reply = new JdwpModNameCmd(modId).send(channel); 125 assertReply(reply); 126 return reply.getModuleName(); 127 } 128 129 private void assertReply(JdwpReply reply) { 130 // Simple assert for any JDWP reply 131 if (reply.getErrorCode() != 0) { 132 throw new RuntimeException("Unexpected reply error code " + reply.getErrorCode() + " for reply " + reply); 133 } 134 } 135 136 private void assertClassLoader(long modId, String modName) throws IOException { 137 // Verify that the module classloader id is valid 138 JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel); 139 assertReply(reply); 140 long moduleClassLoader = reply.getClassLoaderId(); 141 assertTrue(moduleClassLoader >= 0, "bad classloader refId " + moduleClassLoader + " for module '" + modName + "', moduleId=" + modId); 142 143 String clsModName = getModuleName(modId); 144 if ("java.base".equals(clsModName)) { 145 // For the java.base module, because there will be some loaded classes, we can verify 146 // that some of the loaded classes do report the java.base module as the module they belong to 147 assertGetModule(moduleClassLoader, modId); 148 } 149 } 150 151 private void assertGetModule(long moduleClassLoader, long modId) throws IOException { 152 // Get all the visible classes for the module classloader 153 JdwpVisibleClassesReply visibleClasses = new JdwpVisibleClassesCmd(moduleClassLoader).send(channel); 154 assertReply(visibleClasses); 155 156 boolean moduleFound = false; 157 for (long clsId : visibleClasses.getVisibleClasses()) { 158 // For each visible class get the module the class belongs to 159 JdwpModuleReply modReply = new JdwpModuleCmd(clsId).send(channel); 160 assertReply(modReply); 161 long clsModId = modReply.getModuleId(); 162 163 // At least one of the visible classes should belong to our module 164 if (modId == clsModId) { 165 moduleFound = true; 166 break; 167 } 168 } 169 assertTrue(moduleFound, "None of the visible classes for the classloader of the module " + getModuleName(modId) + " reports the module as its own"); 170 } 171 172} 173