ARTEMIS-2047 Compatible option for ActiveMQJMSClient
This commit is contained in:
parent
281cff3d41
commit
55b0d5b0ea
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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());
|
|
@ -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");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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()");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue