Workaround for NoClassDefFound issue in Netty.
SimpleChannelInboundHandler generates `message` instance check code on the fly,
using JavaAssist. Which was not working, when a new Connection was created on the thread
outside of NettyMessagingManager bundle, which did not have access to netty classes.
- Implemented equivalent for SimpleChannelInboundHandler<InternaleMessage>
without specifying type parameter, avoiding on the fly code generation.
Other changes:
- Add a method in IpAddress to return InetAddress instance.
Change-Id: Ie97294a5650683457b9395e773269c5232d8e602
diff --git a/core/store/dist/BUCK b/core/store/dist/BUCK
index 27e4e3b..b5db3b8 100644
--- a/core/store/dist/BUCK
+++ b/core/store/dist/BUCK
@@ -23,5 +23,4 @@
deps = COMPILE_DEPS,
test_deps = TEST_DEPS,
visibility = ['PUBLIC'],
- dynamicimport_packages = 'io.netty.*',
)
diff --git a/core/store/dist/pom.xml b/core/store/dist/pom.xml
index d709022..d411da9 100644
--- a/core/store/dist/pom.xml
+++ b/core/store/dist/pom.xml
@@ -116,22 +116,4 @@
</dependency>
</dependencies>
- <build>
- <plugins>
-
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <DynamicImport-Package>
- io.netty.*
- </DynamicImport-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
</project>
diff --git a/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/MessageEncoder.java b/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/MessageEncoder.java
index 4f7bcfd..4b40108 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/MessageEncoder.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/MessageEncoder.java
@@ -32,7 +32,11 @@
* Encode InternalMessage out into a byte buffer.
*/
@Sharable
-public class MessageEncoder extends MessageToByteEncoder<InternalMessage> {
+public class MessageEncoder extends MessageToByteEncoder<Object> {
+// Effectively MessageToByteEncoder<InternalMessage>,
+// had to specify <Object> to avoid Class Loader not being able to find some classes.
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
private final int preamble;
@@ -41,14 +45,15 @@
this.preamble = preamble;
}
- private final Logger log = LoggerFactory.getLogger(getClass());
@Override
protected void encode(
ChannelHandlerContext context,
- InternalMessage message,
+ Object rawMessage,
ByteBuf out) throws Exception {
+ InternalMessage message = (InternalMessage) rawMessage;
+
out.writeInt(this.preamble);
// write time
@@ -100,4 +105,10 @@
}
context.close();
}
+
+ // Effectively same result as one generated by MessageToByteEncoder<InternalMessage>
+ @Override
+ public final boolean acceptOutboundMessage(Object msg) throws Exception {
+ return msg instanceof InternalMessage;
+ }
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java b/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java
index 52a264e..a806c02 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java
@@ -41,7 +41,6 @@
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
-
import org.apache.commons.pool.KeyedPoolableObjectFactory;
import org.apache.commons.pool.impl.GenericKeyedObjectPool;
import org.apache.felix.scr.annotations.Activate;
@@ -383,7 +382,7 @@
}
// Start the client.
CompletableFuture<Channel> retFuture = new CompletableFuture<>();
- ChannelFuture f = bootstrap.connect(ep.host().toString(), ep.port());
+ ChannelFuture f = bootstrap.connect(ep.host().toInetAddress(), ep.port());
f.addListener(future -> {
if (future.isSuccess()) {
@@ -491,10 +490,13 @@
}
@ChannelHandler.Sharable
- private class InboundMessageDispatcher extends SimpleChannelInboundHandler<InternalMessage> {
+ private class InboundMessageDispatcher extends SimpleChannelInboundHandler<Object> {
+ // Effectively SimpleChannelInboundHandler<InternalMessage>,
+ // had to specify <Object> to avoid Class Loader not being able to find some classes.
@Override
- protected void channelRead0(ChannelHandlerContext ctx, InternalMessage message) throws Exception {
+ protected void channelRead0(ChannelHandlerContext ctx, Object rawMessage) throws Exception {
+ InternalMessage message = (InternalMessage) rawMessage;
try {
dispatchLocally(message);
} catch (RejectedExecutionException e) {
@@ -507,7 +509,21 @@
log.error("Exception inside channel handling pipeline.", cause);
context.close();
}
+
+ /**
+ * Returns true if the given message should be handled.
+ *
+ * @param msg inbound message
+ * @return true if {@code msg} is {@link InternalMessage} instance.
+ *
+ * @see SimpleChannelInboundHandler#acceptInboundMessage(Object)
+ */
+ @Override
+ public final boolean acceptInboundMessage(Object msg) {
+ return msg instanceof InternalMessage;
+ }
}
+
private void dispatchLocally(InternalMessage message) throws IOException {
if (message.preamble() != preamble) {
log.debug("Received {} with invalid preamble from {}", message.type(), message.sender());
diff --git a/utils/misc/src/main/java/org/onlab/packet/IpAddress.java b/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
index f47b065..bf01406 100644
--- a/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
+++ b/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
@@ -16,6 +16,7 @@
package org.onlab.packet;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.nio.ByteBuffer;
@@ -142,6 +143,20 @@
}
/**
+ * Returns the IP address as InetAddress.
+ *
+ * @return InetAddress
+ */
+ public InetAddress toInetAddress() {
+ try {
+ return InetAddress.getByAddress(octets);
+ } catch (UnknownHostException e) {
+ // Should never reach here
+ return null;
+ }
+ }
+
+ /**
* Computes the IP address byte length for a given IP version.
*
* @param version the IP version