From 0771ba511cd9c7445380e6c252717874751521db Mon Sep 17 00:00:00 2001 From: Clebert Suconic Date: Mon, 24 Aug 2015 20:06:53 -0400 Subject: [PATCH] Improving bootstraping / CLI - Added a method on Bootstrap class that could be used on embedding a server --- .../apache/activemq/artemis/boot/Artemis.java | 48 +++++++++++++------ .../apache/activemq/artemis/cli/Artemis.java | 28 +++++++---- .../artemis/cli/commands/ActionContext.java | 4 ++ .../apache/activemq/cli/test/ArtemisTest.java | 20 ++++---- .../artemis/maven/ArtemisCLIPlugin.java | 4 +- .../artemis/maven/ArtemisCreatePlugin.java | 4 +- .../server/impl/RemotingServiceImpl.java | 26 ++++++---- 7 files changed, 85 insertions(+), 49 deletions(-) diff --git a/artemis-boot/src/main/java/org/apache/activemq/artemis/boot/Artemis.java b/artemis-boot/src/main/java/org/apache/activemq/artemis/boot/Artemis.java index 52a6852dcd..114d9a73ef 100644 --- a/artemis-boot/src/main/java/org/apache/activemq/artemis/boot/Artemis.java +++ b/artemis-boot/src/main/java/org/apache/activemq/artemis/boot/Artemis.java @@ -25,6 +25,7 @@ import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.List; /** *

@@ -35,19 +36,31 @@ import java.util.Comparator; public class Artemis { public static void main(String[] args) throws Throwable { - ArrayList dirs = new ArrayList(); - String home = System.getProperty("artemis.home"); - if (home != null) { - dirs.add(new File(new File(home), "lib")); - } + + File fileHome = home != null ? new File(home) : null; String instance = System.getProperty("artemis.instance"); - File instanceFile = null; - if (instance != null) { - instanceFile = new File(instance); - dirs.add(new File(instanceFile, "lib")); + File fileInstance = instance != null ? new File(instance) : null; + execute(fileHome, fileInstance, args); + } + + + /** This is a good method for booting an embedded command */ + public static void execute(File artemisHome, File artemisInstance, List args) throws Throwable { + execute(artemisHome, artemisInstance, (String[]) args.toArray(new String[args.size()])); + } + + /** This is a good method for booting an embedded command */ + public static void execute(File fileHome, File fileInstance, String ... args) throws Throwable { + ArrayList dirs = new ArrayList(); + if (fileHome != null) { + dirs.add(new File(fileHome, "lib")); } + if (fileInstance != null) { + dirs.add(new File(fileInstance, "lib")); + } + ArrayList urls = new ArrayList(); for (File bootdir : dirs) { @@ -75,8 +88,8 @@ public class Artemis { } } - if (instance != null) { - System.setProperty("java.io.tmpdir", new File(new File(instance), "tmp").getCanonicalPath()); + if (fileInstance != null) { + System.setProperty("java.io.tmpdir", new File(fileInstance, "tmp").getCanonicalPath()); } // Lets try to covert the logging.configuration setting to a valid URI @@ -86,23 +99,28 @@ public class Artemis { } // Without the etc on the config, things like JGroups configuration wouldn't be loaded - if (instanceFile != null) { - File etcFile = new File(instance, "etc"); + if (fileInstance != null) { + File etcFile = new File(fileInstance, "etc"); // Adding etc to the classLoader so modules can lookup for their configs urls.add(etcFile.toURI().toURL()); } + ClassLoader originalCL = Thread.currentThread().getContextClassLoader(); + // Now setup our classloader.. URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[urls.size()])); Thread.currentThread().setContextClassLoader(loader); Class clazz = loader.loadClass("org.apache.activemq.artemis.cli.Artemis"); - Method method = clazz.getMethod("main", args.getClass()); + Method method = clazz.getMethod("execute", File.class, File.class, args.getClass()); try { - method.invoke(null, (Object) args); + method.invoke(null, fileHome, fileInstance, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } + finally { + Thread.currentThread().setContextClassLoader(originalCL); + } } diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java index 4692b1f2fb..f40c19ae58 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java @@ -44,13 +44,26 @@ public class Artemis { @SuppressWarnings("unchecked") public static void main(String... args) throws Exception { + execute(null, null, args); + } + + public static Object internalExecute(String... args) throws Exception { + return internalExecute(null, null, args); + } + + public static Object execute(File artemisHome, File artemisInstance, List args) throws Exception { + return execute(artemisHome, artemisInstance, (String[]) args.toArray(new String[args.size()])); + } + + public static Object execute(File artemisHome, File artemisInstance, String... args) throws Exception { try { - execute(args); + return internalExecute(artemisHome, artemisInstance, args); } catch (ConfigurationException configException) { System.err.println(configException.getMessage()); System.out.println(); System.out.println("Configuration should be specified as 'scheme:location'. Default configuration is 'xml:${ARTEMIS_INSTANCE}/etc/bootstrap.xml'"); + return null; } catch (RuntimeException re) { System.err.println(re.getMessage()); @@ -59,18 +72,13 @@ public class Artemis { Cli parser = builder(null).build(); parser.parse("help").execute(ActionContext.system()); + return null; } } - public static Object execute(String... args) throws Exception { - return execute(null, null, args); - } - - public static Object execute(File artemisHome, File artemisInstance, List args) throws Exception { - return execute(artemisHome, artemisInstance, (String[]) args.toArray(new String[args.size()])); - } - - public static Object execute(File artemisHome, File artemisInstance, String... args) throws Exception { + /** This method is used to validate exception returns. + * Useful on test cases */ + public static Object internalExecute(File artemisHome, File artemisInstance, String[] args) throws Exception { Action action = builder(artemisInstance).build().parse(args); action.setHomeValues(artemisHome, artemisInstance); diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionContext.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionContext.java index 244de07a53..b25bfd4ae2 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionContext.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionContext.java @@ -27,6 +27,10 @@ public class ActionContext { this.err = err; } + public ActionContext() { + this(System.in, System.out, System.err); + } + public InputStream in; public PrintStream out; public PrintStream err; diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java index cfcc53f985..c85a0329ca 100644 --- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java +++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java @@ -91,7 +91,7 @@ public class ArtemisTest { Artemis.main("create", temporaryFolder.getRoot().getAbsolutePath(), "--force", "--silent", "--no-web", "--queues", queues, "--topics", topics); System.setProperty("artemis.instance", temporaryFolder.getRoot().getAbsolutePath()); // Some exceptions may happen on the initialization, but they should be ok on start the basic core protocol - Artemis.execute("run"); + Artemis.internalExecute("run"); try (ServerLocator locator = ServerLocatorImpl.newLocator("tcp://localhost:61616"); ClientSessionFactory factory = locator.createSessionFactory(); @@ -106,8 +106,8 @@ public class ArtemisTest { } } - Assert.assertEquals(Integer.valueOf(1000), Artemis.execute("producer", "--message-count", "1000", "--verbose")); - Assert.assertEquals(Integer.valueOf(1000), Artemis.execute("consumer", "--verbose", "--break-on-null", "--receive-timeout", "100")); + Assert.assertEquals(Integer.valueOf(1000), Artemis.internalExecute("producer", "--message-count", "1000", "--verbose")); + Assert.assertEquals(Integer.valueOf(1000), Artemis.internalExecute("consumer", "--verbose", "--break-on-null", "--receive-timeout", "100")); ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616"); Connection connection = cf.createConnection(); @@ -128,22 +128,22 @@ public class ArtemisTest { connection.close(); cf.close(); - Assert.assertEquals(Integer.valueOf(1), Artemis.execute("browser", "--txt-size", "50", "--verbose", "--filter", "fruit='banana'")); + Assert.assertEquals(Integer.valueOf(1), Artemis.internalExecute("browser", "--txt-size", "50", "--verbose", "--filter", "fruit='banana'")); - Assert.assertEquals(Integer.valueOf(100), Artemis.execute("browser", "--txt-size", "50", "--verbose", "--filter", "fruit='orange'")); + Assert.assertEquals(Integer.valueOf(100), Artemis.internalExecute("browser", "--txt-size", "50", "--verbose", "--filter", "fruit='orange'")); - Assert.assertEquals(Integer.valueOf(101), Artemis.execute("browser", "--txt-size", "50", "--verbose")); + Assert.assertEquals(Integer.valueOf(101), Artemis.internalExecute("browser", "--txt-size", "50", "--verbose")); // should only receive 10 messages on browse as I'm setting messageCount=10 - Assert.assertEquals(Integer.valueOf(10), Artemis.execute("browser", "--txt-size", "50", "--verbose", "--message-count", "10")); + Assert.assertEquals(Integer.valueOf(10), Artemis.internalExecute("browser", "--txt-size", "50", "--verbose", "--message-count", "10")); // Nothing was consumed until here as it was only browsing, check it's receiving again - Assert.assertEquals(Integer.valueOf(1), Artemis.execute("consumer", "--txt-size", "50", "--verbose", "--break-on-null", "--receive-timeout", "100", "--filter", "fruit='banana'")); + Assert.assertEquals(Integer.valueOf(1), Artemis.internalExecute("consumer", "--txt-size", "50", "--verbose", "--break-on-null", "--receive-timeout", "100", "--filter", "fruit='banana'")); // Checking it was acked before - Assert.assertEquals(Integer.valueOf(100), Artemis.execute("consumer", "--txt-size", "50", "--verbose", "--break-on-null", "--receive-timeout", "100")); + Assert.assertEquals(Integer.valueOf(100), Artemis.internalExecute("consumer", "--txt-size", "50", "--verbose", "--break-on-null", "--receive-timeout", "100")); - Artemis.execute("stop"); + Artemis.internalExecute("stop"); Assert.assertTrue(Run.latchRunning.await(5, TimeUnit.SECONDS)); Assert.assertEquals(0, LibaioContext.getTotalMaxIO()); diff --git a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCLIPlugin.java b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCLIPlugin.java index 2424d26e70..d0ee8fc3aa 100644 --- a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCLIPlugin.java +++ b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCLIPlugin.java @@ -21,7 +21,6 @@ import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; -import org.apache.activemq.artemis.cli.Artemis; import org.apache.activemq.artemis.cli.commands.Run; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.maven.plugin.MojoExecutionException; @@ -31,6 +30,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; +import org.apache.activemq.artemis.boot.Artemis; @Mojo(name = "cli", defaultPhase = LifecyclePhase.VERIFY) public class ArtemisCLIPlugin extends ArtemisAbstractPlugin { @@ -158,7 +158,7 @@ public class ArtemisCLIPlugin extends ArtemisAbstractPlugin { org.apache.activemq.artemis.cli.process.ProcessBuilder.cleanupProcess(); } - catch (Exception e) { + catch (Throwable e) { throw new MojoExecutionException(e.getMessage(), e); } } diff --git a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCreatePlugin.java b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCreatePlugin.java index a60c341982..79745261b4 100644 --- a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCreatePlugin.java +++ b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCreatePlugin.java @@ -29,7 +29,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.activemq.artemis.cli.Artemis; +import org.apache.activemq.artemis.boot.Artemis; import org.apache.activemq.artemis.utils.FileUtil; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -351,7 +351,7 @@ public class ArtemisCreatePlugin extends ArtemisAbstractPlugin { getLog().info("###################################################################################################"); } - catch (Exception e) { + catch (Throwable e) { getLog().error(e); throw new MojoFailureException(e.getMessage()); } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/server/impl/RemotingServiceImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/server/impl/RemotingServiceImpl.java index 5401c8a001..7d24506882 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/server/impl/RemotingServiceImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/server/impl/RemotingServiceImpl.java @@ -148,15 +148,10 @@ public class RemotingServiceImpl implements RemotingService, ConnectionLifeCycle this.protocolMap.put(coreProtocolManagerFactory.getProtocols()[0], coreProtocolManagerFactory.createProtocolManager(server, coreProtocolManagerFactory.filterInterceptors(incomingInterceptors), coreProtocolManagerFactory.filterInterceptors(outgoingInterceptors))); if (config.isResolveProtocols()) { - ServiceLoader serviceLoader = ServiceLoader.load(ProtocolManagerFactory.class, this.getClass().getClassLoader()); - if (serviceLoader != null) { - for (ProtocolManagerFactory next : serviceLoader) { - String[] protocols = next.getProtocols(); - for (String protocol : protocols) { - ActiveMQServerLogger.LOGGER.addingProtocolSupport(protocol, next.getModuleName()); - protocolMap.put(protocol, next.createProtocolManager(server, next.filterInterceptors(incomingInterceptors), next.filterInterceptors(outgoingInterceptors))); - } - } + resolveProtocols(server, this.getClass().getClassLoader()); + + if (this.getClass().getClassLoader() != Thread.currentThread().getContextClassLoader()) { + resolveProtocols(server, Thread.currentThread().getContextClassLoader()); } } @@ -171,7 +166,18 @@ public class RemotingServiceImpl implements RemotingService, ConnectionLifeCycle } } - // RemotingService implementation ------------------------------- + private void resolveProtocols(ActiveMQServer server, ClassLoader loader) { + ServiceLoader serviceLoader = ServiceLoader.load(ProtocolManagerFactory.class, loader); + if (serviceLoader != null) { + for (ProtocolManagerFactory next : serviceLoader) { + String[] protocols = next.getProtocols(); + for (String protocol : protocols) { + ActiveMQServerLogger.LOGGER.addingProtocolSupport(protocol, next.getModuleName()); + protocolMap.put(protocol, next.createProtocolManager(server, next.filterInterceptors(incomingInterceptors), next.filterInterceptors(outgoingInterceptors))); + } + } + } + } private void setInterceptors(Configuration configuration) { incomingInterceptors.addAll(serviceRegistry.getIncomingInterceptors(configuration.getIncomingInterceptorClassNames()));