diff --git a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/sasl/CramMD5Mechanism.java b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/sasl/CramMD5Mechanism.java index 7ad14e434dc..fbd85a27e14 100644 --- a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/sasl/CramMD5Mechanism.java +++ b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/sasl/CramMD5Mechanism.java @@ -16,7 +16,6 @@ */ package org.apache.activemq.transport.amqp.client.sasl; -import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -24,6 +23,8 @@ import javax.crypto.spec.SecretKeySpec; import javax.security.sasl.SaslException; +import static java.nio.charset.StandardCharsets.US_ASCII; + /** * Implements the SASL PLAIN authentication Mechanism. * @@ -31,7 +32,6 @@ */ public class CramMD5Mechanism extends AbstractMechanism { - private static final String ASCII = "ASCII"; private static final String HMACMD5 = "HMACMD5"; private boolean sentResponse; @@ -54,16 +54,17 @@ public byte[] getInitialResponse() { public byte[] getChallengeResponse(byte[] challenge) throws SaslException { if (!sentResponse && challenge != null && challenge.length != 0) { try { - SecretKeySpec key = new SecretKeySpec(getPassword().getBytes(ASCII), HMACMD5); + SecretKeySpec key = new SecretKeySpec(getPassword().getBytes(US_ASCII), HMACMD5); Mac mac = Mac.getInstance(HMACMD5); mac.init(key); byte[] bytes = mac.doFinal(challenge); - StringBuffer hash = new StringBuffer(getUsername()); + StringBuilder hash = new StringBuilder((bytes.length * 2) + 64); + hash.append(getUsername()); hash.append(' '); - for (int i = 0; i < bytes.length; i++) { - String hex = Integer.toHexString(0xFF & bytes[i]); + for (byte aByte : bytes) { + String hex = Integer.toHexString(0xFF & aByte); if (hex.length() == 1) { hash.append('0'); } @@ -71,9 +72,7 @@ public byte[] getChallengeResponse(byte[] challenge) throws SaslException { } sentResponse = true; - return hash.toString().getBytes(ASCII); - } catch (UnsupportedEncodingException e) { - throw new SaslException("Unable to utilise required encoding", e); + return hash.toString().getBytes(US_ASCII); } catch (InvalidKeyException e) { throw new SaslException("Unable to utilise key", e); } catch (NoSuchAlgorithmException e) { @@ -86,6 +85,6 @@ public byte[] getChallengeResponse(byte[] challenge) throws SaslException { @Override public boolean isApplicable(String username, String password) { - return username != null && username.length() > 0 && password != null && password.length() > 0; + return username != null && !username.isEmpty() && password != null && !password.isEmpty(); } } diff --git a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/util/PropertyUtil.java b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/util/PropertyUtil.java index 9be74978a03..4d9f39e0986 100644 --- a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/util/PropertyUtil.java +++ b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/util/PropertyUtil.java @@ -19,13 +19,13 @@ import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; -import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -85,7 +85,7 @@ public static URI replaceQuery(URI uri, String query) throws URISyntaxException if (questionMark > 0) { schemeSpecificPart = schemeSpecificPart.substring(0, questionMark); } - if (query != null && query.length() > 0) { + if (query != null && !query.isEmpty()) { schemeSpecificPart += "?" + query; } return new URI(uri.getScheme(), schemeSpecificPart, uri.getFragment()); @@ -116,27 +116,23 @@ public static URI eraseQuery(URI uri) throws URISyntaxException { * * @throws URISyntaxException if the given URI is invalid. */ - public static String createQueryString(Map options) throws URISyntaxException { - try { - if (options.size() > 0) { - StringBuffer rc = new StringBuffer(); - boolean first = true; - for (Entry entry : options.entrySet()) { - if (first) { - first = false; - } else { - rc.append("&"); - } - rc.append(URLEncoder.encode(entry.getKey(), "UTF-8")); - rc.append("="); - rc.append(URLEncoder.encode((String) entry.getValue(), "UTF-8")); + public static String createQueryString(Map options) { + if (!options.isEmpty()) { + StringBuilder rc = new StringBuilder(); + boolean first = true; + for (Entry entry : options.entrySet()) { + if (first) { + first = false; + } else { + rc.append("&"); } - return rc.toString(); - } else { - return ""; + rc.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)); + rc.append("="); + rc.append(URLEncoder.encode((String) entry.getValue(), StandardCharsets.UTF_8)); } - } catch (UnsupportedEncodingException e) { - throw (URISyntaxException) new URISyntaxException(e.toString(), "Invalid encoding").initCause(e); + return rc.toString(); + } else { + return ""; } } @@ -196,8 +192,8 @@ public static Map parseQuery(String queryString) throws Exceptio for (int i = 0; i < parameters.length; i++) { int p = parameters[i].indexOf("="); if (p >= 0) { - String name = URLDecoder.decode(parameters[i].substring(0, p), "UTF-8"); - String value = URLDecoder.decode(parameters[i].substring(p + 1), "UTF-8"); + String name = URLDecoder.decode(parameters[i].substring(0, p), StandardCharsets.UTF_8); + String value = URLDecoder.decode(parameters[i].substring(p + 1), StandardCharsets.UTF_8); rc.put(name, value); } else { rc.put(parameters[i], null); diff --git a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/util/StringArrayConverter.java b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/util/StringArrayConverter.java index e5951058266..96003d6a361 100644 --- a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/util/StringArrayConverter.java +++ b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/client/util/StringArrayConverter.java @@ -54,7 +54,8 @@ public static String convertToString(String[] value) { return null; } - StringBuffer result = new StringBuffer(String.valueOf(value[0])); + StringBuilder result = new StringBuilder(value.length * 2); + result.append(value[0]); for (int i = 1; i < value.length; i++) { result.append(",").append(value[i]); } diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java index 510b55f89c4..1eeb6fb8b47 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java @@ -50,6 +50,7 @@ import org.apache.activemq.ConfigurationException; import org.apache.activemq.Service; import org.apache.activemq.advisory.AdvisoryBroker; +import org.apache.activemq.annotation.Experimental; import org.apache.activemq.broker.cluster.ConnectionSplitBroker; import org.apache.activemq.broker.jmx.AnnotatedMBean; import org.apache.activemq.broker.jmx.BrokerMBeanSupport; @@ -223,6 +224,7 @@ public class BrokerService implements Service { private boolean monitorConnectionSplits = false; private int taskRunnerPriority = Thread.NORM_PRIORITY; private boolean dedicatedTaskRunner; + private boolean virtualThreadTaskRunner; private boolean cacheTempDestinations = false;// useful for failover private int timeBeforePurgeTempDestinations = 5000; private final List shutdownHooks = new ArrayList<>(); @@ -1269,7 +1271,7 @@ public void setPersistenceAdapter(PersistenceAdapter persistenceAdapter) throws public TaskRunnerFactory getTaskRunnerFactory() { if (this.taskRunnerFactory == null) { this.taskRunnerFactory = new TaskRunnerFactory("ActiveMQ BrokerService["+getBrokerName()+"] Task", getTaskRunnerPriority(), true, 1000, - isDedicatedTaskRunner()); + isDedicatedTaskRunner(), isVirtualThreadTaskRunner()); this.taskRunnerFactory.setThreadClassLoader(this.getClass().getClassLoader()); } return this.taskRunnerFactory; @@ -1280,9 +1282,10 @@ public void setTaskRunnerFactory(TaskRunnerFactory taskRunnerFactory) { } public TaskRunnerFactory getPersistenceTaskRunnerFactory() { + // [AMQ-9394] TODO: Should we have a separate config flag for virtualThread for persistence task runner? if (taskRunnerFactory == null) { persistenceTaskRunnerFactory = new TaskRunnerFactory("Persistence Adaptor Task", persistenceThreadPriority, - true, 1000, isDedicatedTaskRunner()); + true, 1000, isDedicatedTaskRunner(), isVirtualThreadTaskRunner()); } return persistenceTaskRunnerFactory; } @@ -1891,6 +1894,15 @@ public void setDedicatedTaskRunner(boolean dedicatedTaskRunner) { this.dedicatedTaskRunner = dedicatedTaskRunner; } + public boolean isVirtualThreadTaskRunner() { + return virtualThreadTaskRunner; + } + + @Experimental("Tech Preview for Virtaul Thread support") + public void setVirtualThreadTaskRunner(boolean virtualThreadTaskRunner) { + this.virtualThreadTaskRunner = virtualThreadTaskRunner; + } + public boolean isCacheTempDestinations() { return cacheTempDestinations; } diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java index e8ec158dae0..4f0ab2c7a64 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java @@ -280,11 +280,41 @@ public ObjectName[] getTopics() { return safeGetBroker().getTopicsNonSuppressed(); } + @Override + public int getTotalTopicsCount() { + return safeGetBroker().getTopicRegion().getDestinationMap().size(); + } + + @Override + public int getTotalManagedTopicsCount() { + return safeGetBroker().getTopicsNonSuppressed().length; + } + + @Override + public int getTotalTemporaryTopicsCount() { + return safeGetBroker().getTempTopicRegion().getDestinationMap().size(); + } + @Override public ObjectName[] getQueues() { return safeGetBroker().getQueuesNonSuppressed(); } + @Override + public int getTotalQueuesCount() { + return safeGetBroker().getQueueRegion().getDestinationMap().size(); + } + + @Override + public int getTotalManagedQueuesCount() { + return safeGetBroker().getQueuesNonSuppressed().length; + } + + @Override + public int getTotalTemporaryQueuesCount() { + return safeGetBroker().getTempQueueRegion().getDestinationMap().size(); + } + @Override public String queryQueues(String filter, int page, int pageSize) throws IOException { return DestinationsViewFilter.create(filter) @@ -517,6 +547,16 @@ public boolean isSlave() { return brokerService.isSlave(); } + @Override + public boolean isDedicatedTaskRunner() { + return brokerService.isDedicatedTaskRunner(); + } + + @Override + public boolean isVirtualThreadTaskRunner() { + return brokerService.isVirtualThreadTaskRunner(); + } + private ManagedRegionBroker safeGetBroker() { if (broker == null) { throw new IllegalStateException("Broker is not yet started."); diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerViewMBean.java b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerViewMBean.java index 7584a717349..98df113f690 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerViewMBean.java +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerViewMBean.java @@ -179,9 +179,27 @@ public interface BrokerViewMBean extends Service { @MBeanInfo("Topics (broadcasted 'queues'); generally system information.") ObjectName[] getTopics(); + @MBeanInfo("Total number of topics") + int getTotalTopicsCount(); + + @MBeanInfo("Total number of non suppressed topics") + int getTotalManagedTopicsCount(); + + @MBeanInfo("Total number of temporary topics") + int getTotalTemporaryTopicsCount(); + @MBeanInfo("Standard Queues containing AIE messages.") ObjectName[] getQueues(); + @MBeanInfo("Total number of queues") + int getTotalQueuesCount(); + + @MBeanInfo("Total number of non suppressed queues") + int getTotalManagedQueuesCount(); + + @MBeanInfo("Total number of temporary queues") + int getTotalTemporaryQueuesCount(); + /** * Queue Query API, take a look at {@link DestinationsViewFilter} for more information */ @@ -335,4 +353,11 @@ public interface BrokerViewMBean extends Service { @MBeanInfo(value="The total number of times that the max number of uncommitted count has been exceeded across all destinations") long getTotalMaxUncommittedExceededCount(); + + @MBeanInfo("Dedicated Task Runner enabled.") + boolean isDedicatedTaskRunner(); + + @MBeanInfo("Virtual Thread Task Runner enabled.") + boolean isVirtualThreadTaskRunner(); + } diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/SchedulerBroker.java b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/SchedulerBroker.java index 3a778c5ad1c..54bfc743851 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/SchedulerBroker.java +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/SchedulerBroker.java @@ -240,10 +240,10 @@ public void send(ProducerBrokerExchange producerExchange, final Message messageS final Object delayValue = messageSend.getProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY); String physicalName = messageSend.getDestination().getPhysicalName(); - boolean schedularManage = physicalName.regionMatches(true, 0, ScheduledMessage.AMQ_SCHEDULER_MANAGEMENT_DESTINATION, 0, + boolean schedulerManage = physicalName.regionMatches(true, 0, ScheduledMessage.AMQ_SCHEDULER_MANAGEMENT_DESTINATION, 0, ScheduledMessage.AMQ_SCHEDULER_MANAGEMENT_DESTINATION.length()); - if (schedularManage == true) { + if (schedulerManage == true) { JobScheduler scheduler = getInternalScheduler(); ActiveMQDestination replyTo = messageSend.getReplyTo(); diff --git a/activemq-broker/src/main/java/org/apache/activemq/security/JaasDualAuthenticationBroker.java b/activemq-broker/src/main/java/org/apache/activemq/security/JaasDualAuthenticationBroker.java index c2aacdef10c..9a8d4dfd0ee 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/security/JaasDualAuthenticationBroker.java +++ b/activemq-broker/src/main/java/org/apache/activemq/security/JaasDualAuthenticationBroker.java @@ -110,7 +110,7 @@ public void removeConnection(ConnectionContext context, ConnectionInfo info, Thr } } - private boolean isSSL(ConnectionContext context, ConnectionInfo info) throws Exception { + protected boolean isSSL(ConnectionContext context, ConnectionInfo info) throws Exception { boolean sslCapable = false; Connector connector = context.getConnector(); if (connector instanceof TransportConnector) { diff --git a/activemq-broker/src/test/java/org/apache/activemq/store/PListTestSupport.java b/activemq-broker/src/test/java/org/apache/activemq/store/PListTestSupport.java index b40a6692cd3..5e6d0c58e46 100644 --- a/activemq-broker/src/test/java/org/apache/activemq/store/PListTestSupport.java +++ b/activemq-broker/src/test/java/org/apache/activemq/store/PListTestSupport.java @@ -128,11 +128,9 @@ private PListEntry getFirst(PList plist) throws IOException { } protected void doTestRemove(final int COUNT) throws IOException { - Map map = new LinkedHashMap(); for (int i = 0; i < COUNT; i++) { String test = new String("test" + i); ByteSequence bs = new ByteSequence(test.getBytes()); - map.put(test, bs); plist.addLast(test, bs); } assertEquals(plist.size(), COUNT); diff --git a/activemq-client/pom.xml b/activemq-client/pom.xml index 6b160eb9af9..4d6f5a79eb4 100644 --- a/activemq-client/pom.xml +++ b/activemq-client/pom.xml @@ -200,15 +200,21 @@ + !java.*, + !javax.naming*, + !javax.net*, + !org.apache.activemq*, !com.google.errorprone.annotations, !com.google.errorprone.annotations.concurrent, com.thoughtworks.xstream.*;resolution:="optional", + javax.jmdns.*;resolution:="optional", * com.google.errorprone.annotations, com.google.errorprone.annotations.concurrent + true <_noee>true @@ -396,5 +402,32 @@ + + jdk21-plus + + [21,) + + + + + maven-compiler-plugin + + + java21-compile + compile + + compile + + + 21 + ${project.basedir}/src/main/java21 + true + + + + + + + diff --git a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java index a91349b28b2..74a25b728a3 100644 --- a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java +++ b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java @@ -199,6 +199,7 @@ public class ActiveMQConnection implements Connection, TopicConnection, QueueCon private DestinationSource destinationSource; private final Object ensureConnectionInfoSentMutex = new Object(); private boolean useDedicatedTaskRunner; + private boolean useVirtualThreadTaskRunner; protected AtomicInteger transportInterruptionProcessingComplete = new AtomicInteger(0); private long consumerFailoverRedeliveryWaitPeriod; private volatile Scheduler scheduler; @@ -1068,10 +1069,22 @@ public void setUseDedicatedTaskRunner(boolean useDedicatedTaskRunner) { this.useDedicatedTaskRunner = useDedicatedTaskRunner; } + public boolean isUseVirtualThreadTaskRunner() { + return useVirtualThreadTaskRunner; + } + + public void setUseVirtualThreadTaskRunner(boolean useVirtualThreadTaskRunner) { + this.useVirtualThreadTaskRunner = useVirtualThreadTaskRunner; + } + public TaskRunnerFactory getSessionTaskRunner() { synchronized (this) { if (sessionTaskRunner == null) { - sessionTaskRunner = new TaskRunnerFactory("ActiveMQ Session Task", ThreadPriorities.INBOUND_CLIENT_SESSION, false, 1000, isUseDedicatedTaskRunner(), maxThreadPoolSize); + if(isUseVirtualThreadTaskRunner()) { + sessionTaskRunner = new TaskRunnerFactory("ActiveMQ Session Task", ThreadPriorities.INBOUND_CLIENT_SESSION, false, 1000, isUseDedicatedTaskRunner(), isUseVirtualThreadTaskRunner()); + } else { + sessionTaskRunner = new TaskRunnerFactory("ActiveMQ Session Task", ThreadPriorities.INBOUND_CLIENT_SESSION, false, 1000, isUseDedicatedTaskRunner(), maxThreadPoolSize); + } sessionTaskRunner.setRejectedTaskHandler(rejectedTaskHandler); } } diff --git a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java index 54969f39ceb..ae57d2624b6 100644 --- a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java +++ b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java @@ -148,6 +148,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne private int auditDepth = ActiveMQMessageAudit.DEFAULT_WINDOW_SIZE; private int auditMaximumProducerNumber = ActiveMQMessageAudit.MAXIMUM_PRODUCER_COUNT; private boolean useDedicatedTaskRunner; + private boolean useVirtualThreadTaskRunner; private long consumerFailoverRedeliveryWaitPeriod = 0; private boolean checkForDuplicates = true; private ClientInternalExceptionListener clientInternalExceptionListener; @@ -438,6 +439,7 @@ protected void configureConnection(ActiveMQConnection connection) throws JMSExce connection.setAuditDepth(getAuditDepth()); connection.setAuditMaximumProducerNumber(getAuditMaximumProducerNumber()); connection.setUseDedicatedTaskRunner(isUseDedicatedTaskRunner()); + connection.setUseVirtualThreadTaskRunner(isUseVirtualThreadTaskRunner()); connection.setConsumerFailoverRedeliveryWaitPeriod(getConsumerFailoverRedeliveryWaitPeriod()); connection.setCheckForDuplicates(isCheckForDuplicates()); connection.setMessagePrioritySupported(isMessagePrioritySupported()); @@ -1148,6 +1150,14 @@ public boolean isUseDedicatedTaskRunner() { return useDedicatedTaskRunner; } + public void setUseVirtualThreadTaskRunner(boolean useVirtualThreadTaskRunner) { + this.useVirtualThreadTaskRunner = useVirtualThreadTaskRunner; + } + + public boolean isUseVirtualThreadTaskRunner() { + return useVirtualThreadTaskRunner; + } + public void setConsumerFailoverRedeliveryWaitPeriod(long consumerFailoverRedeliveryWaitPeriod) { this.consumerFailoverRedeliveryWaitPeriod = consumerFailoverRedeliveryWaitPeriod; } diff --git a/activemq-client/src/main/java/org/apache/activemq/annotation/Experimental.java b/activemq-client/src/main/java/org/apache/activemq/annotation/Experimental.java new file mode 100644 index 00000000000..62b6bd429c5 --- /dev/null +++ b/activemq-client/src/main/java/org/apache/activemq/annotation/Experimental.java @@ -0,0 +1,46 @@ +/** + * 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.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The Experimental annotation documents in-progress + * ActiveMQ features and communicates preview status + * of new features that may change or be removed + * between any release, + * + * @author Matt Pavlovich + * @since 6.2.0 + */ +@Documented +@Retention(value=RetentionPolicy.CLASS) +@Target(value={ + ElementType.CONSTRUCTOR, + ElementType.FIELD, + ElementType.LOCAL_VARIABLE, + ElementType.METHOD, + ElementType.PACKAGE, + ElementType.PARAMETER, + ElementType.TYPE}) +public @interface Experimental { + String value(); +} diff --git a/activemq-client/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java b/activemq-client/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java index 002aec79d4b..3c872bef3c3 100644 --- a/activemq-client/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java +++ b/activemq-client/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java @@ -16,8 +16,12 @@ */ package org.apache.activemq.thread; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; @@ -56,6 +60,9 @@ public class TaskRunnerFactory implements Executor { private RejectedExecutionHandler rejectedTaskHandler = null; private ClassLoader threadClassLoader; + // [AMQ-9394] Virtual Thread support + private boolean virtualThreadTaskRunner = false; + public TaskRunnerFactory() { this("ActiveMQ Task"); } @@ -72,13 +79,22 @@ public TaskRunnerFactory(String name, int priority, boolean daemon, int maxItera this(name, priority, daemon, maxIterationsPerRun, dedicatedTaskRunner, getDefaultMaximumPoolSize()); } + public TaskRunnerFactory(String name, int priority, boolean daemon, int maxIterationsPerRun, boolean dedicatedTaskRunner, boolean virtualThreadTaskRunner) { + this(name, priority, daemon, maxIterationsPerRun, dedicatedTaskRunner, getDefaultMaximumPoolSize(), virtualThreadTaskRunner); + } + public TaskRunnerFactory(String name, int priority, boolean daemon, int maxIterationsPerRun, boolean dedicatedTaskRunner, int maxThreadPoolSize) { + this(name, priority, daemon, maxIterationsPerRun, dedicatedTaskRunner, maxThreadPoolSize, false); + } + + public TaskRunnerFactory(String name, int priority, boolean daemon, int maxIterationsPerRun, boolean dedicatedTaskRunner, int maxThreadPoolSize, boolean virtualThreadTaskRunner) { this.name = name; this.priority = priority; this.daemon = daemon; this.maxIterationsPerRun = maxIterationsPerRun; this.dedicatedTaskRunner = dedicatedTaskRunner; this.maxThreadPoolSize = maxThreadPoolSize; + this.virtualThreadTaskRunner = virtualThreadTaskRunner; } public void init() { @@ -90,7 +106,9 @@ public void init() { synchronized(this) { //need to recheck if initDone is true under the lock if (!initDone.get()) { - if (dedicatedTaskRunner || "true".equalsIgnoreCase(System.getProperty("org.apache.activemq.UseDedicatedTaskRunner"))) { + if (virtualThreadTaskRunner || "true".equalsIgnoreCase(System.getProperty("org.apache.activemq.UseVirtualThreadTaskRunner")) ) { + executorRef.compareAndSet(null, createVirtualThreadExecutor()); + } else if (dedicatedTaskRunner || "true".equalsIgnoreCase(System.getProperty("org.apache.activemq.UseDedicatedTaskRunner"))) { executorRef.set(null); } else { executorRef.compareAndSet(null, createDefaultExecutor()); @@ -154,7 +172,11 @@ public TaskRunner createTaskRunner(Task task, String name) { init(); ExecutorService executor = executorRef.get(); if (executor != null) { - return new PooledTaskRunner(executor, task, maxIterationsPerRun); + if(isVirtualThreadTaskRunner()) { + return createVirtualThreadTaskRunner(executor, task, maxIterationsPerRun); + } else { + return new PooledTaskRunner(executor, task, maxIterationsPerRun); + } } else { return new DedicatedTaskRunner(task, name, priority, daemon); } @@ -217,6 +239,48 @@ public void uncaughtException(final Thread t, final Throwable e) { return rc; } + protected ExecutorService createVirtualThreadExecutor() { + if(!(Runtime.version().feature() >= 21)) { + LOG.error("Virtual Thread support requires JDK 21 or higher"); + throw new IllegalStateException("Virtual Thread support requires JDK 21 or higher"); + } + + try { + Class virtualThreadExecutorClass = Class.forName("org.apache.activemq.thread.VirtualThreadExecutor", false, threadClassLoader); + Method method = virtualThreadExecutorClass.getMethod("createVirtualThreadExecutorService", String.class, AtomicLong.class, Logger.class); + Object result = method.invoke(null, name, id, LOG); + if(!ExecutorService.class.isAssignableFrom(result.getClass())) { + throw new IllegalStateException("VirtualThreadExecutor not returned"); + } + LOG.info("VirtualThreadExecutor initialized name:{}", name); + return ExecutorService.class.cast(result); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | InvocationTargetException e) { + LOG.error("VirtualThreadExecutor class failed to load", e); + throw new IllegalStateException(e); + } + } + + protected TaskRunner createVirtualThreadTaskRunner(Executor executor, Task task, int maxIterations) { + if(!(Runtime.version().feature() >= 21)) { + LOG.error("Virtual Thread support requires JDK 21 or higher"); + throw new IllegalStateException("Virtual Thread support requires JDK 21 or higher"); + } + + try { + Class virtualThreadTaskRunnerClass = Class.forName("org.apache.activemq.thread.VirtualThreadTaskRunner", false, threadClassLoader); + Constructor constructor = virtualThreadTaskRunnerClass.getConstructor(Executor.class, Task.class, Integer.TYPE); + Object result = constructor.newInstance(executor, task, maxIterations); + if(!TaskRunner.class.isAssignableFrom(result.getClass())) { + throw new IllegalStateException("VirtualThreadTaskRunner not returned"); + } + return TaskRunner.class.cast(result); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | InvocationTargetException | InstantiationException | IllegalArgumentException e) { + LOG.error("VirtualThreadTaskRunner class failed to load", e); + throw new IllegalStateException(e); + } + } + + public ExecutorService getExecutor() { return executorRef.get(); } @@ -265,6 +329,14 @@ public void setDedicatedTaskRunner(boolean dedicatedTaskRunner) { this.dedicatedTaskRunner = dedicatedTaskRunner; } + public boolean isVirtualThreadTaskRunner() { + return virtualThreadTaskRunner; + } + + public void setVirtualThreadTaskRunner(boolean virtualThreadTaskRunner) { + this.virtualThreadTaskRunner = virtualThreadTaskRunner; + } + public int getMaxThreadPoolSize() { return maxThreadPoolSize; } diff --git a/activemq-client/src/main/java21/org/apache/activemq/thread/VirtualThreadExecutor.java b/activemq-client/src/main/java21/org/apache/activemq/thread/VirtualThreadExecutor.java new file mode 100644 index 00000000000..783e198f4df --- /dev/null +++ b/activemq-client/src/main/java21/org/apache/activemq/thread/VirtualThreadExecutor.java @@ -0,0 +1,80 @@ +/** + * 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.thread; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.activemq.annotation.Experimental; +import org.slf4j.Logger; + +/** + * [AMQ-9394] Virtual Thread support + * + * JDK 21 introduces experimental virtual thread support which allow detaching of OS threads + * from JVM threads. This allows the Java VM to continue working on other tasks while waiting + * for OS operations (specifically I/O) to complete. + * + * JDK 25 provides improvements to Virtual Threads to prevent thread pinning in code blocks + * that use synchronized. + * + * ActiveMQ support for Virtual Threads is currently experimental and profiling of various + * scenarios and end-user feedback is needed to identify hotspots in order to realize + * the full performance benefit. + * + * Additionally, usage to ThreadLocal needs to be removed/refactored to use ScopedValue + * or another approach altogether. ActiveMQ has only a few ThreadLocal usages, but a key + * area is SSLContext support. JIRA [AMQ-9753] will SSL Context ThreadLocal usage. + * + * Status: + * v6.2.0 - Experimental Virtual Thread support introduced. + * + */ +@Experimental("Tech Preview for Virtual Thread support") +public class VirtualThreadExecutor { + + private VirtualThreadExecutor() {} + + public static ExecutorService createVirtualThreadExecutorService(final String name, final AtomicLong id, final Logger LOG) { + + // [AMQ-9394] NOTE: Submitted JDK feature enhancement id: 9076243 to allow AtomicLong thread id param + // https://bugs.java.com/bugdatabase/view_bug?bug_id=JDK-8320377 + Thread.Builder.OfVirtual threadBuilderOfVirtual = Thread.ofVirtual() + .name(name) + .uncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(final Thread t, final Throwable e) { + LOG.error("Error in thread '{}'", t.getName(), e); + } + }); + + // [AMQ-9394] Work around to have global thread id increment across ThreadFactories + ThreadFactory virtualThreadFactory = threadBuilderOfVirtual.factory(); + ThreadFactory atomicThreadFactory = new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread tmpThread = virtualThreadFactory.newThread(r); + tmpThread.setName(tmpThread.getName() + id.incrementAndGet()); + return tmpThread; + } + }; + + return Executors.newThreadPerTaskExecutor(atomicThreadFactory); // [AMQ-9394] Same as newVirtualThreadPerTaskExecutor + } +} diff --git a/activemq-client/src/main/java21/org/apache/activemq/thread/VirtualThreadTaskRunner.java b/activemq-client/src/main/java21/org/apache/activemq/thread/VirtualThreadTaskRunner.java new file mode 100644 index 00000000000..0b58657e7ea --- /dev/null +++ b/activemq-client/src/main/java21/org/apache/activemq/thread/VirtualThreadTaskRunner.java @@ -0,0 +1,176 @@ +/** + * 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.thread; + +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class VirtualThreadTaskRunner implements TaskRunner { + + private static final Logger LOG = LoggerFactory.getLogger(VirtualThreadTaskRunner.class); + private final int maxIterationsPerRun; + private final Executor executor; + private final Task task; + private final Lock taskRunnerLock = new ReentrantLock(); + private final Runnable runable; + private final Condition runnableCondition; + private boolean queued; + private boolean shutdown; + private boolean iterating; + // [AMQ-9394] TODO: Remove references to the running thread where possible + private volatile Thread runningThread; + + public VirtualThreadTaskRunner(Executor executor, final Task task, int maxIterationsPerRun) { + this.executor = executor; + this.maxIterationsPerRun = maxIterationsPerRun; + this.task = task; + runable = new Runnable() { + @Override + public void run() { + runningThread = Thread.currentThread(); + try { + runTask(); + } finally { + LOG.trace("Run task done: {}", task); + runningThread = null; + } + } + }; + this.runnableCondition = taskRunnerLock.newCondition(); + } + + /** + * We Expect MANY wakeup calls on the same TaskRunner. + */ + @Override + public void wakeup() throws InterruptedException { + taskRunnerLock.lock(); + try { + // When we get in here, we make some assumptions of state: + // queued=false, iterating=false: wakeup() has not be called and + // therefore task is not executing. + // queued=true, iterating=false: wakeup() was called but, task + // execution has not started yet + // queued=false, iterating=true : wakeup() was called, which caused + // task execution to start. + // queued=true, iterating=true : wakeup() called after task + // execution was started. + + if (queued || shutdown) { + return; + } + + queued = true; + + // The runTask() method will do this for me once we are done + // iterating. + if (!iterating) { + executor.execute(runable); + } + } finally { + taskRunnerLock.unlock(); + } + } + + /** + * shut down the task + * + * @throws InterruptedException + */ + @Override + public void shutdown(long timeout) throws InterruptedException { + LOG.trace("Shutdown timeout: {} task: {}", timeout, task); + taskRunnerLock.lock(); + try { + shutdown = true; + // the check on the thread is done + // because a call to iterate can result in + // shutDown() being called, which would wait forever + // waiting for iterating to finish + if (runningThread != Thread.currentThread()) { + if (iterating) { + runnableCondition.await(timeout, TimeUnit.MILLISECONDS); + } + } + } finally { + taskRunnerLock.unlock(); + } + } + + @Override + public void shutdown() throws InterruptedException { + shutdown(0); + } + + final void runTask() { + + taskRunnerLock.lock(); + try { + queued = false; + if (shutdown) { + iterating = false; + runnableCondition.signalAll(); + return; + } + iterating = true; + } finally { + taskRunnerLock.unlock(); + } + + // Don't synchronize while we are iterating so that + // multiple wakeup() calls can be executed concurrently. + boolean done = false; + try { + for (int i = 0; i < maxIterationsPerRun; i++) { + LOG.trace("Running task iteration {} - {}", i, task); + if (!task.iterate()) { + done = true; + break; + } + } + } finally { + taskRunnerLock.lock(); + try { + iterating = false; + runnableCondition.signalAll(); + if (shutdown) { + queued = false; + runnableCondition.signalAll(); + } else { + // If we could not iterate all the items + // then we need to re-queue. + if (!done) { + queued = true; + } + + if (queued) { + executor.execute(runable); + } + } + + } finally { + taskRunnerLock.unlock(); + } + } + } +} diff --git a/activemq-client/src/test/java/org/apache/activemq/thread/TaskRunnerTest.java b/activemq-client/src/test/java/org/apache/activemq/thread/TaskRunnerTest.java index 9cfd1d404e4..04f6086fbc4 100644 --- a/activemq-client/src/test/java/org/apache/activemq/thread/TaskRunnerTest.java +++ b/activemq-client/src/test/java/org/apache/activemq/thread/TaskRunnerTest.java @@ -3,8 +3,6 @@ * 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 * diff --git a/activemq-console/pom.xml b/activemq-console/pom.xml index bcdab109bf5..87812b5c1ae 100644 --- a/activemq-console/pom.xml +++ b/activemq-console/pom.xml @@ -34,7 +34,6 @@ org.apache.activemq*;resolution:=optional, org.springframework*;resolution:=optional, sun.management*;resolution:=optional, - org.josql*;resolution:=optional, * @@ -117,10 +116,6 @@ junit test - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.josql - org.jasypt jasypt diff --git a/activemq-console/src/main/java/org/apache/activemq/console/Main.java b/activemq-console/src/main/java/org/apache/activemq/console/Main.java index a6d507accaf..71251729e80 100644 --- a/activemq-console/src/main/java/org/apache/activemq/console/Main.java +++ b/activemq-console/src/main/java/org/apache/activemq/console/Main.java @@ -143,7 +143,7 @@ private static int printClassLoaderTree(ClassLoader cl) { depth = printClassLoaderTree(cl.getParent()) + 1; } - StringBuffer indent = new StringBuffer(); + StringBuilder indent = new StringBuilder(depth * 2); for (int i = 0; i < depth; i++) { indent.append(" "); } @@ -270,7 +270,7 @@ public void addExtensionDirectory(File directory) { } public void addClassPathList(String fileList) { - if (fileList != null && fileList.length() > 0) { + if (fileList != null && !fileList.isEmpty()) { StringTokenizer tokenizer = new StringTokenizer(fileList, File.pathSeparator); while (tokenizer.hasMoreTokens()) { addClassPath(new File(tokenizer.nextToken())); @@ -335,7 +335,7 @@ public int compare(File f1, File f2) { } } - URL u[] = new URL[urls.size()]; + URL[] u = new URL[urls.size()]; urls.toArray(u); classLoader = new URLClassLoader(u, classLoader); } diff --git a/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java b/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java index 68b6ff3bf13..7bf61442fd3 100644 --- a/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java +++ b/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java @@ -75,7 +75,6 @@ public class BrowseCommand extends AbstractJmxCommand { }; private final List queryAddObjects = new ArrayList(10); - private final List querySubObjects = new ArrayList(10); private final Set groupViews = new HashSet(10); private final Set queryViews = new HashSet(10); @@ -144,12 +143,6 @@ protected void handleOption(String token, List tokens) throws Exception // option if (tokens.isEmpty() || ((String)tokens.get(0)).startsWith("-")) { context.printException(new IllegalArgumentException("Message selector not specified")); - return; - } - - StringTokenizer queryTokens = new StringTokenizer((String)tokens.remove(0), COMMAND_OPTION_DELIMETER); - while (queryTokens.hasMoreTokens()) { - querySubObjects.add(queryTokens.nextToken()); } } else if (token.startsWith("--view")) { diff --git a/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java b/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java index c1c8685f45b..44bf8f8619f 100644 --- a/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java +++ b/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java @@ -233,7 +233,7 @@ private void copyFile(File from, File dest) throws IOException { private void copyConfDirectory(File from, File dest) throws IOException { if (from.isDirectory()) { - String files[] = from.list(); + String[] files = from.list(); for (String file : files) { File srcFile = new File(from, file); @@ -271,36 +271,34 @@ private String resolveParam(String paramName, String paramValue, String target) private String getUnixActivemqData() { - StringBuffer res = new StringBuffer(); - res.append("#!/bin/sh\n\n"); - res.append("## Figure out the ACTIVEMQ_BASE from the directory this script was run from\n"); - res.append("PRG=\"$0\"\n"); - res.append("progname=`basename \"$0\"`\n"); - res.append("saveddir=`pwd`\n"); - res.append("# need this for relative symlinks\n"); - res.append("dirname_prg=`dirname \"$PRG\"`\n"); - res.append("cd \"$dirname_prg\"\n"); - res.append("while [ -h \"$PRG\" ] ; do\n"); - res.append(" ls=`ls -ld \"$PRG\"`\n"); - res.append(" link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n"); - res.append(" if expr \"$link\" : '.*/.*' > /dev/null; then\n"); - res.append(" PRG=\"$link\"\n"); - res.append(" else\n"); - res.append(" PRG=`dirname \"$PRG\"`\"/$link\"\n"); - res.append(" fi\n"); - res.append("done\n"); - res.append("ACTIVEMQ_BASE=`dirname \"$PRG\"`/..\n"); - res.append("cd \"$saveddir\"\n\n"); - res.append("ACTIVEMQ_BASE=`cd \"$ACTIVEMQ_BASE\" && pwd`\n\n"); - res.append("## Enable remote debugging\n"); - res.append("#export ACTIVEMQ_DEBUG_OPTS=\"-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005\"\n\n"); - res.append("## Add system properties for this instance here (if needed), e.g\n"); - res.append("#export ACTIVEMQ_OPTS_MEMORY=\"-Xms256M -Xmx1G\"\n"); - res.append("#export ACTIVEMQ_OPTS=\"$ACTIVEMQ_OPTS_MEMORY -Dorg.apache.activemq.UseDedicatedTaskRunner=true -Djava.util.logging.config.file=logging.properties\"\n\n"); - res.append("export ACTIVEMQ_HOME=${activemq.home}\n"); - res.append("export ACTIVEMQ_BASE=$ACTIVEMQ_BASE\n\n"); - res.append("${ACTIVEMQ_HOME}/bin/activemq \"$@\""); - return res.toString(); + return "#!/bin/sh\n\n" + + "## Figure out the ACTIVEMQ_BASE from the directory this script was run from\n" + + "PRG=\"$0\"\n" + + "progname=`basename \"$0\"`\n" + + "saveddir=`pwd`\n" + + "# need this for relative symlinks\n" + + "dirname_prg=`dirname \"$PRG\"`\n" + + "cd \"$dirname_prg\"\n" + + "while [ -h \"$PRG\" ] ; do\n" + + " ls=`ls -ld \"$PRG\"`\n" + + " link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n" + + " if expr \"$link\" : '.*/.*' > /dev/null; then\n" + + " PRG=\"$link\"\n" + + " else\n" + + " PRG=`dirname \"$PRG\"`\"/$link\"\n" + + " fi\n" + + "done\n" + + "ACTIVEMQ_BASE=`dirname \"$PRG\"`/..\n" + + "cd \"$saveddir\"\n\n" + + "ACTIVEMQ_BASE=`cd \"$ACTIVEMQ_BASE\" && pwd`\n\n" + + "## Enable remote debugging\n" + + "#export ACTIVEMQ_DEBUG_OPTS=\"-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005\"\n\n" + + "## Add system properties for this instance here (if needed), e.g\n" + + "#export ACTIVEMQ_OPTS_MEMORY=\"-Xms256M -Xmx1G\"\n" + + "#export ACTIVEMQ_OPTS=\"$ACTIVEMQ_OPTS_MEMORY -Dorg.apache.activemq.UseDedicatedTaskRunner=true -Djava.util.logging.config.file=logging.properties\"\n\n" + + "export ACTIVEMQ_HOME=${activemq.home}\n" + + "export ACTIVEMQ_BASE=$ACTIVEMQ_BASE\n\n" + + "${ACTIVEMQ_HOME}/bin/activemq \"$@\""; } } diff --git a/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java b/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java index 4974925f4fd..c312c735e7b 100644 --- a/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java +++ b/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java @@ -60,7 +60,6 @@ public class PurgeCommand extends AbstractJmxCommand { }; private final List queryAddObjects = new ArrayList(10); - private final List querySubObjects = new ArrayList(10); private boolean resetStatistics; @Override @@ -175,12 +174,6 @@ protected void handleOption(String token, List tokens) throws Exception // option if (tokens.isEmpty() || tokens.get(0).startsWith("-")) { context.printException(new IllegalArgumentException("Message selector not specified")); - return; - } - - StringTokenizer queryTokens = new StringTokenizer(tokens.remove(0), COMMAND_OPTION_DELIMETER); - while (queryTokens.hasMoreTokens()) { - querySubObjects.add(queryTokens.nextToken()); } } else if (token.startsWith("--reset")) { resetStatistics = true; diff --git a/activemq-console/src/main/resources/org/apache/activemq/console/command/store/amq/help.txt b/activemq-console/src/main/resources/org/apache/activemq/console/command/store/amq/help.txt deleted file mode 100644 index afc70fb88d9..00000000000 --- a/activemq-console/src/main/resources/org/apache/activemq/console/command/store/amq/help.txt +++ /dev/null @@ -1,52 +0,0 @@ -Usage: - java org.apache.activemq.console.command.store.amq.AMQJournalTool [options]* (directory) * - -Displays the records stored in the Journal log files used by ActiveMQ. This -tool supports loading the journal data files from multiple directories. Normally -it is run against the journal archive directory and the active journal directory. - -This tool supports controlling the output format using Velocity [1] templates. -It also supports filtering out records using a SQL like WHERE syntax implemented -using JoSQL. - -Options to control output format: - -Any valid Velocity Template Language (VTL) expression can be used to control the -display of the record. - - --message-format=VTL The format used to display message records. Message - records get created every time a producer sends a persistent message to the broker. - The message gets recorded in the journal even if it's transaction is rolled back. - Default VTL: ${location.dataFileId},${location.offset}|${type}|${record.destination}|${record.messageId}|${record.properties}|${body} - - --topic-ack-format=VTL The format used to display topic ack records. A topic - ack records that a durable subscription for a topic has acknowleged a set of messages. - Default VTL: ${location.dataFileId},${location.offset}|${type}|${record.destination}|${record.clientId}|${record.subscritionName}|${record.messageId} - - --queue-ack-format=VTL The format used to display queue ack records. A queue - ack records that a consumer for a quue has acknowleged a message. - Default VTL: ${location.dataFileId},${location.offset}|${type}|${record.destination}|${record.messageAck.lastMessageId} - - --transaction-format=VTL The format used to display transaction records. Transaction records - are used to record transaction related actions like commit and rollback. - Default VTL: ${location.dataFileId},${location.offset}|${type}|${record.transactionId} - - --trace-format=VTL The format used to display trace records. - Trace records are informational messages stored in the journal that assist in Auditing. - For example a trace message is recorded whenever the broker is restarted or when the - long term store is checkpointed. - Default VTL: ${location.dataFileId},${location.offset}|${type}|${record.message} - -Options to control the selection of records displayed: - --where=VALUE The where clause used to control the records selected - for display. It can select on all the fields available in the velocity context. - example: --where="type='ActiveMQTextMessage' and location.dataFileId > 2" - -Other Options: - --help Show this help screen. - -Example: - - java org.apache.activemq.console.command.store.amq.AMQJournalTool /path/to/archive /path/to/journal - - \ No newline at end of file diff --git a/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/adapter/AxionJDBCAdapter.java b/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/adapter/AxionJDBCAdapter.java deleted file mode 100644 index 42fa0935434..00000000000 --- a/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/adapter/AxionJDBCAdapter.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * 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.store.jdbc.adapter; - -import org.apache.activemq.store.jdbc.Statements; - -/** - * Axion specific Adapter. - * - * Axion does not seem to support ALTER statements or sub-selects. This means: - * - We cannot auto upgrade the schema was we roll out new versions of ActiveMQ - * - We cannot delete durable sub messages that have be acknowledged by all consumers. - * - * @org.apache.xbean.XBean element="axionJDBCAdapter" - * - */ -public class AxionJDBCAdapter extends StreamJDBCAdapter { - - @Override - public void setStatements(Statements statements) { - - String[] createStatements = new String[]{ - "CREATE TABLE " + statements.getFullMessageTableName() + "(" - + "ID " + statements.getSequenceDataType() + " NOT NULL" - + ", CONTAINER " + statements.getContainerNameDataType() - + ", MSGID_PROD " + statements.getMsgIdDataType() - + ", MSGID_SEQ " + statements.getSequenceDataType() - + ", EXPIRATION " + statements.getLongDataType() - + ", MSG " + (statements.isUseExternalMessageReferences() ? statements.getStringIdDataType() : statements.getBinaryDataType()) - + ", PRIMARY KEY ( ID ) )", - "CREATE INDEX " + statements.getFullMessageTableName() + "_MIDX ON " + statements.getFullMessageTableName() + " (MSGID_PROD,MSGID_SEQ)", - "CREATE INDEX " + statements.getFullMessageTableName() + "_CIDX ON " + statements.getFullMessageTableName() + " (CONTAINER)", - "CREATE INDEX " + statements.getFullMessageTableName() + "_EIDX ON " + statements.getFullMessageTableName() + " (EXPIRATION)", - "CREATE TABLE " + statements.getFullAckTableName() + "(" - + "CONTAINER " + statements.getContainerNameDataType() + " NOT NULL" - + ", SUB_DEST " + statements.getContainerNameDataType() - + ", CLIENT_ID " + statements.getStringIdDataType() + " NOT NULL" - + ", SUB_NAME " + statements.getStringIdDataType() + " NOT NULL" - + ", SELECTOR " + statements.getStringIdDataType() - + ", LAST_ACKED_ID " + statements.getSequenceDataType() - + ", PRIMARY KEY ( CONTAINER, CLIENT_ID, SUB_NAME))" - }; - statements.setCreateSchemaStatements(createStatements); - statements.setLongDataType("LONG"); - statements.setSequenceDataType("LONG"); - - super.setStatements(statements); - } - -} diff --git a/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/adapter/StreamJDBCAdapter.java b/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/adapter/StreamJDBCAdapter.java deleted file mode 100644 index c83600bde5b..00000000000 --- a/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/adapter/StreamJDBCAdapter.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * 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.store.jdbc.adapter; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.apache.activemq.util.ByteArrayInputStream; - -/** - * This JDBCAdapter inserts and extracts BLOB data using the - * setBinaryStream()/getBinaryStream() operations. - * - * The databases/JDBC drivers that use this adapter are: - *
    - *
  • Axion
  • - *
- * - * @org.apache.xbean.XBean element="streamJDBCAdapter" - * - * - */ -public class StreamJDBCAdapter extends DefaultJDBCAdapter { - - /** - * @see org.apache.activemq.store.jdbc.adapter.DefaultJDBCAdapter#getBinaryData(java.sql.ResultSet, - * int) - */ - @Override - protected byte[] getBinaryData(ResultSet rs, int index) throws SQLException { - - try (InputStream is = rs.getBinaryStream(index); - ByteArrayOutputStream os = new ByteArrayOutputStream(1024 * 4)) { - - int ch; - while ((ch = is.read()) >= 0) { - os.write(ch); - } - - return os.toByteArray(); - } catch (IOException e) { - throw (SQLException)new SQLException("Error reading binary parameter: " + index).initCause(e); - } - } - - /** - * @see org.apache.activemq.store.jdbc.adapter.DefaultJDBCAdapter#setBinaryData(java.sql.PreparedStatement, - * int, byte[]) - */ - @Override - protected void setBinaryData(PreparedStatement s, int index, byte[] data) throws SQLException { - s.setBinaryStream(index, new ByteArrayInputStream(data), data.length); - } - -} diff --git a/activemq-jdbc-store/src/main/resources/META-INF/services/org/apache/activemq/store/jdbc/axion_jdbc_driver b/activemq-jdbc-store/src/main/resources/META-INF/services/org/apache/activemq/store/jdbc/axion_jdbc_driver deleted file mode 100644 index ebd44ae98ea..00000000000 --- a/activemq-jdbc-store/src/main/resources/META-INF/services/org/apache/activemq/store/jdbc/axion_jdbc_driver +++ /dev/null @@ -1,17 +0,0 @@ -## --------------------------------------------------------------------------- -## 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. -## --------------------------------------------------------------------------- -class=org.apache.activemq.store.jdbc.adapter.AxionJDBCAdapter \ No newline at end of file diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java index f52c49421e9..c605460fc30 100644 --- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java +++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java @@ -754,6 +754,25 @@ public void recoverMessages(final MessageRecoveryContext messageRecoveryContext) public void execute(Transaction tx) throws Exception { StoredDestination sd = getStoredDestination(dest, tx); + /** + * [AMQ-9773] + * + * The order index sequence key value increases for every message since the beginning of the + * creation of the index, so the first message available won't be at sequence key value:0 in + * the index when there were older messages acknowledged. + * + * The MessageOrderCursor _position_ value is relative to the index, so there is a disconnect + * between queue _position_ and index sequence value over time. + * + * The MessageRecoveryContext determines the recovery start position based off the provided + * offset, or the position of the requested startMessageId. If a startMessageId is specified, + * but not found in the index, then the value of 0 is used as a fallback. + * + * The MessageRecoveryContext determines the recovery end position based off of the provided + * endMessageId (if provided), or the maximum recovered message count, or if the + * MessageRecoveryListener signals that no more messages should be recovered + * (ie memory is full). + */ Long startSequenceOffset = null; Long endSequenceOffset = null; @@ -766,16 +785,15 @@ public void execute(Transaction tx) throws Exception { if(messageRecoveryContext.getEndMessageId() != null && !messageRecoveryContext.getEndMessageId().isBlank()) { endSequenceOffset = Optional.ofNullable(sd.messageIdIndex.get(tx, messageRecoveryContext.getEndMessageId())) .orElse(startSequenceOffset + Long.valueOf(messageRecoveryContext.getMaxMessageCountReturned())); - } else { - endSequenceOffset = startSequenceOffset + Long.valueOf(messageRecoveryContext.getMaxMessageCountReturned()); + messageRecoveryContext.setEndSequenceId(endSequenceOffset); } - if(endSequenceOffset < startSequenceOffset) { + if(endSequenceOffset != null && + endSequenceOffset < startSequenceOffset) { LOG.warn("Invalid offset parameters start:{} end:{}", startSequenceOffset, endSequenceOffset); throw new IllegalStateException("Invalid offset parameters start:" + startSequenceOffset + " end:" + endSequenceOffset); } - messageRecoveryContext.setEndSequenceId(endSequenceOffset); Entry entry = null; recoverRolledBackAcks(destination.getPhysicalName(), sd, tx, messageRecoveryContext.getMaxMessageCountReturned(), messageRecoveryContext); Set ackedAndPrepared = ackedAndPreparedMap.get(destination.getPhysicalName()); @@ -796,7 +814,11 @@ public void execute(Transaction tx) throws Exception { break; } } - sd.orderIndex.stoppedIterating(); + + // [AMQ-9773] The sd.orderIndex uses the destination's cursor + if(!messageRecoveryContext.isUseDedicatedCursor()) { + sd.orderIndex.stoppedIterating(); + } } }); } finally { diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MessageDatabase.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MessageDatabase.java index dbab306fc7d..64764cf90da 100644 --- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MessageDatabase.java +++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MessageDatabase.java @@ -191,7 +191,7 @@ public void read(DataInput is) throws IOException { openwireVersion = OpenWireFormat.DEFAULT_LEGACY_VERSION; } - LOG.info("KahaDB is version " + version); + LOG.info("KahaDB is version {}", version); } public void write(DataOutput os) throws IOException { @@ -381,7 +381,7 @@ public void execute(Transaction tx) throws IOException { private void startCheckpoint() { if (checkpointInterval == 0 && cleanupInterval == 0) { - LOG.info("periodic checkpoint/cleanup disabled, will occur on clean " + (getCleanupOnStop() ? "shutdown/" : "") + "restart"); + LOG.info("periodic checkpoint/cleanup disabled, will occur on clean {}restart", getCleanupOnStop() ? "shutdown/" : ""); return; } synchronized (schedulerLock) { @@ -448,10 +448,10 @@ public void run() { } } catch (IOException ioe) { LOG.error("Checkpoint failed", ioe); - brokerService.handleIOException(ioe); + handleIOException("CheckpointRunner", ioe); } catch (Throwable e) { LOG.error("Checkpoint failed", e); - brokerService.handleIOException(IOExceptionSupport.create(e)); + handleIOException("CheckpointRunner", IOExceptionSupport.create(e)); } } } @@ -463,7 +463,7 @@ public void open() throws IOException { try { loadPageFile(); } catch (Throwable t) { - LOG.warn("Index corrupted. Recovering the index through journal replay. Cause:" + t); + LOG.warn("Index corrupted. Recovering the index through journal replay. Cause", t); if (LOG.isDebugEnabled()) { LOG.debug("Index load failure", t); } @@ -631,7 +631,7 @@ public void track(Operation operation) { @Override public String toString() { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); buffer.append(location).append(";").append(id).append(";\n"); for (Entry op : destinationOpCount.entrySet()) { buffer.append(op.getKey()).append('+').append(op.getValue().add).append(',').append('-').append(op.getValue().remove).append(';'); @@ -2120,10 +2120,10 @@ public void run() { forwarded = true; } catch (IOException ioe) { LOG.error("Forwarding of acks failed", ioe); - brokerService.handleIOException(ioe); + handleIOException("AckCompactionRunner", ioe); } catch (Throwable e) { LOG.error("Forwarding of acks failed", e); - brokerService.handleIOException(IOExceptionSupport.create(e)); + handleIOException("AckCompactionRunner", IOExceptionSupport.create(e)); } } finally { checkpointLock.readLock().unlock(); @@ -2136,10 +2136,10 @@ public void run() { } } catch (IOException ioe) { LOG.error("Checkpoint failed", ioe); - brokerService.handleIOException(ioe); + handleIOException("AckCompactionRunner", ioe); } catch (Throwable e) { LOG.error("Checkpoint failed", e); - brokerService.handleIOException(IOExceptionSupport.create(e)); + handleIOException("AckCompactionRunner", IOExceptionSupport.create(e)); } } } @@ -4274,4 +4274,27 @@ protected Class resolveClass(ObjectStreamClass desc) throws IOException, Clas } } + + /* + * Execute the configured IOExceptionHandler when an IOException is thrown during + * task execution and handle any runtime exceptions that the handler itself might throw. + * + * By default, the DefaultIOExceptionHandler will stop the broker when handling an IOException, + * however, if DefaultIOExceptionHandler is configured with startStopConnectors to be true + * it will throw a SuppressReplyException and not stop the broker. It's also possible another + * custom implementation of IOExceptionHandler could throw a runtime exception. + * + * This method will now handle and log those runtime exceptions so that the task will not + * die and will continue to execute future iterations if the broker is not shut down. + */ + private void handleIOException(String taskName, IOException ioe) { + try { + brokerService.handleIOException(ioe); + } catch (RuntimeException e) { + LOG.warn("IOException handler threw exception in task {} with " + + "error: {}, continuing.", taskName, + e.getMessage()); + LOG.debug(e.getMessage(), e); + } + } } diff --git a/activemq-karaf/src/main/resources/features-core.xml b/activemq-karaf/src/main/resources/features-core.xml index 99fe8713716..5a1748a99c7 100644 --- a/activemq-karaf/src/main/resources/features-core.xml +++ b/activemq-karaf/src/main/resources/features-core.xml @@ -65,7 +65,7 @@ mvn:org.codehaus.jettison/jettison/${jettison-version} mvn:com.fasterxml.jackson.core/jackson-core/${jackson-version} mvn:com.fasterxml.jackson.core/jackson-databind/${jackson-version} - mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson-version} + mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson-annotations-version} diff --git a/activemq-openwire-generator/src/main/java/org/apache/activemq/openwire/tool/CHeadersGenerator.java b/activemq-openwire-generator/src/main/java/org/apache/activemq/openwire/tool/CHeadersGenerator.java index 627481926ca..830a7fd088e 100644 --- a/activemq-openwire-generator/src/main/java/org/apache/activemq/openwire/tool/CHeadersGenerator.java +++ b/activemq-openwire-generator/src/main/java/org/apache/activemq/openwire/tool/CHeadersGenerator.java @@ -74,7 +74,7 @@ protected void generateLicence(PrintWriter out) { } String changeCase(String value) { - StringBuffer b = new StringBuffer(); + StringBuilder b = new StringBuilder(); char[] cs = value.toCharArray(); for (int i = 0; i < cs.length; i++) { char c = cs[i]; diff --git a/activemq-osgi/pom.xml b/activemq-osgi/pom.xml index 74a3de4522e..8ef951a2835 100644 --- a/activemq-osgi/pom.xml +++ b/activemq-osgi/pom.xml @@ -263,7 +263,7 @@ maven-resources-plugin - copy-xbean + copy-activemq-spring-resources validate copy-resources @@ -275,6 +275,7 @@ ${basedir}/../activemq-spring/target/classes/ activemq.xsd* + META-INF/spring.schemas diff --git a/activemq-osgi/src/main/resources/META-INF/spring.schemas b/activemq-osgi/src/main/resources/META-INF/spring.schemas deleted file mode 100644 index aa9b3b7c82d..00000000000 --- a/activemq-osgi/src/main/resources/META-INF/spring.schemas +++ /dev/null @@ -1,124 +0,0 @@ -## --------------------------------------------------------------------------- -## 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. -## --------------------------------------------------------------------------- -http\://activemq.org/config/1.0=activemq.xsd -http\://activemq.org/config/1.0/1.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.0.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.1.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.3.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.3.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.3.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.4.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.4.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.4.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.5.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.5.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.6.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.9.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.9.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.10.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.10.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.11.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.11.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.11.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.12.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.12.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.12.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.5.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.5.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.5.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.6.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.7.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.8.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.9.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.10.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.11.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.12.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.13.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.14.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.15.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.5.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.6.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.18.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-6.0.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-6.0.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-6.1.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-6.1.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-6.1.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-6.2.0.xsd=activemq.xsd - -http\://camel.apache.org/schema/spring/camel-spring.xsd=camel-spring.xsd - -http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd -http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd -http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd -http\://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd -http\://www.springframework.org/schema/beans/spring-beans-3.2.xsd=org/springframework/beans/factory/xml/spring-beans-3.2.xsd -http\://www.springframework.org/schema/beans/spring-beans-4.0.xsd=org/springframework/beans/factory/xml/spring-beans-4.0.xsd -http\://www.springframework.org/schema/beans/spring-beans-4.1.xsd=org/springframework/beans/factory/xml/spring-beans-4.1.xsd -http\://www.springframework.org/schema/beans/spring-beans-4.2.xsd=org/springframework/beans/factory/xml/spring-beans-4.2.xsd -http\://www.springframework.org/schema/beans/spring-beans-4.3.xsd=org/springframework/beans/factory/xml/spring-beans-4.3.xsd -http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans.xsd -http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd -http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd -http\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd -http\://www.springframework.org/schema/tool/spring-tool-3.1.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd -http\://www.springframework.org/schema/tool/spring-tool-3.2.xsd=org/springframework/beans/factory/xml/spring-tool-3.2.xsd -http\://www.springframework.org/schema/tool/spring-tool-4.0.xsd=org/springframework/beans/factory/xml/spring-tool-4.0.xsd -http\://www.springframework.org/schema/tool/spring-tool-4.1.xsd=org/springframework/beans/factory/xml/spring-tool-4.1.xsd -http\://www.springframework.org/schema/tool/spring-tool-4.2.xsd=org/springframework/beans/factory/xml/spring-tool-4.2.xsd -http\://www.springframework.org/schema/tool/spring-tool-4.3.xsd=org/springframework/beans/factory/xml/spring-tool-4.3.xsd -http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool.xsd -http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd -http\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd -http\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd -http\://www.springframework.org/schema/util/spring-util-3.1.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd -http\://www.springframework.org/schema/util/spring-util-3.2.xsd=org/springframework/beans/factory/xml/spring-util-3.2.xsd -http\://www.springframework.org/schema/util/spring-util-4.0.xsd=org/springframework/beans/factory/xml/spring-util-4.0.xsd -http\://www.springframework.org/schema/util/spring-util-4.1.xsd=org/springframework/beans/factory/xml/spring-util-4.1.xsd -http\://www.springframework.org/schema/util/spring-util-4.2.xsd=org/springframework/beans/factory/xml/spring-util-4.2.xsd -http\://www.springframework.org/schema/util/spring-util-4.3.xsd=org/springframework/beans/factory/xml/spring-util-4.3.xsd -http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util.xsd diff --git a/activemq-ra/src/main/java/org/apache/activemq/ra/ActiveMQActivationSpec.java b/activemq-ra/src/main/java/org/apache/activemq/ra/ActiveMQActivationSpec.java index ad6bcabd6ce..d7ec3a413a3 100644 --- a/activemq-ra/src/main/java/org/apache/activemq/ra/ActiveMQActivationSpec.java +++ b/activemq-ra/src/main/java/org/apache/activemq/ra/ActiveMQActivationSpec.java @@ -132,12 +132,12 @@ public void validate() throws InvalidPropertyException { e.printStackTrace(); } - if (propsNotSet.size() > 0) { - StringBuffer b = new StringBuffer(); + if (!propsNotSet.isEmpty()) { + StringBuilder b = new StringBuilder(); b.append("Invalid settings:"); - for (Iterator iter = errorMessages.iterator(); iter.hasNext();) { + for (String errorMessage : errorMessages) { b.append(" "); - b.append(iter.next()); + b.append(errorMessage); } InvalidPropertyException e = new InvalidPropertyException(b.toString()); final PropertyDescriptor[] descriptors = propsNotSet.toArray(new PropertyDescriptor[propsNotSet.size()]); diff --git a/activemq-rar/pom.xml b/activemq-rar/pom.xml index 68a03e447b6..b429f9c10a9 100644 --- a/activemq-rar/pom.xml +++ b/activemq-rar/pom.xml @@ -73,10 +73,6 @@ geronimo geronimo-j2ee - - axion - axion - ${project.groupId} activemq-jaas @@ -109,10 +105,6 @@ junit junit - - jakarta-regexp - jakarta-regexp - org.jmdns jmdns @@ -145,10 +137,6 @@ commons-collections commons-collections - - commons-primitives - commons-primitives - org.apache.commons commons-pool2 @@ -195,10 +183,6 @@ geronimo geronimo-j2ee - - axion - axion - ${project.groupId} activemq-jaas @@ -239,10 +223,6 @@ junit junit - - regexp - regexp - javax.jmdns jmdns @@ -275,10 +255,6 @@ commons-collections commons-collections - - commons-primitives - commons-primitives - org.apache.commons commons-pool2 diff --git a/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java index e0d3d80ccc2..b7342f417de 100644 --- a/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java +++ b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java @@ -228,8 +228,9 @@ private void loadPropertiesPlaceHolderSupport(Document doc) { private Schema getSchema() throws SAXException, IOException { if (schema == null) { - SchemaFactory schemaFactory = SchemaFactory.newInstance( - XMLConstants.W3C_XML_SCHEMA_NS_URI); + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + schemaFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + schemaFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); ArrayList schemas = new ArrayList(); schemas.add(new StreamSource(getClass().getResource("/activemq.xsd").toExternalForm())); diff --git a/activemq-spring/src/main/resources/META-INF/spring.schemas b/activemq-spring/src/main/resources/META-INF/spring.schemas index 7348766b02d..f9eede793f0 100644 --- a/activemq-spring/src/main/resources/META-INF/spring.schemas +++ b/activemq-spring/src/main/resources/META-INF/spring.schemas @@ -14,76 +14,8 @@ ## See the License for the specific language governing permissions and ## limitations under the License. ## --------------------------------------------------------------------------- -http\://activemq.org/config/1.0=activemq.xsd -http\://activemq.org/config/1.0/1.0.xsd=activemq.xsd http\://activemq.apache.org/schema/core=activemq.xsd http\://activemq.apache.org/schema/core/activemq-core.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.0.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.1.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.3.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.3.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.3.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.4.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.4.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.4.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.5.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.5.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.6.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.9.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.9.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.10.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.10.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.11.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.11.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.11.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.12.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.12.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.12.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.13.5.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.14.5.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.5.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.6.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.7.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.8.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.9.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.10.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.11.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.12.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.13.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.14.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.15.15.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.5.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.16.6.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.1.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.2.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.3.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.17.4.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.18.0.xsd=activemq.xsd -http\://activemq.apache.org/schema/core/activemq-core-5.18.1.xsd=activemq.xsd http\://activemq.apache.org/schema/core/activemq-core-6.0.0.xsd=activemq.xsd http\://activemq.apache.org/schema/core/activemq-core-6.0.1.xsd=activemq.xsd http\://activemq.apache.org/schema/core/activemq-core-6.1.0.xsd=activemq.xsd diff --git a/activemq-tooling/activemq-memtest-maven-plugin/src/main/java/org/apache/activemq/tool/ReportGenerator.java b/activemq-tooling/activemq-memtest-maven-plugin/src/main/java/org/apache/activemq/tool/ReportGenerator.java index 984cb6eee38..a02993c9379 100644 --- a/activemq-tooling/activemq-memtest-maven-plugin/src/main/java/org/apache/activemq/tool/ReportGenerator.java +++ b/activemq-tooling/activemq-memtest-maven-plugin/src/main/java/org/apache/activemq/tool/ReportGenerator.java @@ -114,14 +114,8 @@ protected void endTestResult() { } protected void writeWithIndent(int indent, String result) { - StringBuffer buffer = new StringBuffer(); - - for (int i = 0; i < indent; ++i) { - buffer.append(" "); - } - - buffer.append(result); - writer.println(buffer.toString()); + String buffer = " ".repeat(Math.max(0, indent)) + result; + writer.println(buffer); } public PrintWriter getWriter() { diff --git a/activemq-tooling/activemq-perf-maven-plugin/src/main/java/org/apache/activemq/tool/AbstractJmsClient.java b/activemq-tooling/activemq-perf-maven-plugin/src/main/java/org/apache/activemq/tool/AbstractJmsClient.java index 0fbaaa7ba3c..a9d80ad4867 100644 --- a/activemq-tooling/activemq-perf-maven-plugin/src/main/java/org/apache/activemq/tool/AbstractJmsClient.java +++ b/activemq-tooling/activemq-perf-maven-plugin/src/main/java/org/apache/activemq/tool/AbstractJmsClient.java @@ -90,7 +90,7 @@ public Connection getConnection() throws JMSException { if (jmsConnection == null) { jmsConnection = factory.createConnection(); jmsConnection.setClientID(getClientName()); - LOG.info("Creating JMS Connection: Provider=" + getClient().getJmsProvider() + ", JMS Spec=" + getClient().getJmsVersion()); + LOG.info("Creating JMS Connection: Provider={}, JMS Spec={}", getClient().getJmsProvider(), getClient().getJmsVersion()); } return jmsConnection; } @@ -142,7 +142,7 @@ public Destination[] createDestinations(int destCount) throws JMSException { } private String join(String[] stings, String separator) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (int i = 0; i < stings.length; i++) { if (i > 0) { sb.append(separator); @@ -174,21 +174,21 @@ protected Destination createCompositeDestination(String destName, int destCount) protected Destination createCompositeDestination(byte destinationType, String destName, int destCount) throws JMSException { String simpleName = getSimpleName(destName); - String compDestName = ""; + StringBuilder compDestName = new StringBuilder(destCount * (simpleName.length() + 4)); for (int i = 0; i < destCount; i++) { if (i > 0) { - compDestName += ","; + compDestName.append(","); } - compDestName += withDestinationSuffix(simpleName, i, destCount); + compDestName.append(withDestinationSuffix(simpleName, i, destCount)); } LOG.info("Creating composite destination: {}", compDestName); Destination destination; Session session = getSession(); if (destinationType == ActiveMQDestination.TOPIC_TYPE) { - destination = session.createTopic(compDestName); + destination = session.createTopic(compDestName.toString()); } else if (destinationType == ActiveMQDestination.QUEUE_TYPE) { - destination = session.createQueue(compDestName); + destination = session.createQueue(compDestName.toString()); } else { throw new UnsupportedOperationException( "Cannot create composite destinations using temporary queues or topics."); diff --git a/activemq-tooling/activemq-perf-maven-plugin/src/main/java/org/apache/activemq/tool/JmsProducerClient.java b/activemq-tooling/activemq-perf-maven-plugin/src/main/java/org/apache/activemq/tool/JmsProducerClient.java index 4f6a89bd5fd..7003aa67ab3 100644 --- a/activemq-tooling/activemq-perf-maven-plugin/src/main/java/org/apache/activemq/tool/JmsProducerClient.java +++ b/activemq-tooling/activemq-perf-maven-plugin/src/main/java/org/apache/activemq/tool/JmsProducerClient.java @@ -91,18 +91,9 @@ public void sendCountBasedMessages(long messageCount) throws JMSException { try { getConnection().start(); if (client.getMsgFileName() != null) { - LOG.info("Starting to publish " + - messageCount + - " messages from file " + - client.getMsgFileName() - ); + LOG.info("Starting to publish {} messages from file {}", messageCount, client.getMsgFileName()); } else { - LOG.info("Starting to publish " + - messageCount + - " messages of size " + - client.getMessageSize() + - " byte(s)." - ); + LOG.info("Starting to publish {} messages of size {} byte(s).", messageCount, client.getMessageSize()); } // Send one type of message only, avoiding the creation of different messages on sending @@ -180,17 +171,9 @@ public void sendTimeBasedMessages(long duration) throws JMSException { try { getConnection().start(); if (client.getMsgFileName() != null) { - LOG.info("Starting to publish messages from file " + - client.getMsgFileName() + - " for " + - duration + - " ms"); + LOG.info("Starting to publish messages from file {} for {} ms", client.getMsgFileName(), duration); } else { - LOG.info("Starting to publish " + - client.getMessageSize() + - " byte(s) messages for " + - duration + - " ms"); + LOG.info("Starting to publish {} byte(s) messages for {} ms", client.getMessageSize(), duration); } // Send one type of message only, avoiding the creation of different messages on sending if (!client.isCreateNewMsg()) { @@ -268,10 +251,10 @@ public MessageProducer createJmsProducer() throws JMSException { public MessageProducer createJmsProducer(Destination dest) throws JMSException { jmsProducer = getSession().createProducer(dest); if (client.getDeliveryMode().equalsIgnoreCase(JmsProducerProperties.DELIVERY_MODE_PERSISTENT)) { - LOG.info("Creating producer to: " + dest.toString() + " with persistent delivery."); + LOG.info("Creating producer to: {} with persistent delivery.", dest.toString()); jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT); } else if (client.getDeliveryMode().equalsIgnoreCase(JmsProducerProperties.DELIVERY_MODE_NON_PERSISTENT)) { - LOG.info("Creating producer to: " + dest.toString() + " with non-persistent delivery."); + LOG.info("Creating producer to: {} with non-persistent delivery.", dest.toString()); jmsProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); } else { LOG.warn("Unknown deliveryMode value. Defaulting to non-persistent."); @@ -350,7 +333,7 @@ protected String buildText(String text, int size) { protected void sleep() { if (client.getSendDelay() > 0) { try { - LOG.trace("Sleeping for " + client.getSendDelay() + " milliseconds"); + LOG.trace("Sleeping for {} milliseconds", client.getSendDelay()); Thread.sleep(client.getSendDelay()); } catch (java.lang.InterruptedException ex) { LOG.warn(ex.getMessage()); @@ -376,7 +359,7 @@ protected TextMessage loadJmsMessage() throws JMSException { } // try to load file - StringBuffer payload = new StringBuffer(); + StringBuilder payload = new StringBuilder(); try(FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr)) { String tmp = null; diff --git a/activemq-unit-tests/pom.xml b/activemq-unit-tests/pom.xml index b1f8ee4678c..13b53fe40f4 100644 --- a/activemq-unit-tests/pom.xml +++ b/activemq-unit-tests/pom.xml @@ -216,21 +216,6 @@ commons-collections test
- - commons-primitives - commons-primitives - test - - - axion - axion - test - - - jakarta-regexp - jakarta-regexp - test - org.apache.commons commons-dbcp2 @@ -1160,5 +1145,33 @@ + + jdk21-plus + + [21,) + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-jdk21-test-source + generate-test-sources + + add-test-source + + + + src/test/java21 + + + + + + + + diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/jmx/BrokerViewTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/jmx/BrokerViewTest.java new file mode 100644 index 00000000000..c3b0f720252 --- /dev/null +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/jmx/BrokerViewTest.java @@ -0,0 +1,90 @@ +/** + * 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.broker.jmx; + +import jakarta.jms.*; +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.broker.BrokerRegistry; +import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.util.Wait; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + + +public class BrokerViewTest { + @Test(timeout=120000) + public void testBrokerViewRetrieveQueuesAndTopicsCount() throws Exception { + BrokerService brokerService = new BrokerService(); + brokerService.setPersistent(false); + + // Create and configure ManagementContext with suppressed destinations + ManagementContext managementContext = new ManagementContext(); + managementContext.setCreateConnector(false); + managementContext.setSuppressMBean("endpoint=dynamicProducer,destinationName=suppressedQueue,destinationName=suppressedTopic"); + brokerService.setManagementContext(managementContext); + brokerService.start(); + + ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(BrokerRegistry.getInstance().findFirst().getVmConnectorURI()); + Connection producerConnection = factory.createConnection(); + producerConnection.start(); + // Create non-suppressed queue + Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = producerSession.createQueue("testQueue"); + MessageProducer producer = producerSession.createProducer(queue); + producer.send(producerSession.createTextMessage("testMessage")); + // Create suppressed queue + Queue suppressedQueue = producerSession.createQueue("suppressedQueue"); + MessageProducer suppressedProducer = producerSession.createProducer(suppressedQueue); + suppressedProducer.send(producerSession.createTextMessage("testMessage")); + // Create temporary queue + Session tempProducerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue tempQueue = tempProducerSession.createTemporaryQueue(); + MessageProducer tempProducer = tempProducerSession.createProducer(tempQueue); + tempProducer.send(tempProducerSession.createTextMessage("testMessage")); + Session tempProducerSession2 = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue tempQueue2 = tempProducerSession2.createTemporaryQueue(); + MessageProducer tempProducer2 = tempProducerSession2.createProducer(tempQueue2); + tempProducer2.send(tempProducerSession2.createTextMessage("testMessage")); + // Create non-suppressed topic + Session topicProducerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = topicProducerSession.createTopic("testTopic"); + MessageProducer topicProducer = topicProducerSession.createProducer(topic); + topicProducer.send(topicProducerSession.createTextMessage("testMessage")); + // Create suppressed topic + Session suppressedTopicProducerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic suppressedTopic = suppressedTopicProducerSession.createTopic("suppressedTopic"); + MessageProducer suppressedTopicProducer = topicProducerSession.createProducer(suppressedTopic); + topicProducer.send(suppressedTopicProducerSession.createTextMessage("testMessage")); + // Create temporary topic + Session tempTopicProducerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic tempTopic = tempTopicProducerSession.createTemporaryTopic(); + MessageProducer tempTopicProducer = tempTopicProducerSession.createProducer(tempTopic); + tempTopicProducer.send(tempTopicProducerSession.createTextMessage("testMessage")); + + assertTrue(Wait.waitFor(() -> (brokerService.getAdminView()) != null)); + final BrokerView view = brokerService.getAdminView(); + assertEquals(15, view.getTotalTopicsCount()); + assertEquals(14, view.getTotalManagedTopicsCount()); + assertEquals(1, view.getTotalTemporaryTopicsCount()); + assertEquals(1, view.getQueues().length); + assertEquals(2, view.getTotalQueuesCount()); + assertEquals(1, view.getTotalManagedQueuesCount()); + assertEquals(view.getTotalTemporaryQueuesCount(), 2); + } +} diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/region/cursors/StoreBasedCursorTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/region/cursors/StoreBasedCursorTest.java index e7d8f6b8962..916459827dd 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/region/cursors/StoreBasedCursorTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/region/cursors/StoreBasedCursorTest.java @@ -102,8 +102,9 @@ protected void configureBroker(long memoryLimit, long systemLimit) throws Except } protected String createMessageText(int index) { - StringBuffer buffer = new StringBuffer(messageSize); - buffer.append("Message: " + index + " sent at: " + new Date()); + StringBuilder buffer = new StringBuilder(messageSize); + buffer.append("Message: ").append(index) + .append(" sent at: ").append(new Date()); if (buffer.length() > messageSize) { return buffer.substring(0, messageSize); } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/ReduceMemoryFootprintTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/ReduceMemoryFootprintTest.java index 0f09a6f160b..3d5ba8b27b5 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/ReduceMemoryFootprintTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/ReduceMemoryFootprintTest.java @@ -140,12 +140,7 @@ public void testPropertyLostScheduled() throws Exception { } private String createMessageText() { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < 50; i++) { - buffer.append("1234567890"); - } - - return buffer.toString(); + return "1234567890".repeat(50); } private Message consumeMessages(Connection connection) { diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ3352Test.java b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ3352Test.java index 132fca9f0c6..8863433965c 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ3352Test.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ3352Test.java @@ -59,17 +59,15 @@ public void verifyEnqueueLargeNumWithStateTracker() throws Exception { producer.setDisableMessageID(true); producer.setDisableMessageTimestamp(true); - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); for (int i=0;i<1024;i++) { - buffer.append(String.valueOf(Math.random())); + buffer.append(Math.random()); } String payload = buffer.toString(); for (int i=0; i<10000; i++) { - StringBuffer buff = new StringBuffer("x"); - buff.append(payload); - producer.send(session.createTextMessage(buff.toString())); + producer.send(session.createTextMessage("x" + payload)); } } } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ3436Test.java b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ3436Test.java index 4d21417e83a..622d5ab2874 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ3436Test.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ3436Test.java @@ -131,12 +131,12 @@ public void testPriorityWhenConsumerCreatedBeforeProduction() throws Exception { producer.close(); // *************************************************** - // If we create the consumer here instead of above, the + // If we create the consumer here instead of above, // the messages will be consumed in priority order // *************************************************** //consumer = (ActiveMQMessageConsumer) consumerSession.createConsumer(dest); - // Consume all of the messages we produce using a listener. + // Consume all the messages we produce using a listener. // Don't exit until we get all the messages. final CountDownLatch latch = new CountDownLatch(messageCount); final StringBuffer failureMessage = new StringBuffer(); @@ -150,11 +150,11 @@ public void onMessage(Message msg) { try { int currentPriority = msg.getJMSPriority(); - LOG.debug(currentPriority + "<=" + lowestPrioritySeen); + LOG.debug("{}<={}", currentPriority, lowestPrioritySeen); // Ignore the first message priority since it is prefetched // and is out of order by design - if (firstMessage == true) { + if (firstMessage) { firstMessage = false; LOG.debug("Ignoring first message since it was prefetched"); @@ -167,9 +167,12 @@ public void onMessage(Message msg) { lowestPrioritySeen = currentPriority; } if (lowestPrioritySeen < currentPriority) { - failureMessage.append("Incorrect priority seen (Lowest Priority = " + lowestPrioritySeen - + " Current Priority = " + currentPriority + ")" - + System.getProperty("line.separator")); + failureMessage.append("Incorrect priority seen (Lowest Priority = ") + .append(lowestPrioritySeen) + .append(" Current Priority = ") + .append(currentPriority) + .append(")") + .append(System.lineSeparator()); } } @@ -177,7 +180,7 @@ public void onMessage(Message msg) { e.printStackTrace(); } finally { latch.countDown(); - LOG.debug("Messages remaining = " + latch.getCount()); + LOG.debug("Messages remaining = {}", latch.getCount()); } } }); @@ -196,7 +199,7 @@ public void onMessage(Message msg) { consumerConnection.close(); // Report the failure if found - if (failureMessage.length() > 0) { + if (!failureMessage.isEmpty()) { Assert.fail(failureMessage.toString()); } } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4368Test.java b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4368Test.java index a20b9a5d1b3..9afcd5d247c 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4368Test.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4368Test.java @@ -102,7 +102,7 @@ abstract class Client implements Runnable { } public void start() { - LOG.info("Starting: " + name); + LOG.info("Starting: {}", name); new Thread(this, name).start(); } @@ -117,6 +117,7 @@ public void stop() throws InterruptedException { connection.close(); doneLatch.await(); } catch (Exception e) { + LOG.warn("Exception occurred", e); } } } @@ -133,11 +134,12 @@ public void run() { try { connection.close(); } catch (JMSException ignore) { + LOG.warn("exception ignored", ignore); } - LOG.info("Stopped: " + name); + LOG.info("Stopped: {}", name); } } catch (Exception e) { - e.printStackTrace(); + LOG.warn("exception occurred", e); done.set(true); } finally { doneLatch.countDown(); @@ -162,11 +164,11 @@ class ProducingClient extends Client { } private String createMessage() { - StringBuffer stringBuffer = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (long i = 0; i < 1000000; i++) { - stringBuffer.append("1234567890"); + sb.append("1234567890"); } - return stringBuffer.toString(); + return sb.toString(); } @Override @@ -178,7 +180,7 @@ protected void work() throws Exception { producer.send(session.createTextMessage(data)); long i = size.incrementAndGet(); if ((i % 1000) == 0) { - LOG.info("produced " + i + "."); + LOG.info("produced {}.", i); } } } @@ -234,7 +236,7 @@ public boolean isSatisified() throws Exception { } }); long size = listener1.size.get(); - LOG.info("Listener 1: consumed: " + (size - lastSize.get())); + LOG.info("Listener 1: consumed: {}", size - lastSize.get()); assertTrue("No messages received on iteration: " + i, size > lastSize.get()); lastSize.set(size); } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4504Test.java b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4504Test.java index 864fa3a6abd..8e5af597414 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4504Test.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4504Test.java @@ -53,15 +53,15 @@ public void testCompositeDestConsumer() throws Exception { final int numDests = 20; final int numMessages = 200; - StringBuffer stringBuffer = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (int i=0; i adapters = new ArrayList(); if (compositeMatch) { - StringBuffer compositeDestBuf = new StringBuffer(); + StringBuilder compositeDestBuf = new StringBuilder(DESTS.length * 3); for (int i=1; i<=DESTS.length;i++) { for (int j=0;j 10000; i++) { - stringBuffer.append("0123456789"); + sb.append("0123456789"); } - return stringBuffer.toString(); + return sb.toString(); } - private void consume(String queue, int messageCount) throws Exception { Connection con = connectionFactory.createConnection(); diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/JmsTimeoutTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/JmsTimeoutTest.java index cc8d2f244e3..778ae2b81ed 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/JmsTimeoutTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/JmsTimeoutTest.java @@ -146,7 +146,7 @@ protected ConnectionFactory createConnectionFactory() throws Exception { } protected String createMessageText() { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); buffer.append(""); for (int i = buffer.length(); i < messageSize; i++) { buffer.append('X'); diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/PfcTimeoutTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/PfcTimeoutTest.java index 556b5d298eb..0f670c845e2 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/PfcTimeoutTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/PfcTimeoutTest.java @@ -135,8 +135,8 @@ public void testTransactedSendWithTimeoutRollbackUsage() throws Exception { long memoryUsage = queueView.getCursorMemoryUsage(); - LOG.info("queueSize after test = " + queueSize); - LOG.info("memoryUsage after test = " + memoryUsage); + LOG.info("queueSize after test = {}", queueSize); + LOG.info("memoryUsage after test = {}", memoryUsage); assertEquals("queue size after test ", 0, queueSize); assertEquals("memory size after test ", 0, memoryUsage); @@ -174,13 +174,13 @@ private int sendMessages(final BrokerService broker, final CountDownLatch gotTim } - LOG.info(" Finished after producing : " + numberOfMessageSent); + LOG.info(" Finished after producing : {}", numberOfMessageSent); return numberOfMessageSent; } catch (Exception ex) { LOG.info("Exception received producing ", ex); - LOG.info("finishing after exception :" + numberOfMessageSent); + LOG.info("finishing after exception :{}", numberOfMessageSent); LOG.info("rolling back current transaction "); gotTimeoutException.countDown(); @@ -196,13 +196,7 @@ private int sendMessages(final BrokerService broker, final CountDownLatch gotTim } private String createTextMessage(int size) { - StringBuffer buffer = new StringBuffer(); - - for (int i = 0; i < size; i++) { - buffer.append("9"); - } - - return buffer.toString(); + return "9".repeat(Math.max(0, size)); } @@ -233,13 +227,13 @@ private int consumeMessages(BrokerService broker, int messageCount) throws Excep numberOfMessageConsumed++; } - LOG.info(" Finished after consuming : " + numberOfMessageConsumed); + LOG.info(" Finished after consuming : {}", numberOfMessageConsumed); return numberOfMessageConsumed; } catch (Exception ex) { LOG.info("Exception received producing ", ex); - LOG.info("finishing after exception :" + numberOfMessageConsumed); + LOG.info("finishing after exception :{}", numberOfMessageConsumed); return numberOfMessageConsumed; diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/amq1095/MessageSelectorTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/amq1095/MessageSelectorTest.java index 49c76d8d167..33f09fe7341 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/amq1095/MessageSelectorTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/amq1095/MessageSelectorTest.java @@ -153,7 +153,7 @@ private void runMessageSelectorTest(final boolean isDurableSubscriber) msg1 = (TextMessage) consumer1.receive(RECEIVE_TIMEOUT); if (msg1 != null) { - final StringBuffer msg = new StringBuffer("The consumer read a message that was left over from a former ActiveMQ broker run."); + final StringBuilder msg = new StringBuilder("The consumer read a message that was left over from a former ActiveMQ broker run."); propertyValue = msg1.getIntProperty(PROPERTY_CONSUMER); contents = msg1.getText(); if (propertyValue != 1) // Is the property value as expected? @@ -167,7 +167,7 @@ private void runMessageSelectorTest(final boolean isDurableSubscriber) msg2 = (TextMessage) consumer2.receive(RECEIVE_TIMEOUT); if (msg2 != null) { - final StringBuffer msg = new StringBuffer("The consumer read a message that was left over from a former ActiveMQ broker run."); + final StringBuilder msg = new StringBuilder("The consumer read a message that was left over from a former ActiveMQ broker run."); propertyValue = msg2.getIntProperty(PROPERTY_CONSUMER); contents = msg2.getText(); if (propertyValue != 2) // Is the property value as expected? diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/embedded/ThreadExplorer.java b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/embedded/ThreadExplorer.java index cc6cbf37453..1640d930f55 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/embedded/ThreadExplorer.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/bugs/embedded/ThreadExplorer.java @@ -30,7 +30,7 @@ public static Thread[] listThreads() { int nThreads = Thread.activeCount(); - Thread ret[] = new Thread[nThreads]; + Thread[] ret = new Thread[nThreads]; Thread.enumerate(ret); @@ -70,7 +70,7 @@ public static int kill(String threadName, boolean isStarredExp, String motivatio String me = "ThreadExplorer.kill: "; if (logger.isDebugEnabled()) { - logger.debug("Entering " + me + " with " + threadName + " isStarred: " + isStarredExp); + logger.debug("Entering {} with {} isStarred: {}", me, threadName, isStarredExp); } int ret = 0; Pattern mypattern = null; @@ -101,7 +101,7 @@ public static int kill(String threadName, boolean isStarredExp, String motivatio if (matches && (Thread.currentThread() != thread) && !thread.getName().equals("main")) { if (logger.isInfoEnabled()) - logger.info("Killing thread named [" + thread.getName() + "]"); // , removing its uncaught + logger.info("Killing thread named [{}]", thread.getName()); // , removing its uncaught // exception handler to // avoid ThreadDeath // exception tracing @@ -128,22 +128,24 @@ public static int kill(String threadName, boolean isStarredExp, String motivatio public static String show(String title) { - StringBuffer out = new StringBuffer(); + StringBuilder out = new StringBuilder(); Thread[] threadArray = ThreadExplorer.listThreads(); - out.append(title + "\n"); + out.append(title).append("\n"); for (int i = 0; i < threadArray.length; i++) { Thread thread = threadArray[i]; if (thread != null) { - out.append("* [" + thread.getName() + "] " + (thread.isDaemon() ? "(Daemon)" : "") - + " Group: " + (thread.getThreadGroup() != null ? thread.getThreadGroup().getName() : "") + "\n"); + out.append("* [").append(thread.getName()).append("] ") + .append(thread.isDaemon() ? "(Daemon)" : "").append(" Group: ") + .append(thread.getThreadGroup() != null ? thread.getThreadGroup().getName() : "") + .append("\n"); } else { - out.append("* ThreadDeath: " + thread + "\n"); + out.append("* ThreadDeath: ").append(thread).append("\n"); } } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/network/NetworkLoadTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/network/NetworkLoadTest.java index 81bc03166af..4d9b9e09f2f 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/network/NetworkLoadTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/network/NetworkLoadTest.java @@ -57,7 +57,7 @@ * * If the network bridges gets stuck at any point subsequent queues will not get messages. This test * samples the production and consumption stats every second and if the flow of messages - * get stuck then this tast fails. The test monitors the flow of messages for 1 min. + * get stuck then this test fails. The test monitors the flow of messages for 1 min. * * @author chirino */ @@ -126,7 +126,7 @@ protected void setUp() throws Exception { groupId = "network-load-test-"+System.currentTimeMillis(); brokers = new BrokerService[BROKER_COUNT]; for (int i = 0; i < brokers.length; i++) { - LOG.info("Starting broker: "+i); + LOG.info("Starting broker: {}", i); brokers[i] = createBroker(i); brokers[i].start(); } @@ -137,7 +137,7 @@ protected void setUp() throws Exception { forwardingClients = new ForwardingClient[BROKER_COUNT-1]; for (int i = 0; i < forwardingClients.length; i++) { - LOG.info("Starting fowarding client "+i); + LOG.info("Starting forwarding client {}", i); forwardingClients[i] = new ForwardingClient(i, i+1); forwardingClients[i].start(); } @@ -145,11 +145,11 @@ protected void setUp() throws Exception { protected void tearDown() throws Exception { for (int i = 0; i < forwardingClients.length; i++) { - LOG.info("Stoping fowarding client "+i); + LOG.info("Stoping forwarding client {}", i); forwardingClients[i].close(); } for (int i = 0; i < brokers.length; i++) { - LOG.info("Stoping broker "+i); + LOG.info("Stoping broker {}", i); brokers[i].stop(); } } @@ -232,7 +232,7 @@ public void testRequestReply() throws Exception { final AtomicLong receivedMessages = new AtomicLong(); final AtomicBoolean done = new AtomicBoolean(); - // Setup the consumer.. + // Set up the consumer... consumer.setMessageListener(new MessageListener() { public void onMessage(Message msg) { ActiveMQTextMessage m = (ActiveMQTextMessage) msg; @@ -271,8 +271,8 @@ public void run() { } private String createMessageText(int index) { - StringBuffer buffer = new StringBuffer(MESSAGE_SIZE); - buffer.append(index + " on " + new Date() + " ..."); + StringBuilder buffer = new StringBuilder(MESSAGE_SIZE); + buffer.append(index).append(" on ").append(new Date()).append(" ..."); if (buffer.length() > MESSAGE_SIZE) { return buffer.substring(0, MESSAGE_SIZE); } @@ -287,7 +287,7 @@ private String createMessageText(int index) { // Give the forwarding clients a chance to get going and fill the down - // stream broker queues.. + // stream broker queues... Thread.sleep(BROKER_COUNT*200); for (int i = 0; i < SAMPLES; i++) { @@ -305,9 +305,9 @@ private String createMessageText(int index) { long r = receivedMessages.get(); long p = producedMessages.get(); - LOG.info("published: " + p + " msgs at " + (p * 1000f / (end - start)) + " msgs/sec, " + "consumed: " + r + " msgs at " + (r * 1000f / (end - start)) + " msgs/sec"); + LOG.info("published: {} msgs at {} msgs/sec, consumed: {} msgs at {} msgs/sec", p, p * 1000f / (end - start), r, r * 1000f / (end - start)); - StringBuffer fwdingmsg = new StringBuffer(500); + StringBuilder fwdingmsg = new StringBuilder(forwardingClients.length * 16); fwdingmsg.append(" forwarding counters: "); for (int j = 0; j < forwardingClients.length; j++) { if( j!= 0 ) { @@ -317,9 +317,9 @@ private String createMessageText(int index) { } LOG.info(fwdingmsg.toString()); - // The test is just checking to make sure thaat the producer and consumer does not hang + // The test is just checking to make sure that the producer and consumer does not hang // due to the network hops take to route the message form the producer to the consumer. - assertTrue("Recieved some messages since last sample", r>0); + assertTrue("Received some messages since last sample", r>0); assertTrue("Produced some messages since last sample", p>0); } @@ -332,5 +332,4 @@ private String createMessageText(int index) { } - } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/store/jdbc/JDBCIOExceptionHandlerMockeryTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/store/jdbc/JDBCIOExceptionHandlerMockeryTest.java index 1e9a209a24d..57e84aa4d48 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/store/jdbc/JDBCIOExceptionHandlerMockeryTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/store/jdbc/JDBCIOExceptionHandlerMockeryTest.java @@ -16,6 +16,15 @@ */ package org.apache.activemq.store.jdbc; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import java.io.IOException; import java.util.HashMap; import org.apache.activemq.broker.BrokerService; @@ -23,74 +32,34 @@ import org.apache.activemq.broker.SuppressReplyException; import org.apache.activemq.util.LeaseLockerIOExceptionHandler; import org.apache.activemq.util.ServiceStopper; -import org.apache.activemq.util.Wait; -import org.jmock.Expectations; -import org.jmock.Mockery; -import org.jmock.States; -import org.jmock.lib.legacy.ClassImposteriser; -import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -@Ignore // AMQ-9239 FIXME: mock / byte-buddy opens public class JDBCIOExceptionHandlerMockeryTest { - private static final Logger LOG = LoggerFactory.getLogger(JDBCIOExceptionHandlerMockeryTest.class); - private HashMap exceptions = new HashMap(); + private final HashMap exceptions = new HashMap(); @Test public void testShutdownWithoutTransportRestart() throws Exception { - - Mockery context = new Mockery() {{ - setImposteriser(ClassImposteriser.INSTANCE); - }}; - - Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread t, Throwable e) { - LOG.error("unexpected exception {} on thread {}", e, t); - exceptions.put(t, e); - } + Thread.setDefaultUncaughtExceptionHandler((t, e) -> { + LOG.error("unexpected exception {} on thread {}", e, t); + exceptions.put(t, e); }); - final BrokerService brokerService = context.mock(BrokerService.class); - final JDBCPersistenceAdapter jdbcPersistenceAdapter = context.mock(JDBCPersistenceAdapter.class); - final Locker locker = context.mock(Locker.class); - - final States jdbcConn = context.states("jdbc").startsAs("down"); - final States broker = context.states("broker").startsAs("started"); + // Create mocks + BrokerService brokerService = mock(BrokerService.class); + JDBCPersistenceAdapter jdbcPersistenceAdapter = mock(JDBCPersistenceAdapter.class); + Locker locker = mock(Locker.class); - // simulate jdbc up between hasLock and checkpoint, so hasLock fails to verify - context.checking(new Expectations() {{ - allowing(brokerService).isStarted(); - will(returnValue(true)); - allowing(brokerService).isRestartAllowed(); - will(returnValue(false)); - allowing(brokerService).setSystemExitOnShutdown(with(false)); - allowing(brokerService).stopAllConnectors(with(any(ServiceStopper.class))); - allowing(brokerService).getPersistenceAdapter(); - will(returnValue(jdbcPersistenceAdapter)); - allowing(jdbcPersistenceAdapter).allowIOResumption(); - allowing(jdbcPersistenceAdapter).getLocker(); - will(returnValue(locker)); - allowing(locker).keepAlive(); - when(jdbcConn.is("down")); - will(returnValue(true)); - allowing(locker).keepAlive(); - when(jdbcConn.is("up")); - will(returnValue(false)); - - allowing(jdbcPersistenceAdapter).checkpoint(with(true)); - then(jdbcConn.is("up")); - allowing(brokerService).stop(); - then(broker.is("stopped")); - - }}); + // Setup mock behaviors + when(brokerService.isStarted()).thenReturn(true); + when(brokerService.isRestartAllowed()).thenReturn(false); + when(brokerService.getPersistenceAdapter()).thenReturn(jdbcPersistenceAdapter); + doNothing().when(brokerService).setSystemExitOnShutdown(false); + doNothing().when(brokerService).stopAllConnectors(any(ServiceStopper.class)); + when(jdbcPersistenceAdapter.getLocker()).thenReturn(locker); + when(locker.keepAlive()).thenReturn(true); LeaseLockerIOExceptionHandler underTest = new LeaseLockerIOExceptionHandler(); underTest.setBrokerService(brokerService); @@ -101,15 +70,7 @@ public void uncaughtException(Thread t, Throwable e) { } catch (SuppressReplyException expected) { } - assertTrue("broker stopped state triggered", Wait.waitFor(new Wait.Condition() { - @Override - public boolean isSatisified() throws Exception { - LOG.info("broker state {}", broker); - return broker.is("stopped").isActive(); - } - })); - context.assertIsSatisfied(); - + verify(brokerService, timeout(5000).times(1)).stop(); assertTrue("no exceptions: " + exceptions, exceptions.isEmpty()); } } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBOffsetRecoveryListenerTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBOffsetRecoveryListenerTest.java index 1b3f1e8afab..613b620d72f 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBOffsetRecoveryListenerTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBOffsetRecoveryListenerTest.java @@ -32,7 +32,9 @@ import org.apache.activemq.store.MessageStore; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,9 +54,17 @@ public class KahaDBOffsetRecoveryListenerTest { protected BrokerService brokerService = null; protected BrokerService restartBrokerService = null; + @Rule + public TestName testName = new TestName(); + + protected final int PRETEST_MSG_COUNT = 17531; + @Before public void beforeEach() throws Exception { - + // Send+Recv a odd number of messages beyond cache sizes + // to confirm the queue's sequence number gets pushed off + sendMessages(PRETEST_MSG_COUNT, testName.getMethodName()); + assertEquals(Integer.valueOf(PRETEST_MSG_COUNT), Integer.valueOf(receiveMessages(testName.getMethodName()))); } @After @@ -68,7 +78,7 @@ protected BrokerService createBroker(KahaDBStore kaha) throws Exception { broker.setUseJmx(false); broker.setPersistenceAdapter(kaha); broker.start(); - broker.waitUntilStarted(10_000l); + broker.waitUntilStarted(10_000L); return broker; } @@ -130,7 +140,7 @@ protected void runOffsetLoopTest(final int sendCount, final int expectedMessageC restartBrokerService = createBroker(createStore(false)); restartBrokerService.start(); - restartBrokerService.waitUntilStarted(30_000l); + restartBrokerService.waitUntilStarted(30_000L); assertEquals(sendCount, receiveMessages(queueName)); restartBrokerService.stop(); @@ -139,42 +149,42 @@ protected void runOffsetLoopTest(final int sendCount, final int expectedMessageC @Test public void testOffsetZero() throws Exception { - runOffsetTest(1_000, 1_000, 0, 1, 1, 0, "TEST.OFFSET.ZERO"); + runOffsetTest(1_000, 1_000, 0, 1, 1, 0, testName.getMethodName()); } @Test public void testOffsetOne() throws Exception { - runOffsetTest(1_000, 1_000, 1, 1, 1, 1, "TEST.OFFSET.ONE"); + runOffsetTest(1_000, 1_000, 1, 1, 1, 1, testName.getMethodName()); } @Test public void testOffsetLastMinusOne() throws Exception { - runOffsetTest(1_000, 1_000, 999, 1, 1, 999, "TEST.OFFSET.LASTMINUSONE"); + runOffsetTest(1_000, 1_000, 999, 1, 1, 999, testName.getMethodName()); } @Test public void testOffsetLast() throws Exception { - runOffsetTest(1_000, 1_000, 1_000, 1, 0, -1, "TEST.OFFSET.LAST"); + runOffsetTest(1_000, 1_000, 1_000, 1, 0, -1, testName.getMethodName()); } @Test public void testOffsetBeyondQueueSizeNoError() throws Exception { - runOffsetTest(1_000, 1_000, 10_000, 1, 0, -1, "TEST.OFFSET.BEYOND"); + runOffsetTest(1_000, 1_000, 10_000, 1, 0, -1, testName.getMethodName()); } @Test public void testOffsetEmptyQueue() throws Exception { - runOffsetTest(0, 0, 10_000, 1, 0, -1, "TEST.OFFSET.EMPTY"); + runOffsetTest(0, 0, 10_000, 1, 0, -1, testName.getMethodName()); } @Test public void testOffsetWalk() throws Exception { - runOffsetLoopTest(10_000, 10_000, 9_000, 200, 200, 9_000, "TEST.OFFSET.WALK", 8, false); + runOffsetLoopTest(10_000, 10_000, 9_000, 200, 200, 9_000, testName.getMethodName(), 8, false); } @Test public void testOffsetRepeat() throws Exception { - runOffsetLoopTest(10_000, 10_000, 7_000, 133, 133, 7_000, "TEST.OFFSET.REPEAT", 10, true); + runOffsetLoopTest(10_000, 10_000, 7_000, 133, 133, 7_000, testName.getMethodName(), 10, true); } private void sendMessages(int count, String queueName) throws JMSException { @@ -198,12 +208,15 @@ private void sendMessages(int count, String queueName) throws JMSException { private int receiveMessages(String queueName) throws JMSException { int rc=0; ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost"); + cf.setWatchTopicAdvisories(false); + Connection connection = cf.createConnection(); + try { connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer messageConsumer = session.createConsumer(new ActiveMQQueue(queueName)); - while ( messageConsumer.receive(1000) !=null ) { + while (messageConsumer.receive(1_000L) != null) { rc++; } return rc; diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBTest.java index e1fc1d77817..d06544f673d 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBTest.java @@ -27,11 +27,15 @@ import jakarta.jms.MessageProducer; import jakarta.jms.Session; +import java.util.concurrent.atomic.AtomicInteger; import junit.framework.TestCase; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.broker.BrokerService; import org.apache.activemq.command.ActiveMQQueue; +import org.apache.activemq.util.DefaultIOExceptionHandler; +import org.apache.activemq.util.IOExceptionHandler; +import org.apache.activemq.util.Wait; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.LogEvent; @@ -236,6 +240,69 @@ public void append(LogEvent event) { assertFalse("Did not replay any records from the journal", didSomeRecovery.get()); } + + /** + * Test the checkpoint runner task continues to run if the configured + * IOExceptionHandler throws a runtime exception while processing + * the IOException it is handling and the broker is not shut down. This + * could happen if using the DefaultIOExceptionHandler and startStopConnectors + * is set to true, or if a user provides their own IOExceptionHandler that + * throws an exception. + */ + public void testCheckpointExceptionKeepRunning() throws Exception { + testCheckpointIOException(true); + } + + /** + * Test the broker shuts down by when DefaultIOExceptionHandler + * handles an IOException thrown by the checkpoint runner task. This is the + * default behavior of the broker if not configured with a custom + * IOExceptionHandler and startStopConnectors is false + */ + public void testCheckpointExceptionShutdown() throws Exception { + testCheckpointIOException(false); + } + + private void testCheckpointIOException(boolean startStopConnectors) throws Exception { + final AtomicInteger iterations = new AtomicInteger(); + // Create a store that always throws an IOException when checkpoint is called + final KahaDBStore kaha = new KahaDBStore() { + @Override + protected void checkpointCleanup(boolean cleanup) throws IOException { + iterations.incrementAndGet(); + throw new IOException("fail"); + } + }; + kaha.setDirectory(new File("target/activemq-data/kahadb")); + kaha.deleteAllMessages(); + // Set the checkpoint interval to be very short so we can quickly + // check number of iterations + kaha.setCheckpointInterval(100); + + BrokerService broker = createBroker(kaha); + DefaultIOExceptionHandler ioExceptionHandler = new DefaultIOExceptionHandler(); + ioExceptionHandler.setStopStartConnectors(startStopConnectors); + broker.setIoExceptionHandler(ioExceptionHandler); + broker.start(); + + try { + if (startStopConnectors) { + // If startStopConnectors is true, the task should continue with future iterations + // as the SuppressReplyException that will be thrown is now handled so just verify + // we see 10 iterations which should happen quickly + assertTrue(Wait.waitFor(() -> iterations.get() == 10, 2000, 100)); + // broker should not be stopped + assertFalse(broker.isStopped()); + } else { + // If startStopConnectors is false, an IOException should shut down the broker + // which is the normal behavior + assertTrue(Wait.waitFor(broker::isStopped, 2000, 100)); + } + } finally { + broker.stop(); + } + } + private void assertExistsAndDelete(File file) { assertTrue(file.exists()); file.delete(); @@ -281,4 +348,4 @@ private String createContent(int i) { return sb.toString(); } -} \ No newline at end of file +} diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/test/JmsSendReceiveTestSupport.java b/activemq-unit-tests/src/test/java/org/apache/activemq/test/JmsSendReceiveTestSupport.java index 55f8b67f932..2800a37a97d 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/test/JmsSendReceiveTestSupport.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/test/JmsSendReceiveTestSupport.java @@ -77,7 +77,7 @@ protected void setUp() throws Exception { } } - LOG.info("Message count for test case is: " + messageCount); + LOG.info("Message count for test case is: {}", messageCount); data = new String[messageCount]; for (int i = 0; i < messageCount; i++) { data[i] = createMessageText(i); @@ -93,11 +93,7 @@ protected String createMessageText(int i) { } protected String createMessageBodyText() { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < largeMessageLoopSize; i++) { - buffer.append("0123456789"); - } - return buffer.toString(); + return "0123456789".repeat(Math.max(0, largeMessageLoopSize)); } /** @@ -111,7 +107,7 @@ public void testSendReceive() throws Exception { sendMessages(); assertMessagesAreReceived(); - LOG.info("" + data.length + " messages(s) received, closing down connections"); + LOG.info("{} messages(s) received, closing down connections", data.length); } protected void sendMessages() throws Exception { @@ -119,7 +115,7 @@ protected void sendMessages() throws Exception { Message message = createMessage(i); configureMessage(message); if (verbose) { - LOG.info("About to send a message: " + message + " with text: " + data[i]); + LOG.info("About to send a message: {} with text: {}", message, data[i]); } sendMessage(i, message); } @@ -130,8 +126,7 @@ protected void sendMessage(int index, Message message) throws Exception { } protected Message createMessage(int index) throws JMSException { - Message message = session.createTextMessage(data[index]); - return message; + return session.createTextMessage(data[index]); } /** @@ -166,7 +161,7 @@ protected void assertMessagesReceivedAreValid(List receivedMessages) th if (data.length != copyOfMessages.size()) { for (Iterator iter = copyOfMessages.iterator(); iter.hasNext();) { Object message = iter.next(); - LOG.info("<== " + counter++ + " = " + message); + LOG.info("<== {} = {}", counter++, message); } } @@ -191,7 +186,7 @@ protected void assertMessageValid(int index, Message message) throws JMSExceptio String text = textMessage.getText(); if (verbose) { - LOG.info("Received Text: " + text); + LOG.info("Received Text: {}", text); } assertEquals("Message: " + index, data[index], text); @@ -238,7 +233,7 @@ public synchronized void onMessage(Message message) { */ protected void consumeMessage(Message message, List messageList) { if (verbose) { - LOG.info("Received message: " + message); + LOG.info("Received message: {}", message); } messageList.add(message); diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/transport/nio/NIOMaxFrameSizeCleanupTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/transport/nio/NIOMaxFrameSizeCleanupTest.java index 81fe2869d00..5b838f5ce13 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/transport/nio/NIOMaxFrameSizeCleanupTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/transport/nio/NIOMaxFrameSizeCleanupTest.java @@ -120,7 +120,7 @@ protected void testMaxFrameSizeCleanup(String transportType, String clientUri) t } //Generate a body that is too large - StringBuffer body = new StringBuffer(); + StringBuilder body = new StringBuilder(); Random r = new Random(); for (int i = 0; i < 10000; i++) { body.append(r.nextInt()); diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/transport/udp/UdpTestSupport.java b/activemq-unit-tests/src/test/java/org/apache/activemq/transport/udp/UdpTestSupport.java index aa80937797c..86bd37a358d 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/transport/udp/UdpTestSupport.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/transport/udp/UdpTestSupport.java @@ -62,7 +62,7 @@ public void testSendingSmallMessage() throws Exception { expected.setPrefetchSize(3456); try { - LOG.info("About to send: " + expected); + LOG.info("About to send: {}", expected); producer.oneway(expected); Command received = assertCommandReceived(); @@ -72,7 +72,7 @@ public void testSendingSmallMessage() throws Exception { assertEquals("isExclusive", expected.isExclusive(), actual.isExclusive()); assertEquals("getPrefetchSize", expected.getPrefetchSize(), actual.getPrefetchSize()); } catch (Exception e) { - LOG.info("Caught: " + e); + LOG.info("Caught: {}", String.valueOf(e)); e.printStackTrace(); fail("Failed to send to transport: " + e); } @@ -99,7 +99,7 @@ protected void assertSendTextMessage(ActiveMQDestination destination, String tex expected.setDestination(destination); try { - LOG.info("About to send message of type: " + expected.getClass()); + LOG.info("About to send message of type: {}", expected.getClass()); producer.oneway(expected); // lets send a dummy command to ensure things don't block if we @@ -116,20 +116,16 @@ protected void assertSendTextMessage(ActiveMQDestination destination, String tex assertEquals("getDestination", expected.getDestination(), actual.getDestination()); assertEquals("getText", expected.getText(), actual.getText()); - LOG.info("Received text message with: " + actual.getText().length() + " character(s)"); + LOG.info("Received text message with: {} character(s)", actual.getText().length()); } catch (Exception e) { - LOG.info("Caught: " + e); + LOG.info("Caught: {}", String.valueOf(e)); e.printStackTrace(); fail("Failed to send to transport: " + e); } } protected String createMessageBodyText(int loopSize) { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < loopSize; i++) { - buffer.append("0123456789"); - } - return buffer.toString(); + return "0123456789".repeat(Math.max(0, loopSize)); } protected void setUp() throws Exception { @@ -162,11 +158,11 @@ public void onAcceptError(Exception error) { producer = createProducer(); producer.setTransportListener(new TransportListener() { public void onCommand(Object command) { - LOG.info("Producer received: " + command); + LOG.info("Producer received: {}", command); } public void onException(IOException error) { - LOG.info("Producer exception: " + error); + LOG.info("Producer exception: {}", String.valueOf(error)); error.printStackTrace(); } @@ -198,7 +194,7 @@ protected void tearDown() throws Exception { public void onCommand(Object o) { final Command command = (Command)o; if (command instanceof WireFormatInfo) { - LOG.info("Got WireFormatInfo: " + command); + LOG.info("Got WireFormatInfo: {}", command); } else { if (command.isResponseRequired()) { // lets send a response back... @@ -206,9 +202,9 @@ public void onCommand(Object o) { } if (large) { - LOG.info("### Received command: " + command.getClass() + " with id: " + command.getCommandId()); + LOG.info("### Received command: {} with id: {}", command.getClass(), command.getCommandId()); } else { - LOG.info("### Received command: " + command); + LOG.info("### Received command: {}", command); } synchronized (lock) { @@ -228,14 +224,14 @@ protected void sendResponse(Command command) { try { consumer.oneway(response); } catch (IOException e) { - LOG.info("Caught: " + e); + LOG.info("Caught: {}", String.valueOf(e)); e.printStackTrace(); throw new RuntimeException(e); } } public void onException(IOException error) { - LOG.info("### Received error: " + error); + LOG.info("### Received error: {}", String.valueOf(error)); error.printStackTrace(); } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/usecases/TopicDurableConnectStatsTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/usecases/TopicDurableConnectStatsTest.java index 16aeeb9209e..13d4e0e2b95 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/usecases/TopicDurableConnectStatsTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/usecases/TopicDurableConnectStatsTest.java @@ -129,12 +129,12 @@ private void destroyBroker() throws Exception { protected ObjectName assertRegisteredObjectName(String name) throws MalformedObjectNameException, NullPointerException { ObjectName objectName = new ObjectName(name); - LOG.info("** Looking for " + name); + LOG.info("** Looking for {}", name); try { if (mbeanServer.isRegistered(objectName)) { - LOG.info("Bean Registered: " + objectName); + LOG.info("Bean Registered: {}", objectName); } else { - LOG.info("Couldn't find Mbean! " + objectName); + LOG.info("Couldn't find Mbean! {}", objectName); } } catch (IOException e) { @@ -159,8 +159,8 @@ public void testPendingTopicStat() throws Exception { ObjectName subscriberObjName1 = set.iterator().next(); subscriber1 = MBeanServerInvocationHandler.newProxyInstance(mbeanServer, subscriberObjName1, DurableSubscriptionViewMBean.class, true); - LOG.info("Beginning Pending Queue Size count: " + subscriber1.getPendingQueueSize()); - LOG.info("Prefetch Limit: " + subscriber1.getPrefetchSize()); + LOG.info("Beginning Pending Queue Size count: {}", subscriber1.getPendingQueueSize()); + LOG.info("Prefetch Limit: {}", subscriber1.getPrefetchSize()); assertEquals("no pending", 0, subscriber1.getPendingQueueSize()); assertEquals("Prefetch Limit ", 10, subscriber1.getPrefetchSize()); @@ -191,10 +191,10 @@ public void testPendingTopicStat() throws Exception { producerSessions.commit(); } - LOG.info("Sent " + i + " messages in total"); + LOG.info("Sent {} messages in total", i); producerCon.close(); - LOG.info("Pending Queue Size count: " + subscriber1.getPendingQueueSize()); + LOG.info("Pending Queue Size count: {}", subscriber1.getPendingQueueSize()); assertEquals("pending as expected", 20, subscriber1.getPendingQueueSize()); LOG.info("Re-connect client and consume messages"); @@ -213,21 +213,21 @@ public boolean isSatisified() throws Exception { } })); - LOG.info("Received: " + listener.count); + LOG.info("Received: {}", listener.count); int pq = subscriber1.getPendingQueueSize(); - LOG.info("Pending Queue Size count: " + pq); + LOG.info("Pending Queue Size count: {}", pq); assertEquals("Pending queue after consumed", 0, pq); session2.close(); con2.close(); - LOG.info("FINAL Pending Queue Size count (after consumer close): " + subscriber1.getPendingQueueSize()); + LOG.info("FINAL Pending Queue Size count (after consumer close): {}", subscriber1.getPendingQueueSize()); } private String createMessageText(int index) { - StringBuffer buffer = new StringBuffer(messageSize); - buffer.append("Message: " + index + " sent at: " + new Date()); + StringBuilder buffer = new StringBuilder(messageSize); + buffer.append("Message: ").append(index).append(" sent at: ").append(new Date()); if (buffer.length() > messageSize) { return buffer.substring(0, messageSize); } diff --git a/activemq-unit-tests/src/test/java21/org/apache/activemq/broker/VirtualThreadTaskRunnerBrokerTest.java b/activemq-unit-tests/src/test/java21/org/apache/activemq/broker/VirtualThreadTaskRunnerBrokerTest.java new file mode 100644 index 00000000000..88d67158ae5 --- /dev/null +++ b/activemq-unit-tests/src/test/java21/org/apache/activemq/broker/VirtualThreadTaskRunnerBrokerTest.java @@ -0,0 +1,37 @@ +/** + * 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.broker; + +import junit.framework.Test; + +public class VirtualThreadTaskRunnerBrokerTest extends BrokerTest { + + protected BrokerService createBroker() throws Exception { + BrokerService broker = super.createBroker(); + broker.setVirtualThreadTaskRunner(true); + return broker; + } + + public static Test suite() { + return suite(VirtualThreadTaskRunnerBrokerTest.class); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + +} diff --git a/activemq-unit-tests/src/test/resources/org/apache/activemq/broker/virtual/virtual-topic-network-test.xml b/activemq-unit-tests/src/test/resources/org/apache/activemq/broker/virtual/virtual-topic-network-test.xml index ab225d89318..16ae4ce9d99 100644 --- a/activemq-unit-tests/src/test/resources/org/apache/activemq/broker/virtual/virtual-topic-network-test.xml +++ b/activemq-unit-tests/src/test/resources/org/apache/activemq/broker/virtual/virtual-topic-network-test.xml @@ -21,7 +21,7 @@ xmlns:jms="http://www.springframework.org/schema/jms" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd - http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.11.0.xsd"> + http://activemq.apache.org/schema/core classpath:activemq.xsd"> diff --git a/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker1.xml b/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker1.xml index 0ed33d7bdd6..bfcb1bf42f5 100644 --- a/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker1.xml +++ b/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker1.xml @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - + diff --git a/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker2.xml b/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker2.xml index fd96b883bf9..7ecfe559ac2 100644 --- a/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker2.xml +++ b/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker2.xml @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - + diff --git a/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker3.xml b/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker3.xml index 3438feec172..6b867fcb4c2 100644 --- a/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker3.xml +++ b/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/rebalance-broker3.xml @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - + diff --git a/activemq-unit-tests/src/test/resources/spring-embedded-xbean-bean-ref.xml b/activemq-unit-tests/src/test/resources/spring-embedded-xbean-bean-ref.xml index b6daf725c6b..02d3eb46587 100644 --- a/activemq-unit-tests/src/test/resources/spring-embedded-xbean-bean-ref.xml +++ b/activemq-unit-tests/src/test/resources/spring-embedded-xbean-bean-ref.xml @@ -22,7 +22,7 @@ xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd - http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> + http://activemq.apache.org/schema/core classpath:activemq.xsd"> diff --git a/activemq-web-console/src/main/webapp/WEB-INF/tags/form/short.tag b/activemq-web-console/src/main/webapp/WEB-INF/tags/form/short.tag index 03550c3aaaa..06243a13ba5 100644 --- a/activemq-web-console/src/main/webapp/WEB-INF/tags/form/short.tag +++ b/activemq-web-console/src/main/webapp/WEB-INF/tags/form/short.tag @@ -14,16 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. --%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ attribute name="text" type="java.lang.String" required="true" %> <%@ attribute name="length" type="java.lang.Integer" required="false" %> <% - text = org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(text); - text = org.apache.commons.lang3.StringEscapeUtils.escapeEcmaScript(text); - if (length == null || length < 20) - length = 20; - if (text.length() <= length) { - out.print(text); - } else { - out.println(text.substring(0, (length-10)) + "..." + text.substring(text.length() - 5)); + if (length == null || length < 20) { + length = 20; } -%> \ No newline at end of file + if (text.length() > length) { + text = text.substring(0, (length-10)) + "..." + text.substring(text.length() - 5); + } +%> + \ No newline at end of file diff --git a/activemq-web-console/src/main/webapp/WEB-INF/tags/form/text.tag b/activemq-web-console/src/main/webapp/WEB-INF/tags/form/text.tag index 0bbb0f6cef1..547a0c26ed6 100644 --- a/activemq-web-console/src/main/webapp/WEB-INF/tags/form/text.tag +++ b/activemq-web-console/src/main/webapp/WEB-INF/tags/form/text.tag @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. --%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ attribute name="name" type="java.lang.String" required="true" %> <%@ attribute name="defaultValue" type="java.lang.String" required="false" %> <% @@ -24,7 +25,6 @@ if (value == null) { value = ""; } - value = org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(value); - %> - + + diff --git a/activemq-web-console/src/main/webapp/js/head.js b/activemq-web-console/src/main/webapp/js/head.js index d78cd393e56..bc59521db14 100644 --- a/activemq-web-console/src/main/webapp/js/head.js +++ b/activemq-web-console/src/main/webapp/js/head.js @@ -14,7 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -window.onload = function () { - addEvent(window, 'load', prettyPrint) -} +addEvent(window, 'load', (_event) => prettyPrint()); diff --git a/activemq-web-demo/src/test/java/org/apache/activemq/web/RestPersistentTest.java b/activemq-web-demo/src/test/java/org/apache/activemq/web/RestPersistentTest.java index 61345eaa80c..6bd2f79d1ce 100644 --- a/activemq-web-demo/src/test/java/org/apache/activemq/web/RestPersistentTest.java +++ b/activemq-web-demo/src/test/java/org/apache/activemq/web/RestPersistentTest.java @@ -77,7 +77,7 @@ public void postAndGet(String destinationType) throws Exception { private void postMessage(HttpClient httpClient, String url, String properties, String message) throws Exception { final CountDownLatch latch = new CountDownLatch(1); - final StringBuffer buf = new StringBuffer(); + final StringBuilder buf = new StringBuilder(); final AtomicInteger status = new AtomicInteger(); httpClient.newRequest(url+"&"+properties) .header("Content-Type","text/xml") @@ -99,7 +99,7 @@ private void getMessage(HttpClient httpClient, String url, String selector, Stri { final CountDownLatch latch = new CountDownLatch(1); - final StringBuffer buf = new StringBuffer(); + final StringBuilder buf = new StringBuilder(); final AtomicInteger status = new AtomicInteger(); Request request = httpClient.newRequest(url) .header("accept", "text/xml") diff --git a/activemq-web-demo/src/test/java/org/apache/activemq/web/RestTest.java b/activemq-web-demo/src/test/java/org/apache/activemq/web/RestTest.java index 7617ddb8b68..a47dd73a951 100644 --- a/activemq-web-demo/src/test/java/org/apache/activemq/web/RestTest.java +++ b/activemq-web-demo/src/test/java/org/apache/activemq/web/RestTest.java @@ -180,7 +180,7 @@ public void testCorrelation() throws Exception { asyncRequest(httpClient, "http://localhost:" + port + "/message/test?readTimeout=1000&type=queue&clientId=test", buf); assertEquals(HttpStatus.OK_200, result.get().getResponse().getStatus()); - LOG.info("Received: " + buf); + LOG.info("Received: {}", buf); assertEquals(correlId, buf.toString()); } httpClient.stop(); @@ -199,9 +199,9 @@ public void testDisconnect() throws Exception { asyncRequest(httpClient, "http://localhost:" + port + "/message/test?readTimeout=1000&type=queue&clientId=test", buf); assertEquals(HttpStatus.OK_200, result.get().getResponse().getStatus()); - LOG.info("Received: " + buf); + LOG.info("Received: {}", buf); - final StringBuffer buf2 = new StringBuffer(); + final StringBuilder buf2 = new StringBuilder(); final CountDownLatch latch2 = new CountDownLatch(1); httpClient.newRequest("http://localhost:" + port + "/message/test?clientId=test&action=unsubscribe") .method(HttpMethod.POST).send(new BufferingResponseListener() { diff --git a/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java b/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java index 5f8d7df610c..ee090a2907e 100644 --- a/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java +++ b/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java @@ -42,8 +42,8 @@ import org.apache.activemq.broker.jmx.QueueViewMBean; import org.apache.activemq.broker.jmx.SubscriptionViewMBean; import org.apache.activemq.broker.jmx.TopicViewMBean; +import org.apache.activemq.util.JMXSupport; import org.apache.activemq.web.util.ExceptionUtils; -import org.springframework.util.StringUtils; /** * A useful base class for an implementation of {@link BrokerFacade} @@ -78,7 +78,7 @@ public Collection getTopics() throws Exception { @Override public Collection getTopicSubscribers(String topicName) throws Exception { String brokerName = getBrokerName(); - topicName = StringUtils.replace(topicName, "\"", "_"); + topicName = JMXSupport.encodeObjectNamePart(topicName); ObjectName query = new ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName + ",destinationType=Topic,destinationName=" + topicName + ",endpoint=Consumer,*"); Set queryResult = queryNames(query, null); @@ -171,20 +171,22 @@ public Collection getConnections() throws Exception { @SuppressWarnings("unchecked") public Collection getConnections(String connectorName) throws Exception { String brokerName = getBrokerName(); + connectorName = JMXSupport.encodeObjectNamePart(connectorName); ObjectName query = new ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName - + ",connector=clientConnectors,connectorName=" + connectorName + ",connectionViewType=clientId" + ",connectionName=*"); Set queryResult = queryNames(query, null); + + ",connector=clientConnectors,connectorName=" + connectorName + ",connectionViewType=clientId,connectionName=*"); + Set queryResult = queryNames(query, null); + Collection connections = getManagedObjects(queryResult.toArray(new ObjectName[queryResult.size()]), + ConnectionViewMBean.class); Collection result = new ArrayList(queryResult.size()); - for (ObjectName on : queryResult) { - String name = StringUtils.replace(on.getKeyProperty("connectionName"), "_", ":"); - result.add(name); - } + for (ConnectionViewMBean connection : connections) + result.add(connection.getClientId()); return result; } @Override @SuppressWarnings("unchecked") public ConnectionViewMBean getConnection(String connectionName) throws Exception { - connectionName = StringUtils.replace(connectionName, ":", "_"); + connectionName = JMXSupport.encodeObjectNamePart(connectionName); String brokerName = getBrokerName(); ObjectName query = new ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName + ",connector=clientConnectors,*,connectionName=" + connectionName); @@ -211,6 +213,7 @@ public Collection getConnectors() throws Exception { @Override public ConnectorViewMBean getConnector(String name) throws Exception { String brokerName = getBrokerName(); + name = JMXSupport.encodeObjectNamePart(name); ObjectName objectName = new ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName + ",connector=clientConnectors,connectorName=" + name); return (ConnectorViewMBean) newProxyInstance(objectName, ConnectorViewMBean.class, true); @@ -239,8 +242,7 @@ public Collection getNetworkBridges() throws Exception { @SuppressWarnings("unchecked") public Collection getQueueConsumers(String queueName) throws Exception { String brokerName = getBrokerName(); - queueName = StringUtils.replace(queueName, "\"", "_"); - queueName = StringUtils.replace(queueName, ":", "_"); + queueName = JMXSupport.encodeObjectNamePart(queueName); ObjectName query = new ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName + ",destinationType=Queue,destinationName=" + queueName + ",endpoint=Consumer,*"); Set queryResult = queryNames(query, null); @@ -251,8 +253,7 @@ public Collection getQueueConsumers(String queueName) thr @SuppressWarnings("unchecked") public Collection getQueueProducers(String queueName) throws Exception { String brokerName = getBrokerName(); - queueName = StringUtils.replace(queueName, "\"", "_"); - queueName = StringUtils.replace(queueName, ":", "_"); + queueName = JMXSupport.encodeObjectNamePart(queueName); ObjectName query = new ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName + ",destinationType=Queue,destinationName=" + queueName + ",endpoint=Producer,*"); Set queryResult = queryNames(query, null); @@ -263,8 +264,7 @@ public Collection getQueueProducers(String queueName) throws @SuppressWarnings("unchecked") public Collection getTopicProducers(String topicName) throws Exception { String brokerName = getBrokerName(); - topicName = StringUtils.replace(topicName, "\"", "_"); - topicName = StringUtils.replace(topicName, ":", "_"); + topicName = JMXSupport.encodeObjectNamePart(topicName); ObjectName query = new ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName + ",destinationType=Topic,destinationName=" + topicName + ",endpoint=Producer,*"); Set queryResult = queryNames(query, null); @@ -274,7 +274,7 @@ public Collection getTopicProducers(String topicName) throws @Override @SuppressWarnings("unchecked") public Collection getConsumersOnConnection(String connectionName) throws Exception { - connectionName = StringUtils.replace(connectionName, ":", "_"); + connectionName = JMXSupport.encodeObjectNamePart(connectionName); String brokerName = getBrokerName(); ObjectName query = new ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName + ",*,endpoint=Consumer,clientId=" + connectionName); diff --git a/assembly/src/docker/docker-compose.yml b/assembly/src/docker/docker-compose.yml index bac8027f3d0..aed1b4648fd 100644 --- a/assembly/src/docker/docker-compose.yml +++ b/assembly/src/docker/docker-compose.yml @@ -26,7 +26,7 @@ services: - "61613" - "1883" - "61614" - - "8161"` + - "8161" - "1099" ports: - "8161:8161" diff --git a/assembly/src/main/descriptors/common-bin.xml b/assembly/src/main/descriptors/common-bin.xml index a406394abb4..4574d21bc0f 100644 --- a/assembly/src/main/descriptors/common-bin.xml +++ b/assembly/src/main/descriptors/common-bin.xml @@ -225,7 +225,6 @@ com.thoughtworks.xstream:xstream xpp3:xpp3 org.codehaus.jettison:jettison - org.apache.servicemix.bundles:org.apache.servicemix.bundles.josql org.jasypt:jasypt org.jasypt:jasypt-spring4 org.jmdns:jmdns diff --git a/assembly/src/release/conf/jetty.xml b/assembly/src/release/conf/jetty.xml index 75923e6dbed..cb3d281ea35 100644 --- a/assembly/src/release/conf/jetty.xml +++ b/assembly/src/release/conf/jetty.xml @@ -82,13 +82,13 @@ - + - + diff --git a/assembly/src/test/java/org/apache/activemq/benchmark/Producer.java b/assembly/src/test/java/org/apache/activemq/benchmark/Producer.java index 5ece08a67c3..cc8ab794c16 100644 --- a/assembly/src/test/java/org/apache/activemq/benchmark/Producer.java +++ b/assembly/src/test/java/org/apache/activemq/benchmark/Producer.java @@ -118,7 +118,7 @@ public void run() { } protected String getMessage() { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(messageSize); for (int i = 0; i < messageSize; i++) { char ch = 'X'; buffer.append(ch); @@ -164,7 +164,7 @@ protected void publishLoop(Session session, MessageProducer publisher, String te protected String loadFile(String file) throws IOException { System.out.println("Loading file: " + file); - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); BufferedReader in = new BufferedReader(new FileReader(file)); while (true) { String line = in.readLine(); diff --git a/pom.xml b/pom.xml index a2eabd1ac16..6b0faacc394 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache apache - 34 + 35 4.0.0 @@ -44,15 +44,13 @@ 0.1.0 1.10.15 1.1.0 - 1.0-M3-dev - 4.10.5 + 4.14.0 1.11.0 3.2.2 2.13.0 - 2.19.0 + 2.20.0 1.3.5 2.12.1 - 1.0 2.0.0.AM25 3.17.0 1.1.1 @@ -62,19 +60,19 @@ 4.5.14 4.4.16 1.2.0.Beta4 - 2.19.1 + 2.20.0 + 2.20 3.1.0 1.9.3 4.0.5 2.3.2_1 - 11.0.25 + 11.0.26 [11,13) - 3.6.1 + 3.6.2 3.30.2-GA 1.5.4 2.13.1 - 2.1.2 - 1.5_5 + 2.3.0 4.13.2 1.3 4.3.7 @@ -87,12 +85,11 @@ 0.34.1 2.4.0 4.1.94.Final - 1.4 2.1.0 1.13.0 2.0.16 1.1.2 - 6.2.8 + 6.2.11 [6,7) 1.2.5 1.1.4c @@ -580,7 +577,7 @@ com.fasterxml.jackson.core jackson-annotations - ${jackson-version} + ${jackson-annotations-version} com.fasterxml.jackson.core @@ -768,25 +765,6 @@ ${org-apache-derby-version} - - - axion - axion - ${axion-version} - - - - commons-primitives - commons-primitives - ${commons-primitives-version} - - - - jakarta-regexp - jakarta-regexp - ${regexp-version} - - org.apache.commons commons-dbcp2 @@ -952,12 +930,6 @@ jakarta - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.josql - ${josql-version} - - jakarta.annotation jakarta.annotation-api