package org.wildfly.swarm.bootstrap; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoadException; import org.wildfly.swarm.bootstrap.modules.BootModuleLoader; /** * @author Bob McWhirter */ public class MainInvoker { private static final String BOOT_MODULE_PROPERTY = "boot.module.loader"; public MainInvoker(Method mainMethod, String... args) { this.mainMethod = mainMethod; this.args = args; System.setProperty(BOOT_MODULE_PROPERTY, BootModuleLoader.class.getName()); } public MainInvoker(Class<?> mainClass, String... args) throws Exception { this(getMainMethod(mainClass), args); } public MainInvoker(String mainClassName, String... args) throws Exception { this(getMainMethod(getMainClass(mainClassName)), args); } public void invoke() throws Exception { this.mainMethod.invoke(null, new Object[]{this.args}); emitReady(); } protected void emitReady() throws Exception { Module module = Module.getBootModuleLoader().loadModule(ModuleIdentifier.create("swarm.container")); Class<?> messagesClass = module.getClassLoader().loadClass("org.wildfly.swarm.internal.SwarmMessages"); Field field = messagesClass.getDeclaredField("MESSAGES"); Object messages = field.get(null); Method ready = messages.getClass().getMethod("wildflySwarmIsReady"); ready.invoke(messages); } public static void main(String... args) throws Exception { System.setProperty(BOOT_MODULE_PROPERTY, BootModuleLoader.class.getName()); List<String> argList = Arrays.asList(args); if (argList.isEmpty()) { throw new RuntimeException("Invalid usage of MainWrapper; actual main-class must be specified"); } String mainClassName = argList.get(0); List<String> actualArgs = argList.subList(1, argList.size()); Class<?> mainClass = getMainClass(mainClassName); Method mainMethod = getMainMethod(mainClass); MainInvoker wrapper = new MainInvoker(mainMethod, actualArgs.toArray(new String[]{})); wrapper.invoke(); } public static Class<?> getMainClass(String mainClassName) throws IOException, URISyntaxException, ModuleLoadException, ClassNotFoundException { Class<?> mainClass = null; try { Module module = Module.getBootModuleLoader().loadModule(ModuleIdentifier.create("swarm.application")); ClassLoader cl = module.getClassLoader(); mainClass = cl.loadClass(mainClassName); } catch (ClassNotFoundException | ModuleLoadException e) { ClassLoader cl = ClassLoader.getSystemClassLoader(); mainClass = cl.loadClass(mainClassName); } if (mainClass == null) { throw new ClassNotFoundException(mainClassName); } return mainClass; } public static Method getMainMethod(Class<?> mainClass) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { final Method mainMethod = mainClass.getMethod("main", String[].class); if (mainMethod == null) { throw new NoSuchMethodException("No method main() found"); } final int modifiers = mainMethod.getModifiers(); if (!Modifier.isStatic(modifiers)) { throw new NoSuchMethodException("Main method is not static for " + mainClass); } return mainMethod; } private final Method mainMethod; private final String[] args; }