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