From a0f369af05978aff9b2b81cfe6c6cfebc9c0632c Mon Sep 17 00:00:00 2001 From: Francesco Nigro Date: Fri, 7 Apr 2017 13:57:17 +0200 Subject: [PATCH 1/2] ARTEMIS-1099 Force Netty EPOLL to be available only on Linux 64bit platforms --- .../apache/activemq/artemis/utils/Env.java | 56 +++++++++++++++++++ .../core/remoting/impl/netty/Epoll.java | 44 +++++++++++++++ .../remoting/impl/netty/NettyConnector.java | 1 - .../remoting/impl/netty/NettyAcceptor.java | 1 - 4 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 artemis-commons/src/main/java/org/apache/activemq/artemis/utils/Env.java create mode 100644 artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/Epoll.java diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/Env.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/Env.java new file mode 100644 index 0000000000..cb94d1c1e9 --- /dev/null +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/Env.java @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.activemq.artemis.utils; + +/** + * Utility that detects various properties specific to the current runtime + * environment, such as JVM bitness and OS type. + */ +public final class Env { + + private static final String OS = System.getProperty("os.name").toLowerCase(); + private static final boolean IS_LINUX = OS.startsWith("linux"); + private static final boolean IS_64BIT = checkIs64bit(); + + private Env() { + + } + + public static boolean isLinuxOs() { + return IS_LINUX == true; + } + + public static boolean is64BitJvm() { + return IS_64BIT; + } + + private static boolean checkIs64bit() { + //check the more used JVMs + String systemProp; + systemProp = System.getProperty("com.ibm.vm.bitmode"); + if (systemProp != null) { + return "64".equals(systemProp); + } + systemProp = System.getProperty("sun.arch.data.model"); + if (systemProp != null) { + return "64".equals(systemProp); + } + systemProp = System.getProperty("java.vm.version"); + return systemProp != null && systemProp.contains("_64"); + } +} diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/Epoll.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/Epoll.java new file mode 100644 index 0000000000..96af01722d --- /dev/null +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/Epoll.java @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.activemq.artemis.core.remoting.impl.netty; + +import org.apache.activemq.artemis.utils.Env; + +/** + * Tells if {@code netty-transport-native-epoll} is supported. + */ +public final class Epoll { + + private static final boolean IS_AVAILABLE_EPOLL; + + static { + if (Env.is64BitJvm() && Env.isLinuxOs()) { + IS_AVAILABLE_EPOLL = io.netty.channel.epoll.Epoll.isAvailable(); + } else { + IS_AVAILABLE_EPOLL = false; + } + } + + private Epoll() { + + } + + public static boolean isAvailable() { + return IS_AVAILABLE_EPOLL; + } +} diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java index ad789087b8..15c048b580 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java @@ -59,7 +59,6 @@ import io.netty.channel.ChannelPromise; import io.netty.channel.EventLoopGroup; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.WriteBufferWaterMark; -import io.netty.channel.epoll.Epoll; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollSocketChannel; import io.netty.channel.group.ChannelGroup; diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java index 4f248f538a..a428f040ee 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java @@ -45,7 +45,6 @@ import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.ServerChannel; import io.netty.channel.WriteBufferWaterMark; -import io.netty.channel.epoll.Epoll; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollServerSocketChannel; import io.netty.channel.group.ChannelGroup; From dbe1976b47a15cea30f6dededcd68140b765c61f Mon Sep 17 00:00:00 2001 From: Clebert Suconic Date: Fri, 7 Apr 2017 10:28:48 -0400 Subject: [PATCH 2/2] NO-JIRA: Using Env as the source of isTestEnv --- .../org/apache/activemq/artemis/utils/Env.java | 15 +++++++++++++++ .../core/remoting/impl/netty/NettyConnection.java | 9 +++++++++ .../core/config/impl/ConfigurationImpl.java | 7 ++----- .../artemis/core/server/impl/QueueImpl.java | 4 ++-- .../artemis/tests/util/ActiveMQTestBase.java | 3 ++- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/Env.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/Env.java index cb94d1c1e9..d7fc48a7c1 100644 --- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/Env.java +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/Env.java @@ -23,6 +23,13 @@ package org.apache.activemq.artemis.utils; */ public final class Env { + /** The system will change a few logs and semantics to be suitable to + * run a long testsuite. + * Like a few log entries that are only valid during a production system. + * or a few cases we need to know as warn on the testsuite and as log in production. */ + private static boolean testEnv = false; + + private static final String OS = System.getProperty("os.name").toLowerCase(); private static final boolean IS_LINUX = OS.startsWith("linux"); private static final boolean IS_64BIT = checkIs64bit(); @@ -31,6 +38,14 @@ public final class Env { } + public static boolean isTestEnv() { + return testEnv; + } + + public static void setTestEnv(boolean testEnv) { + Env.testEnv = testEnv; + } + public static boolean isLinuxOs() { return IS_LINUX == true; } diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnection.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnection.java index 373c2f7c09..2181643de7 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnection.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnection.java @@ -41,6 +41,7 @@ import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.spi.core.remoting.BaseConnectionLifeCycleListener; import org.apache.activemq.artemis.spi.core.remoting.Connection; import org.apache.activemq.artemis.spi.core.remoting.ReadyListener; +import org.apache.activemq.artemis.utils.Env; import org.apache.activemq.artemis.utils.IPV6Util; import org.jboss.logging.Logger; @@ -295,6 +296,14 @@ public class NettyConnection implements Connection { public final boolean blockUntilWritable(final int requiredCapacity, final long timeout, final TimeUnit timeUnit) { final boolean isAllowedToBlock = isAllowedToBlock(); if (!isAllowedToBlock) { + + if (Env.isTestEnv()) { + // this will only show when inside the testsuite. + // we may great the log for FAILURE + logger.warn("FAILURE! The code is using blockUntilWritable inside a Netty worker, which would block. " + + "The code will probably need fixing!", new Exception("trace")); + } + if (logger.isDebugEnabled()) { logger.debug("Calling blockUntilWritable using a thread where it's not allowed"); } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java index f3455d0a3e..3ab74683ad 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java @@ -65,6 +65,7 @@ import org.apache.activemq.artemis.core.server.SecuritySettingPlugin; import org.apache.activemq.artemis.core.server.group.impl.GroupingHandlerConfiguration; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; import org.apache.activemq.artemis.core.settings.impl.ResourceLimitSettings; +import org.apache.activemq.artemis.utils.Env; import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader; import org.apache.activemq.artemis.utils.uri.BeanSupport; import org.jboss.logging.Logger; @@ -74,10 +75,6 @@ public class ConfigurationImpl implements Configuration, Serializable { private static final Logger logger = Logger.getLogger(ConfigurationImpl.class); - // We want to turn of a few log.infos from the testsuite as they would be too verbose for tests - // Only the testsuite should set this one up - public static boolean TEST_MODE = false; - public static final JournalType DEFAULT_JOURNAL_TYPE = JournalType.ASYNCIO; private static final long serialVersionUID = 4077088945050267843L; @@ -357,7 +354,7 @@ public class ConfigurationImpl implements Configuration, Serializable { public long getGlobalMaxSize() { if (globalMaxSize == null) { this.globalMaxSize = ActiveMQDefaultConfiguration.getDefaultMaxGlobalSize(); - if (!TEST_MODE) { + if (!Env.isTestEnv()) { ActiveMQServerLogger.LOGGER.usingDefaultPaging(globalMaxSize); } } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java index 3901a847df..dc4b09007a 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java @@ -47,7 +47,6 @@ import org.apache.activemq.artemis.api.core.Pair; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.management.CoreNotificationType; import org.apache.activemq.artemis.api.core.management.ManagementHelper; -import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl; import org.apache.activemq.artemis.core.filter.Filter; import org.apache.activemq.artemis.core.io.IOCallback; import org.apache.activemq.artemis.core.paging.cursor.PagePosition; @@ -86,6 +85,7 @@ import org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl import org.apache.activemq.artemis.core.transaction.impl.TransactionImpl; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.utils.ConcurrentHashSet; +import org.apache.activemq.artemis.utils.Env; import org.apache.activemq.artemis.utils.FutureLatch; import org.apache.activemq.artemis.utils.LinkedListIterator; import org.apache.activemq.artemis.utils.PriorityLinkedList; @@ -3122,7 +3122,7 @@ public class QueueImpl implements Queue { } private void checkDeadLetterAddressAndExpiryAddress(final AddressSettings settings) { - if (!ConfigurationImpl.TEST_MODE) { + if (!Env.isTestEnv()) { if (settings.getDeadLetterAddress() == null) { ActiveMQServerLogger.LOGGER.AddressSettingsNoDLA(name); } diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java index 0ffb386226..774b5f5e3d 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java @@ -136,6 +136,7 @@ import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager; import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule; import org.apache.activemq.artemis.utils.ActiveMQThreadFactory; +import org.apache.activemq.artemis.utils.Env; import org.apache.activemq.artemis.utils.FileUtil; import org.apache.activemq.artemis.utils.OrderedExecutorFactory; import org.apache.activemq.artemis.utils.RandomUtil; @@ -158,7 +159,7 @@ import org.junit.runner.Description; public abstract class ActiveMQTestBase extends Assert { static { - ConfigurationImpl.TEST_MODE = true; + Env.setTestEnv(true); } private static final Logger logger = Logger.getLogger(ActiveMQTestBase.class);