1 /* 2 * Copyright (c) 2015, 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 24 /* 25 * @test 26 * @summary Test exclude VM plugin 27 * @author Jean-Francois Denise 28 * @modules jdk.jlink/jdk.tools.jlink.internal 29 * jdk.jlink/jdk.tools.jlink.internal.plugins 30 * @run main ExcludeVMPluginTest 31 */ 32 import java.io.ByteArrayInputStream; 33 import java.net.URI; 34 import java.nio.file.Path; 35 import java.nio.file.Paths; 36 import java.util.HashMap; 37 import java.util.Map; 38 import jdk.tools.jlink.internal.ResourcePoolManager; 39 40 import jdk.tools.jlink.internal.plugins.ExcludeVMPlugin; 41 import jdk.tools.jlink.plugin.Plugin; 42 import jdk.tools.jlink.plugin.ResourcePool; 43 import jdk.tools.jlink.plugin.ResourcePoolEntry; 44 45 public class ExcludeVMPluginTest { 46 47 private static final String TAG = "# orig in test\n"; 48 49 private static final String[] ARCHITECTURES = {"/", "/amd64/", "/i386/", "/arm/", 50 "/aarch64/", "/toto/"}; 51 52 private static final String[] CLIENT = {"client/" + jvmlib(),}; 53 private static final String[] SERVER = {"server/" + jvmlib()}; 54 private static final String[] MINIMAL = {"minimal/" + jvmlib()}; 55 private static final String[] ALL = {CLIENT[0], SERVER[0], MINIMAL[0]}; 56 private static final String JVM_CFG_ALL = TAG + "-server KNOWN\n-client KNOWN\n-minimal KNOWN\n"; 57 private static final String JVM_CFG_CLIENT = TAG + "-client KNOWN\n"; 58 private static final String JVM_CFG_SERVER = TAG + "-server KNOWN\n"; 59 private static final String JVM_CFG_SERVER_ALIAS_OTHERS = TAG + "-server KNOWN\n-client ALIASED_TO -server\n-minimal ALIASED_TO -server\n"; 60 private static final String JVM_CFG_CLIENT_ALIAS_OTHERS = TAG + "-client KNOWN\n-server ALIASED_TO -client\n-minimal ALIASED_TO -client\n"; 61 private static final String JVM_CFG_MINIMAL_ALIAS_OTHERS = TAG + "-minimal KNOWN\n-server ALIASED_TO -minimal\n-client ALIASED_TO -minimal\n"; 62 private static final String JVM_CFG_MINIMAL = TAG + "-minimal KNOWN\n"; 63 64 public static void main(String[] args) throws Exception { 65 new ExcludeVMPluginTest().test(); 66 } 67 68 public void test() throws Exception { 69 boolean failed = false; 70 71 try { 72 checkVM("toto", ALL, JVM_CFG_ALL, ALL, JVM_CFG_ALL); 73 failed = true; 74 throw new Exception("Should have failed"); 75 } catch (Exception ex) { 76 if (failed) { 77 throw ex; 78 } 79 } 80 81 checkVM("all", ALL, JVM_CFG_ALL, ALL, JVM_CFG_ALL); 82 checkVM("all", CLIENT, JVM_CFG_CLIENT, CLIENT, JVM_CFG_CLIENT); 83 checkVM("all", SERVER, JVM_CFG_SERVER, SERVER, JVM_CFG_SERVER); 84 checkVM("all", MINIMAL, JVM_CFG_MINIMAL, MINIMAL, JVM_CFG_MINIMAL); 85 86 checkVM("server", ALL, JVM_CFG_ALL, SERVER, JVM_CFG_SERVER_ALIAS_OTHERS); 87 checkVM("server", SERVER, JVM_CFG_SERVER, SERVER, JVM_CFG_SERVER); 88 try { 89 checkVM("server", CLIENT, JVM_CFG_CLIENT, SERVER, JVM_CFG_SERVER); 90 failed = true; 91 throw new Exception("Should have failed"); 92 } catch (Exception ex) { 93 if (failed) { 94 throw ex; 95 } 96 } 97 try { 98 checkVM("server", MINIMAL, JVM_CFG_MINIMAL, SERVER, JVM_CFG_SERVER); 99 failed = true; 100 throw new Exception("Should have failed"); 101 } catch (Exception ex) { 102 if (failed) { 103 throw ex; 104 } 105 } 106 107 checkVM("client", ALL, JVM_CFG_ALL, CLIENT, JVM_CFG_CLIENT_ALIAS_OTHERS); 108 checkVM("client", CLIENT, JVM_CFG_CLIENT, CLIENT, JVM_CFG_CLIENT); 109 try { 110 checkVM("client", SERVER, JVM_CFG_SERVER, CLIENT, JVM_CFG_CLIENT); 111 failed = true; 112 throw new Exception("Should have failed"); 113 } catch (Exception ex) { 114 if (failed) { 115 throw ex; 116 } 117 } 118 try { 119 checkVM("client", MINIMAL, JVM_CFG_MINIMAL, CLIENT, JVM_CFG_CLIENT); 120 failed = true; 121 throw new Exception("Should have failed"); 122 } catch (Exception ex) { 123 if (failed) { 124 throw ex; 125 } 126 } 127 128 checkVM("minimal", ALL, JVM_CFG_ALL, MINIMAL, JVM_CFG_MINIMAL_ALIAS_OTHERS); 129 checkVM("minimal", MINIMAL, JVM_CFG_MINIMAL, MINIMAL, JVM_CFG_MINIMAL); 130 try { 131 checkVM("minimal", SERVER, JVM_CFG_SERVER, MINIMAL, JVM_CFG_MINIMAL); 132 failed = true; 133 throw new Exception("Should have failed"); 134 } catch (Exception ex) { 135 if (failed) { 136 throw ex; 137 } 138 } 139 try { 140 checkVM("minimal", CLIENT, JVM_CFG_CLIENT, MINIMAL, JVM_CFG_MINIMAL); 141 failed = true; 142 throw new Exception("Should have failed"); 143 } catch (Exception ex) { 144 if (failed) { 145 throw ex; 146 } 147 } 148 149 } 150 151 public void checkVM(String vm, String[] input, String jvmcfg, String[] expectedOutput, String expectdJvmCfg) throws Exception { 152 153 for (String arch : ARCHITECTURES) { 154 String[] winput = new String[input.length]; 155 String[] woutput = new String[expectedOutput.length]; 156 for (int i = 0; i < input.length; i++) { 157 winput[i] = "/java.base/native" + arch + input[i]; 158 } 159 for (int i = 0; i < expectedOutput.length; i++) { 160 woutput[i] = "/java.base/native" + arch + expectedOutput[i]; 161 } 162 doCheckVM(vm, winput, jvmcfg, woutput, expectdJvmCfg); 163 } 164 } 165 166 private void doCheckVM(String vm, String[] input, String jvmcfg, String[] expectedOutput, String expectdJvmCfg) throws Exception { 167 // Create a pool with jvm.cfg and the input paths. 168 byte[] jvmcfgContent = jvmcfg.getBytes(); 169 ResourcePoolManager poolMgr = new ResourcePoolManager(); 170 poolMgr.add( 171 ResourcePoolEntry.create("/java.base/native/jvm.cfg", 172 ResourcePoolEntry.Type.NATIVE_LIB, jvmcfgContent)); 173 174 // java.base/module-info.class is used by exclude vm plugin 175 // to get current osName(). We read it from jrt-fs and add a 176 // ResourcePoolEntry 177 poolMgr.add( 178 ResourcePoolEntry.create("/java.base/module-info.class", 179 ResourcePoolEntry.Type.CLASS_OR_RESOURCE, getJavaBaseModuleInfo())); 180 for (String in : input) { 181 poolMgr.add(ResourcePoolEntry.create(in, 182 ResourcePoolEntry.Type.NATIVE_LIB, new byte[0])); 183 } 184 ResourcePoolManager outMgr = new ResourcePoolManager(); 185 186 Plugin p = new ExcludeVMPlugin(); 187 Map<String, String> config = new HashMap<>(); 188 if (vm != null) { 189 config.put(ExcludeVMPlugin.NAME, vm); 190 } 191 p.configure(config); 192 ResourcePool out = p.transform(poolMgr.resourcePool(), outMgr.resourcePoolBuilder()); 193 194 String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().contentBytes()); 195 196 if (!expectdJvmCfg.equals(newContent)) { 197 throw new Exception("Got content " + newContent + " expected " + expectdJvmCfg); 198 } 199 200 // Apart from native resources, we should find jvm.cfg and 201 // java.base/module-info.class. So, we add 2 here to the 202 // expected count! 203 if (out.entryCount() != (expectedOutput.length + 2)) { 204 out.entries().forEach(m -> { 205 System.err.println(m.path()); 206 }); 207 throw new Exception("Invalid output size " + out.entryCount() + " expected " + (expectedOutput.length + 2)); 208 } 209 210 out.entries().forEach(md -> { 211 if (md.path().equals("/java.base/native/jvm.cfg") || 212 md.path().equals("/java.base/module-info.class")) { 213 return; 214 } 215 boolean contained = false; 216 for (String o : expectedOutput) { 217 if (md.path().equals(o)) { 218 contained = true; 219 break; 220 } 221 } 222 if (!contained) { 223 throw new RuntimeException(md.path() + " not expected"); 224 } 225 }); 226 } 227 228 // read java.base/module-info.class from jrt-fs 229 private static Path getJavaBaseModuleInfo() { 230 return Paths.get(URI.create("jrt:/modules/java.base/module-info.class")); 231 } 232 233 private static boolean isWindows() { 234 return System.getProperty("os.name").startsWith("Windows"); 235 } 236 237 private static boolean isMac() { 238 return System.getProperty("os.name").startsWith("Mac OS"); 239 } 240 241 private static String jvmlib() { 242 String lib = "libjvm.so"; 243 if (isWindows()) { 244 lib = "jvm.dll"; 245 } else if (isMac()) { 246 lib = "libjvm.dylib"; 247 } 248 return lib; 249 } 250 }