diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ClassloadingUtil.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ClassloadingUtil.java index e27ce0cca7..9ea1b61050 100644 --- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ClassloadingUtil.java +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ClassloadingUtil.java @@ -17,6 +17,9 @@ package org.apache.activemq.artemis.utils; import java.net.URL; +import java.util.Properties; + +import org.jboss.logging.Logger; /** * This class will be used to perform generic class-loader operations, @@ -27,6 +30,8 @@ import java.net.URL; public final class ClassloadingUtil { + private static final Logger logger = Logger.getLogger(ClassloadingUtil.class); + private static final String INSTANTIATION_EXCEPTION_MESSAGE = "Your class must have a constructor without arguments. If it is an inner class, it must be static!"; public static Object newInstanceFromClassLoader(final String className) { @@ -84,7 +89,10 @@ public final class ClassloadingUtil { } public static URL findResource(final String resourceName) { - ClassLoader loader = ClassloadingUtil.class.getClassLoader(); + return findResource(ClassloadingUtil.class.getClassLoader(), resourceName); + } + + public static URL findResource(ClassLoader loader, final String resourceName) { try { URL resource = loader.getResource(resourceName); if (resource != null) @@ -98,4 +106,26 @@ public final class ClassloadingUtil { return loader.getResource(resourceName); } + + + public static String loadProperty(ClassLoader loader, String propertiesFile, String name) { + Properties properties = loadProperties(loader, propertiesFile); + + return (String)properties.get(name); + } + + public static Properties loadProperties(ClassLoader loader, String propertiesFile) { + Properties properties = new Properties(); + + try { + URL url = findResource(loader, propertiesFile); + if (url != null) { + properties.load(url.openStream()); + } + } catch (Throwable ignored) { + logger.warn(ignored); + } + return properties; + } + } diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ActiveMQClient.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ActiveMQClient.java index ab647a3170..f4de508d64 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ActiveMQClient.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ActiveMQClient.java @@ -137,8 +137,6 @@ public final class ActiveMQClient { public static final boolean DEFAULT_USE_TOPOLOGY_FOR_LOADBALANCING = true; - public static final boolean DEFAULT_ENABLE_1X_PREFIXES = false; - public static final String THREAD_POOL_MAX_SIZE_PROPERTY_KEY = "activemq.artemis.client.global.thread.pool.max.size"; public static final String SCHEDULED_THREAD_POOL_SIZE_PROPERTY_KEY = "activemq.artemis.client.global.scheduled.thread.pool.core.size"; diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/api/jms/ActiveMQJMSClient.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/api/jms/ActiveMQJMSClient.java index 9cf0c4da0f..0119e35d2c 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/api/jms/ActiveMQJMSClient.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/api/jms/ActiveMQJMSClient.java @@ -21,14 +21,42 @@ import javax.jms.Topic; import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration; import org.apache.activemq.artemis.api.core.TransportConfiguration; +import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.activemq.artemis.jms.client.ActiveMQDestination; import org.apache.activemq.artemis.uri.ConnectionFactoryParser; +import org.apache.activemq.artemis.utils.ClassloadingUtil; +import org.jboss.logging.Logger; /** * A utility class for creating ActiveMQ Artemis client-side JMS managed resources. */ public class ActiveMQJMSClient { + private static final Logger logger = Logger.getLogger(ActiveMQJMSClient.class); + + public static final boolean DEFAULT_ENABLE_1X_PREFIXES; + + + static { + + String value1X = System.getProperty(ActiveMQJMSClient.class.getName() + ".enable1xPrefixes"); + + if (value1X == null) { + value1X = ClassloadingUtil.loadProperty(ActiveMQJMSClient.class.getClassLoader(), ActiveMQJMSClient.class.getName() + ".properties", "enable1xPrefixes"); + } + + boolean prefixes = false; + + + if (value1X != null) { + try { + prefixes = Boolean.parseBoolean(value1X); + } catch (Throwable e) { + logger.warn(e); + } + } + DEFAULT_ENABLE_1X_PREFIXES = prefixes; + } /** * Creates an ActiveMQConnectionFactory; @@ -115,21 +143,37 @@ public class ActiveMQJMSClient { /** * Creates a client-side representation of a JMS Topic. * + * This method is deprecated. Use {@link org.apache.activemq.artemis.jms.client.ActiveMQSession#createTopic(String)} as that method will know the proper + * prefix used at the target server. + * * @param name the name of the topic * @return The Topic */ + @Deprecated public static Topic createTopic(final String name) { - return ActiveMQDestination.createTopic(name); + if (DEFAULT_ENABLE_1X_PREFIXES) { + return ActiveMQDestination.createTopic(PacketImpl.OLD_TOPIC_PREFIX + name, name); + } else { + return ActiveMQDestination.createTopic(name); + } } /** * Creates a client-side representation of a JMS Queue. * + * This method is deprecated. Use {@link org.apache.activemq.artemis.jms.client.ActiveMQSession#createQueue(String)} (String)} as that method will know the proper + * prefix used at the target server. + * * * @param name the name of the queue * @return The Queue */ + @Deprecated public static Queue createQueue(final String name) { - return ActiveMQDestination.createQueue(name); + if (DEFAULT_ENABLE_1X_PREFIXES) { + return ActiveMQDestination.createQueue(PacketImpl.OLD_QUEUE_PREFIX + name, name); + } else { + return ActiveMQDestination.createQueue(name); + } } private ActiveMQJMSClient() { diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java index 17ee6fe302..a0d036c0ff 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java @@ -48,6 +48,7 @@ import org.apache.activemq.artemis.api.core.UDPBroadcastEndpointFactory; import org.apache.activemq.artemis.api.core.client.ActiveMQClient; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; +import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient; import org.apache.activemq.artemis.api.jms.ActiveMQJMSConstants; import org.apache.activemq.artemis.api.jms.JMSFactoryType; import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl; @@ -94,7 +95,7 @@ public class ActiveMQConnectionFactory extends JNDIStorable implements Connectio private boolean ignoreJTA; - private boolean enable1xPrefixes = ActiveMQClient.DEFAULT_ENABLE_1X_PREFIXES; + private boolean enable1xPrefixes = ActiveMQJMSClient.DEFAULT_ENABLE_1X_PREFIXES; @Override public void writeExternal(ObjectOutput out) throws IOException { diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java index c2ac0b6ad0..e1718bd077 100644 --- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java +++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.activemq.artemis.api.core.ActiveMQBuffer; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.client.ActiveMQClient; +import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient; import org.apache.activemq.artemis.api.jms.JMSFactoryType; import org.apache.activemq.artemis.jms.server.config.ConnectionFactoryConfiguration; import org.apache.activemq.artemis.utils.BufferHelper; @@ -124,7 +125,7 @@ public class ConnectionFactoryConfigurationImpl implements ConnectionFactoryConf private int initialMessagePacketSize = ActiveMQClient.DEFAULT_INITIAL_MESSAGE_PACKET_SIZE; - private boolean enable1xPrefixes = ActiveMQClient.DEFAULT_ENABLE_1X_PREFIXES; + private boolean enable1xPrefixes = ActiveMQJMSClient.DEFAULT_ENABLE_1X_PREFIXES; private boolean enableSharedClientID = ActiveMQClient.DEFAULT_ENABLED_SHARED_CLIENT_ID; @@ -640,7 +641,7 @@ public class ConnectionFactoryConfigurationImpl implements ConnectionFactoryConf deserializationWhiteList = BufferHelper.readNullableSimpleStringAsString(buffer); - enable1xPrefixes = buffer.readableBytes() > 0 ? buffer.readBoolean() : ActiveMQClient.DEFAULT_ENABLE_1X_PREFIXES; + enable1xPrefixes = buffer.readableBytes() > 0 ? buffer.readBoolean() : ActiveMQJMSClient.DEFAULT_ENABLE_1X_PREFIXES; enableSharedClientID = buffer.readableBytes() > 0 ? buffer.readBoolean() : ActiveMQClient.DEFAULT_ENABLED_SHARED_CLIENT_ID; diff --git a/tests/compatibility-tests/src/main/resources/ActiveMQJMSClientCompatibilityTest/validateClient.groovy b/tests/compatibility-tests/src/main/resources/ActiveMQJMSClientCompatibilityTest/validateClient.groovy new file mode 100644 index 0000000000..400a69eb82 --- /dev/null +++ b/tests/compatibility-tests/src/main/resources/ActiveMQJMSClientCompatibilityTest/validateClient.groovy @@ -0,0 +1,28 @@ +import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient +import org.apache.activemq.artemis.jms.client.ActiveMQQueue +import org.apache.activemq.artemis.jms.client.ActiveMQTopic +import org.apache.activemq.artemis.tests.compatibility.GroovyRun + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +ActiveMQQueue queue = (ActiveMQQueue) ActiveMQJMSClient.createQueue("q1"); +GroovyRun.assertEquals("jms.queue.q1", queue.getAddress()); +GroovyRun.assertEquals("q1", queue.getQueueName()); +ActiveMQTopic topic = (ActiveMQTopic) ActiveMQJMSClient.createTopic("t1"); +GroovyRun.assertEquals("jms.topic.t1", topic.getAddress()); +GroovyRun.assertEquals("t1", topic.getTopicName()); diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ActiveMQJMSClientCompatibilityTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ActiveMQJMSClientCompatibilityTest.java new file mode 100644 index 0000000000..91e0e2277b --- /dev/null +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ActiveMQJMSClientCompatibilityTest.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.activemq.artemis.tests.compatibility; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; + +import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient; +import org.apache.activemq.artemis.jms.client.ActiveMQQueue; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Test; +import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.SNAPSHOT; +import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.ONE_FIVE; + +public class ActiveMQJMSClientCompatibilityTest extends ClasspathBaseTest { + + @Test + public void testActiveMQJMSCompatibility_1XPrefix_SNAPSHOT() throws Exception { + + Assert.assertFalse(ActiveMQJMSClient.DEFAULT_ENABLE_1X_PREFIXES); + ActiveMQQueue queue = (ActiveMQQueue)ActiveMQJMSClient.createQueue("t1"); + // this step is to guarantee the class is not affected when there's no property in place + Assert.assertEquals("t1", queue.getAddress()); + + ClassLoader loader = getClasspath(SNAPSHOT, true); + + System.setProperty(ActiveMQJMSClient.class.getName() + ".enable1xPrefixes", "true"); + + try { + + evaluate(loader, "ActiveMQJMSClientCompatibilityTest/validateClient.groovy"); + + } finally { + System.clearProperty(ActiveMQJMSClient.class.getName() + ".enable1xPrefixes"); + } + + } + + @Test + public void testActiveMQJMSCompatibility_1XPrefix_SNAPSHOT_with_properties() throws Exception { + + Assert.assertFalse(ActiveMQJMSClient.DEFAULT_ENABLE_1X_PREFIXES); + ActiveMQQueue queue = (ActiveMQQueue)ActiveMQJMSClient.createQueue("t1"); + // this step is to guarantee the class is not affected when there's no property in place + Assert.assertEquals("t1", queue.getAddress()); + + File file = serverFolder.newFile(ActiveMQJMSClient.class.getName() + ".properties"); + + FileOutputStream fileOutputStream = new FileOutputStream(file); + PrintStream stream = new PrintStream(fileOutputStream); + stream.println("enable1xPrefixes=true"); + stream.close(); + + String snapshotPath = System.getProperty(SNAPSHOT); + Assume.assumeNotNull(snapshotPath); + + String path = serverFolder.getRoot().getAbsolutePath() + File.pathSeparator + snapshotPath; + + + ClassLoader loader = defineClassLoader(path); + + evaluate(loader, "ActiveMQJMSClientCompatibilityTest/validateClient.groovy"); + + } + + @Test + + // The purpose here is just to validate the test itself. Nothing to be fixed here + public void testActiveMQJMSCompatibility_1XPrefix_ONE_FIVE() throws Exception { + ClassLoader loader = getClasspath(ONE_FIVE, false); + + evaluate(loader, "ActiveMQJMSClientCompatibilityTest/validateClient.groovy"); + + } +} diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ClasspathBaseTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ClasspathBaseTest.java new file mode 100644 index 0000000000..d2a4b50e38 --- /dev/null +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ClasspathBaseTest.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.activemq.artemis.tests.compatibility; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import org.junit.Assume; +import org.junit.ClassRule; +import org.junit.rules.TemporaryFolder; + +import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.SNAPSHOT; + +public class ClasspathBaseTest { + + + @ClassRule + public static TemporaryFolder serverFolder; + + static { + File parent = new File("./target/tmp"); + parent.mkdirs(); + serverFolder = new TemporaryFolder(parent); + } + + protected static Map loaderMap = new HashMap<>(); + + private static HashSet printed = new HashSet<>(); + + protected static ClassLoader defineClassLoader(String classPath) throws MalformedURLException { + String[] classPathArray = classPath.split(File.pathSeparator); + URL[] elements = new URL[classPathArray.length]; + for (int i = 0; i < classPathArray.length; i++) { + elements[i] = new File(classPathArray[i]).toPath().toUri().toURL(); + } + + return new URLClassLoader(elements, null); + } + + public static ClassLoader getClasspath(String name) throws Exception { + return getClasspath(name, false); + } + + public static ClassLoader getClasspath(String name, boolean forceNew) throws Exception { + + if (!forceNew) { + if (name.equals(SNAPSHOT)) { + return VersionedBaseTest.class.getClassLoader(); + } + + ClassLoader loader = loaderMap.get(name); + if (loader != null && !forceNew) { + return loader; + } + } + + String value = System.getProperty(name); + + if (!printed.contains(name)) { + boolean ok = value != null && !value.trim().isEmpty(); + if (!ok) { + System.out.println("Add \"-D" + name + "=\'CLASSPATH\'\" into your VM settings"); + System.out.println("You will see it in the output from mvn install at the compatibility-tests"); + System.out.println("... look for output from dependency-scan"); + + // our dependency scan used at the pom under compatibility-tests/pom.xml will generate these, example: + // [INFO] dependency-scan setting: -DARTEMIS-140="/Users/someuser/....." + // copy that into your IDE setting and you should be able to debug it + } + Assume.assumeTrue("Cannot run these tests, no classpath found", ok); + } + + ClassLoader loader = defineClassLoader(value); + if (!forceNew) { + // if we are forcing a new one, there's no point in caching it + loaderMap.put(name, loader); + } + + return loader; + } + + protected static Object evaluate(ClassLoader loader, String script, String... arguments) throws Exception { + return tclCall(loader, () -> { + Class clazz = loader.loadClass(GroovyRun.class.getName()); + Method method = clazz.getMethod("evaluate", String.class, String[].class); + return method.invoke(null, script, arguments); + }); + } + + protected static void setVariable(ClassLoader loader, String name, Object object) throws Exception { + tclCall(loader, () -> { + Class clazz = loader.loadClass(GroovyRun.class.getName()); + Method method = clazz.getMethod("setVariable", String.class, Object.class); + method.invoke(null, name, object); + return null; + }); + } + + protected static Object setVariable(ClassLoader loader, String name) throws Exception { + return tclCall(loader, () -> { + Class clazz = loader.loadClass(GroovyRun.class.getName()); + Method method = clazz.getMethod("getVariable", String.class); + return method.invoke(null, name); + }); + } + + protected static Object execute(ClassLoader loader, String script) throws Exception { + return tclCall(loader, () -> { + Class clazz = loader.loadClass(GroovyRun.class.getName()); + Method method = clazz.getMethod("execute", String.class); + return method.invoke(null, script); + }); + } + + protected static Object tclCall(ClassLoader loader, CallIt run) throws Exception { + + ClassLoader original = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(loader); + try { + return run.run(); + } finally { + Thread.currentThread().setContextClassLoader(original); + } + } + + public interface CallIt { + + Object run() throws Exception; + } + +} diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ConnectionFactoryConfigurationSerializationTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ConnectionFactoryConfigurationSerializationTest.java index 9b7dab8483..93894525fd 100644 --- a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ConnectionFactoryConfigurationSerializationTest.java +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ConnectionFactoryConfigurationSerializationTest.java @@ -39,7 +39,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.TWO_FOUR * cd /compatibility-tests * mvn install -Ptests | tee output.log * - * on the output.log you will see the output generated by {@link #getClasspathProperty(String)} + * on the output.log you will see the output generated by {@link #getClasspath(String)} * * On your IDE, edit the Run Configuration to your test and add those -D as parameters to your test. * On Idea you would do the following: diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ExportImportTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ExportImportTest.java index e70d02ce39..854ef1e096 100644 --- a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ExportImportTest.java +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/ExportImportTest.java @@ -37,7 +37,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.SNAPSHOT * cd /compatibility-tests * mvn install -Ptests | tee output.log * - * on the output.log you will see the output generated by {@link #getClasspathProperty(String)} + * on the output.log you will see the output generated by {@link #getClasspath(String)} * * On your IDE, edit the Run Configuration to your test and add those -D as parameters to your test. * On Idea you would do the following: diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/JournalCompatibilityTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/JournalCompatibilityTest.java index e63f70b27f..27ebdd02c3 100644 --- a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/JournalCompatibilityTest.java +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/JournalCompatibilityTest.java @@ -39,7 +39,7 @@ import org.junit.runners.Parameterized; * cd /compatibility-tests * mvn install -Ptests | tee output.log * - * on the output.log you will see the output generated by {@link #getClasspathProperty(String)} + * on the output.log you will see the output generated by {@link #getClasspath(String)} * * On your IDE, edit the Run Configuration to your test and add those -D as parameters to your test. * On Idea you would do the following: diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/MeshTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/MeshTest.java index 8d4939ea23..37219792a7 100644 --- a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/MeshTest.java +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/MeshTest.java @@ -42,7 +42,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.TWO_FOUR * cd /compatibility-tests * mvn install -Ptests | tee output.log * - * on the output.log you will see the output generated by {@link #getClasspathProperty(String)} + * on the output.log you will see the output generated by {@link #getClasspath(String)} * * On your IDE, edit the Run Configuration to your test and add those -D as parameters to your test. * On Idea you would do the following: diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/SendAckTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/SendAckTest.java index 7fe9eb4ca6..168a56f695 100644 --- a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/SendAckTest.java +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/SendAckTest.java @@ -36,7 +36,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.ONE_FIVE * cd /compatibility-tests * mvn install -Ptests | tee output.log * - * on the output.log you will see the output generated by {@link #getClasspathProperty(String)} + * on the output.log you will see the output generated by {@link #getClasspath(String)} * * On your IDE, edit the Run Configuration to your test and add those -D as parameters to your test. * On Idea you would do the following: diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/SerializationTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/SerializationTest.java index cd7daf2eeb..bb238164f7 100644 --- a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/SerializationTest.java +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/SerializationTest.java @@ -38,7 +38,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.SNAPSHOT * cd /compatibility-tests * mvn install -Ptests | tee output.log * - * on the output.log you will see the output generated by {@link #getClasspathProperty(String)} + * on the output.log you will see the output generated by {@link #getClasspath(String)} * * On your IDE, edit the Run Configuration to your test and add those -D as parameters to your test. * On Idea you would do the following: diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/VersionedBaseTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/VersionedBaseTest.java index 19bafd06de..ab5331d5d2 100644 --- a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/VersionedBaseTest.java +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/VersionedBaseTest.java @@ -18,24 +18,12 @@ package org.apache.activemq.artemis.tests.compatibility; import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Map; import org.junit.AfterClass; -import org.junit.Assume; -import org.junit.ClassRule; -import org.junit.rules.TemporaryFolder; -import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.SNAPSHOT; - -public abstract class VersionedBaseTest { +public abstract class VersionedBaseTest extends ClasspathBaseTest { protected final String server; protected final String sender; @@ -45,8 +33,6 @@ public abstract class VersionedBaseTest { protected ClassLoader senderClassloader; protected ClassLoader receiverClassloader; - protected static Map loaderMap = new HashMap<>(); - public VersionedBaseTest(String server, String sender, String receiver) throws Exception { if (server == null) { server = sender; @@ -54,25 +40,9 @@ public abstract class VersionedBaseTest { this.server = server; this.sender = sender; this.receiver = receiver; - this.serverClassloader = getClasspathProperty(server); - this.senderClassloader = getClasspathProperty(sender); - this.receiverClassloader = getClasspathProperty(receiver); - } - - // This is a test optimization.. - // if false it will span a new VM for each classLoader used. - // this can be a bit faster - public static final boolean USE_CLASSLOADER = true; - - private static HashSet printed = new HashSet<>(); - - @ClassRule - public static TemporaryFolder serverFolder; - - static { - File parent = new File("./target/tmp"); - parent.mkdirs(); - serverFolder = new TemporaryFolder(parent); + this.serverClassloader = getClasspath(server); + this.senderClassloader = getClasspath(sender); + this.receiverClassloader = getClasspath(receiver); } @AfterClass @@ -80,97 +50,6 @@ public abstract class VersionedBaseTest { loaderMap.clear(); } - protected static Object evaluate(ClassLoader loader, String script, String... arguments) throws Exception { - return tclCall(loader, () -> { - Class clazz = loader.loadClass(GroovyRun.class.getName()); - Method method = clazz.getMethod("evaluate", String.class, String[].class); - return method.invoke(null, script, arguments); - }); - } - - protected static void setVariable(ClassLoader loader, String name, Object object) throws Exception { - tclCall(loader, () -> { - Class clazz = loader.loadClass(GroovyRun.class.getName()); - Method method = clazz.getMethod("setVariable", String.class, Object.class); - method.invoke(null, name, object); - return null; - }); - } - - protected static Object setVariable(ClassLoader loader, String name) throws Exception { - return tclCall(loader, () -> { - Class clazz = loader.loadClass(GroovyRun.class.getName()); - Method method = clazz.getMethod("getVariable", String.class); - return method.invoke(null, name); - }); - } - - protected static Object execute(ClassLoader loader, String script) throws Exception { - return tclCall(loader, () -> { - Class clazz = loader.loadClass(GroovyRun.class.getName()); - Method method = clazz.getMethod("execute", String.class); - return method.invoke(null, script); - }); - } - - protected static Object tclCall(ClassLoader loader, CallIt run) throws Exception { - - ClassLoader original = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(loader); - try { - return run.run(); - } finally { - Thread.currentThread().setContextClassLoader(original); - } - } - - public interface CallIt { - Object run() throws Exception; - } - - protected static ClassLoader defineClassLoader(String classPath) throws MalformedURLException { - String[] classPathArray = classPath.split(File.pathSeparator); - URL[] elements = new URL[classPathArray.length]; - for (int i = 0; i < classPathArray.length; i++) { - elements[i] = new File(classPathArray[i]).toPath().toUri().toURL(); - } - - return new URLClassLoader(elements, null); - } - - protected static ClassLoader getClasspathProperty(String name) throws Exception { - - if (name.equals(SNAPSHOT)) { - return VersionedBaseTest.class.getClassLoader(); - } - - ClassLoader loader = loaderMap.get(name); - if (loader != null) { - return loader; - } - - String value = System.getProperty(name); - - if (!printed.contains(name)) { - boolean ok = value != null && !value.trim().isEmpty(); - if (!ok) { - System.out.println("Add \"-D" + name + "=\'CLASSPATH\'\" into your VM settings"); - System.out.println("You will see it in the output from mvn install at the compatibility-tests"); - System.out.println("... look for output from dependency-scan"); - - // our dependency scan used at the pom under compatibility-tests/pom.xml will generate these, example: - // [INFO] dependency-scan setting: -DARTEMIS-140="/Users/someuser/....." - // copy that into your IDE setting and you should be able to debug it - } - Assume.assumeTrue("Cannot run these tests, no classpath found", ok); - } - - loader = defineClassLoader(value); - loaderMap.put(name, loader); - - return loader; - } - protected static List combinatory(Object[] rootSide, Object[] sideLeft, Object[] sideRight) { LinkedList combinations = new LinkedList<>(); @@ -193,7 +72,12 @@ public abstract class VersionedBaseTest { startServer(folder, loader, serverName, globalMaxSize, false); } - public void startServer(File folder, ClassLoader loader, String serverName, String globalMaxSize, boolean setAddressSettings) throws Throwable { + + public void startServer(File folder, + ClassLoader loader, + String serverName, + String globalMaxSize, + boolean setAddressSettings) throws Throwable { folder.mkdirs(); String scriptToUse; @@ -208,6 +92,7 @@ public abstract class VersionedBaseTest { setVariable(loader, "setAddressSettings", setAddressSettings); evaluate(loader, scriptToUse, folder.getAbsolutePath(), serverName, server, sender, receiver, globalMaxSize); } + public void stopServer(ClassLoader loader) throws Throwable { execute(loader, "server.stop()"); }