ARTEMIS-2047 Compatible option for ActiveMQJMSClient

This commit is contained in:
Clebert Suconic 2018-08-21 11:50:34 -04:00
parent 281cff3d41
commit 55b0d5b0ea
15 changed files with 371 additions and 140 deletions

View File

@ -17,6 +17,9 @@
package org.apache.activemq.artemis.utils; package org.apache.activemq.artemis.utils;
import java.net.URL; import java.net.URL;
import java.util.Properties;
import org.jboss.logging.Logger;
/** /**
* This class will be used to perform generic class-loader operations, * This class will be used to perform generic class-loader operations,
@ -27,6 +30,8 @@ import java.net.URL;
public final class ClassloadingUtil { 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!"; 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) { public static Object newInstanceFromClassLoader(final String className) {
@ -84,7 +89,10 @@ public final class ClassloadingUtil {
} }
public static URL findResource(final String resourceName) { 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 { try {
URL resource = loader.getResource(resourceName); URL resource = loader.getResource(resourceName);
if (resource != null) if (resource != null)
@ -98,4 +106,26 @@ public final class ClassloadingUtil {
return loader.getResource(resourceName); 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;
}
} }

View File

@ -137,8 +137,6 @@ public final class ActiveMQClient {
public static final boolean DEFAULT_USE_TOPOLOGY_FOR_LOADBALANCING = true; 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 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"; public static final String SCHEDULED_THREAD_POOL_SIZE_PROPERTY_KEY = "activemq.artemis.client.global.scheduled.thread.pool.core.size";

View File

@ -21,14 +21,42 @@ import javax.jms.Topic;
import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration; import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration;
import org.apache.activemq.artemis.api.core.TransportConfiguration; 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.ActiveMQConnectionFactory;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination; import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
import org.apache.activemq.artemis.uri.ConnectionFactoryParser; 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. * A utility class for creating ActiveMQ Artemis client-side JMS managed resources.
*/ */
public class ActiveMQJMSClient { 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; * Creates an ActiveMQConnectionFactory;
@ -115,21 +143,37 @@ public class ActiveMQJMSClient {
/** /**
* Creates a client-side representation of a JMS Topic. * 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 * @param name the name of the topic
* @return The Topic * @return The Topic
*/ */
@Deprecated
public static Topic createTopic(final String name) { 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. * 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 * @param name the name of the queue
* @return The Queue * @return The Queue
*/ */
@Deprecated
public static Queue createQueue(final String name) { 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() { private ActiveMQJMSClient() {

View File

@ -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.ActiveMQClient;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator; 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.ActiveMQJMSConstants;
import org.apache.activemq.artemis.api.jms.JMSFactoryType; import org.apache.activemq.artemis.api.jms.JMSFactoryType;
import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl; 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 ignoreJTA;
private boolean enable1xPrefixes = ActiveMQClient.DEFAULT_ENABLE_1X_PREFIXES; private boolean enable1xPrefixes = ActiveMQJMSClient.DEFAULT_ENABLE_1X_PREFIXES;
@Override @Override
public void writeExternal(ObjectOutput out) throws IOException { public void writeExternal(ObjectOutput out) throws IOException {

View File

@ -23,6 +23,7 @@ import java.util.List;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer; import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient; 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.api.jms.JMSFactoryType;
import org.apache.activemq.artemis.jms.server.config.ConnectionFactoryConfiguration; import org.apache.activemq.artemis.jms.server.config.ConnectionFactoryConfiguration;
import org.apache.activemq.artemis.utils.BufferHelper; 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 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; private boolean enableSharedClientID = ActiveMQClient.DEFAULT_ENABLED_SHARED_CLIENT_ID;
@ -640,7 +641,7 @@ public class ConnectionFactoryConfigurationImpl implements ConnectionFactoryConf
deserializationWhiteList = BufferHelper.readNullableSimpleStringAsString(buffer); 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; enableSharedClientID = buffer.readableBytes() > 0 ? buffer.readBoolean() : ActiveMQClient.DEFAULT_ENABLED_SHARED_CLIENT_ID;

View File

@ -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());

View File

@ -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");
}
}

View File

@ -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<String, ClassLoader> loaderMap = new HashMap<>();
private static HashSet<String> 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;
}
}

View File

@ -39,7 +39,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.TWO_FOUR
* cd /compatibility-tests * cd /compatibility-tests
* mvn install -Ptests | tee output.log * 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 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: * On Idea you would do the following:

View File

@ -37,7 +37,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.SNAPSHOT
* cd /compatibility-tests * cd /compatibility-tests
* mvn install -Ptests | tee output.log * 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 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: * On Idea you would do the following:

View File

@ -39,7 +39,7 @@ import org.junit.runners.Parameterized;
* cd /compatibility-tests * cd /compatibility-tests
* mvn install -Ptests | tee output.log * 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 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: * On Idea you would do the following:

View File

@ -42,7 +42,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.TWO_FOUR
* cd /compatibility-tests * cd /compatibility-tests
* mvn install -Ptests | tee output.log * 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 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: * On Idea you would do the following:

View File

@ -36,7 +36,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.ONE_FIVE
* cd /compatibility-tests * cd /compatibility-tests
* mvn install -Ptests | tee output.log * 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 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: * On Idea you would do the following:

View File

@ -38,7 +38,7 @@ import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.SNAPSHOT
* cd /compatibility-tests * cd /compatibility-tests
* mvn install -Ptests | tee output.log * 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 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: * On Idea you would do the following:

View File

@ -18,24 +18,12 @@
package org.apache.activemq.artemis.tests.compatibility; package org.apache.activemq.artemis.tests.compatibility;
import java.io.File; 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.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import org.junit.AfterClass; 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 extends ClasspathBaseTest {
public abstract class VersionedBaseTest {
protected final String server; protected final String server;
protected final String sender; protected final String sender;
@ -45,8 +33,6 @@ public abstract class VersionedBaseTest {
protected ClassLoader senderClassloader; protected ClassLoader senderClassloader;
protected ClassLoader receiverClassloader; protected ClassLoader receiverClassloader;
protected static Map<String, ClassLoader> loaderMap = new HashMap<>();
public VersionedBaseTest(String server, String sender, String receiver) throws Exception { public VersionedBaseTest(String server, String sender, String receiver) throws Exception {
if (server == null) { if (server == null) {
server = sender; server = sender;
@ -54,25 +40,9 @@ public abstract class VersionedBaseTest {
this.server = server; this.server = server;
this.sender = sender; this.sender = sender;
this.receiver = receiver; this.receiver = receiver;
this.serverClassloader = getClasspathProperty(server); this.serverClassloader = getClasspath(server);
this.senderClassloader = getClasspathProperty(sender); this.senderClassloader = getClasspath(sender);
this.receiverClassloader = getClasspathProperty(receiver); this.receiverClassloader = getClasspath(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<String> printed = new HashSet<>();
@ClassRule
public static TemporaryFolder serverFolder;
static {
File parent = new File("./target/tmp");
parent.mkdirs();
serverFolder = new TemporaryFolder(parent);
} }
@AfterClass @AfterClass
@ -80,97 +50,6 @@ public abstract class VersionedBaseTest {
loaderMap.clear(); 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<Object[]> combinatory(Object[] rootSide, Object[] sideLeft, Object[] sideRight) { protected static List<Object[]> combinatory(Object[] rootSide, Object[] sideLeft, Object[] sideRight) {
LinkedList<Object[]> combinations = new LinkedList<>(); LinkedList<Object[]> combinations = new LinkedList<>();
@ -193,7 +72,12 @@ public abstract class VersionedBaseTest {
startServer(folder, loader, serverName, globalMaxSize, false); 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(); folder.mkdirs();
String scriptToUse; String scriptToUse;
@ -208,6 +92,7 @@ public abstract class VersionedBaseTest {
setVariable(loader, "setAddressSettings", setAddressSettings); setVariable(loader, "setAddressSettings", setAddressSettings);
evaluate(loader, scriptToUse, folder.getAbsolutePath(), serverName, server, sender, receiver, globalMaxSize); evaluate(loader, scriptToUse, folder.getAbsolutePath(), serverName, server, sender, receiver, globalMaxSize);
} }
public void stopServer(ClassLoader loader) throws Throwable { public void stopServer(ClassLoader loader) throws Throwable {
execute(loader, "server.stop()"); execute(loader, "server.stop()");
} }