1 /* 2 * Copyright (c) 2014, 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 24 package container; 25 26 import java.io.File; 27 import java.lang.module.Configuration; 28 import java.lang.module.ModuleFinder; 29 import java.lang.module.ResolvedModule; 30 import java.lang.reflect.Layer; 31 import java.lang.reflect.Method; 32 import java.lang.reflect.Module; 33 import java.nio.file.Path; 34 import java.nio.file.Paths; 35 import java.util.Set; 36 37 /** 38 * Exercises dynamic configuration. 39 */ 40 41 public class Main { 42 43 public static void main(String[] args) throws Exception { 44 45 System.out.println("Boot layer"); 46 Layer.boot() 47 .modules() 48 .stream() 49 .map(Module::getName) 50 .sorted() 51 .forEach(System.out::println); 52 53 // "start" two applications in their own layers 54 start("applib", "app1", "app1.Main"); 55 start("applib", "app2", "app2.Main"); 56 } 57 58 static void start(String appModulePath, 59 String appModuleName, 60 String appMainClass) throws Exception { 61 62 System.out.format("Starting %s/%s ...%n", appModuleName, appMainClass); 63 64 String[] dirs = appModulePath.split(File.pathSeparator); 65 Path[] paths = new Path[dirs.length]; 66 int i = 0; 67 for (String dir: dirs) { 68 paths[i++] = Paths.get(dir); 69 } 70 71 ModuleFinder finder = ModuleFinder.of(paths); 72 73 Configuration cf = Layer.boot().configuration() 74 .resolveRequiresAndUses(finder, 75 ModuleFinder.of(), 76 Set.of(appModuleName)); 77 78 System.out.println("Resolved"); 79 cf.modules().stream() 80 .map(ResolvedModule::name) 81 .sorted() 82 .forEach(mn -> System.out.format(" %s%n", mn)); 83 84 // reify the configuration as a Layer 85 ClassLoader scl = ClassLoader.getSystemClassLoader(); 86 Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl); 87 88 // invoke application main method 89 ClassLoader loader = layer.findLoader(appModuleName); 90 Class<?> c = loader.loadClass(appMainClass); 91 Main.class.getModule().addReads(c.getModule()); 92 Method mainMethod = c.getMethod("main", String[].class); 93 94 // set TCCL as that is the EE thing to do 95 ClassLoader tccl = Thread.currentThread().getContextClassLoader(); 96 try { 97 Thread.currentThread().setContextClassLoader(loader); 98 mainMethod.invoke(null, (Object)new String[0]); 99 } finally { 100 Thread.currentThread().setContextClassLoader(tccl); 101 } 102 103 System.out.println(); 104 } 105 }