Committed by
Gerrit Code Review
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
Showing
5 changed files
with
49 additions
and
26 deletions
... | @@ -23,5 +23,4 @@ osgi_jar_with_tests ( | ... | @@ -23,5 +23,4 @@ osgi_jar_with_tests ( |
23 | deps = COMPILE_DEPS, | 23 | deps = COMPILE_DEPS, |
24 | test_deps = TEST_DEPS, | 24 | test_deps = TEST_DEPS, |
25 | visibility = ['PUBLIC'], | 25 | visibility = ['PUBLIC'], |
26 | - dynamicimport_packages = 'io.netty.*', | ||
27 | ) | 26 | ) | ... | ... |
... | @@ -116,22 +116,4 @@ | ... | @@ -116,22 +116,4 @@ |
116 | </dependency> | 116 | </dependency> |
117 | </dependencies> | 117 | </dependencies> |
118 | 118 | ||
119 | - <build> | ||
120 | - <plugins> | ||
121 | - | ||
122 | - <plugin> | ||
123 | - <groupId>org.apache.felix</groupId> | ||
124 | - <artifactId>maven-bundle-plugin</artifactId> | ||
125 | - <extensions>true</extensions> | ||
126 | - <configuration> | ||
127 | - <instructions> | ||
128 | - <DynamicImport-Package> | ||
129 | - io.netty.* | ||
130 | - </DynamicImport-Package> | ||
131 | - </instructions> | ||
132 | - </configuration> | ||
133 | - </plugin> | ||
134 | - </plugins> | ||
135 | - </build> | ||
136 | - | ||
137 | </project> | 119 | </project> | ... | ... |
... | @@ -32,7 +32,11 @@ import java.io.IOException; | ... | @@ -32,7 +32,11 @@ import java.io.IOException; |
32 | * Encode InternalMessage out into a byte buffer. | 32 | * Encode InternalMessage out into a byte buffer. |
33 | */ | 33 | */ |
34 | @Sharable | 34 | @Sharable |
35 | -public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { | 35 | +public class MessageEncoder extends MessageToByteEncoder<Object> { |
36 | +// Effectively MessageToByteEncoder<InternalMessage>, | ||
37 | +// had to specify <Object> to avoid Class Loader not being able to find some classes. | ||
38 | + | ||
39 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
36 | 40 | ||
37 | private final int preamble; | 41 | private final int preamble; |
38 | 42 | ||
... | @@ -41,14 +45,15 @@ public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { | ... | @@ -41,14 +45,15 @@ public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { |
41 | this.preamble = preamble; | 45 | this.preamble = preamble; |
42 | } | 46 | } |
43 | 47 | ||
44 | - private final Logger log = LoggerFactory.getLogger(getClass()); | ||
45 | 48 | ||
46 | @Override | 49 | @Override |
47 | protected void encode( | 50 | protected void encode( |
48 | ChannelHandlerContext context, | 51 | ChannelHandlerContext context, |
49 | - InternalMessage message, | 52 | + Object rawMessage, |
50 | ByteBuf out) throws Exception { | 53 | ByteBuf out) throws Exception { |
51 | 54 | ||
55 | + InternalMessage message = (InternalMessage) rawMessage; | ||
56 | + | ||
52 | out.writeInt(this.preamble); | 57 | out.writeInt(this.preamble); |
53 | 58 | ||
54 | // write time | 59 | // write time |
... | @@ -100,4 +105,10 @@ public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { | ... | @@ -100,4 +105,10 @@ public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { |
100 | } | 105 | } |
101 | context.close(); | 106 | context.close(); |
102 | } | 107 | } |
108 | + | ||
109 | + // Effectively same result as one generated by MessageToByteEncoder<InternalMessage> | ||
110 | + @Override | ||
111 | + public final boolean acceptOutboundMessage(Object msg) throws Exception { | ||
112 | + return msg instanceof InternalMessage; | ||
113 | + } | ||
103 | } | 114 | } | ... | ... |
... | @@ -41,7 +41,6 @@ import io.netty.channel.nio.NioEventLoopGroup; | ... | @@ -41,7 +41,6 @@ import io.netty.channel.nio.NioEventLoopGroup; |
41 | import io.netty.channel.socket.SocketChannel; | 41 | import io.netty.channel.socket.SocketChannel; |
42 | import io.netty.channel.socket.nio.NioServerSocketChannel; | 42 | import io.netty.channel.socket.nio.NioServerSocketChannel; |
43 | import io.netty.channel.socket.nio.NioSocketChannel; | 43 | import io.netty.channel.socket.nio.NioSocketChannel; |
44 | - | ||
45 | import org.apache.commons.pool.KeyedPoolableObjectFactory; | 44 | import org.apache.commons.pool.KeyedPoolableObjectFactory; |
46 | import org.apache.commons.pool.impl.GenericKeyedObjectPool; | 45 | import org.apache.commons.pool.impl.GenericKeyedObjectPool; |
47 | import org.apache.felix.scr.annotations.Activate; | 46 | import org.apache.felix.scr.annotations.Activate; |
... | @@ -383,7 +382,7 @@ public class NettyMessagingManager implements MessagingService { | ... | @@ -383,7 +382,7 @@ public class NettyMessagingManager implements MessagingService { |
383 | } | 382 | } |
384 | // Start the client. | 383 | // Start the client. |
385 | CompletableFuture<Channel> retFuture = new CompletableFuture<>(); | 384 | CompletableFuture<Channel> retFuture = new CompletableFuture<>(); |
386 | - ChannelFuture f = bootstrap.connect(ep.host().toString(), ep.port()); | 385 | + ChannelFuture f = bootstrap.connect(ep.host().toInetAddress(), ep.port()); |
387 | 386 | ||
388 | f.addListener(future -> { | 387 | f.addListener(future -> { |
389 | if (future.isSuccess()) { | 388 | if (future.isSuccess()) { |
... | @@ -491,10 +490,13 @@ public class NettyMessagingManager implements MessagingService { | ... | @@ -491,10 +490,13 @@ public class NettyMessagingManager implements MessagingService { |
491 | } | 490 | } |
492 | 491 | ||
493 | @ChannelHandler.Sharable | 492 | @ChannelHandler.Sharable |
494 | - private class InboundMessageDispatcher extends SimpleChannelInboundHandler<InternalMessage> { | 493 | + private class InboundMessageDispatcher extends SimpleChannelInboundHandler<Object> { |
494 | + // Effectively SimpleChannelInboundHandler<InternalMessage>, | ||
495 | + // had to specify <Object> to avoid Class Loader not being able to find some classes. | ||
495 | 496 | ||
496 | @Override | 497 | @Override |
497 | - protected void channelRead0(ChannelHandlerContext ctx, InternalMessage message) throws Exception { | 498 | + protected void channelRead0(ChannelHandlerContext ctx, Object rawMessage) throws Exception { |
499 | + InternalMessage message = (InternalMessage) rawMessage; | ||
498 | try { | 500 | try { |
499 | dispatchLocally(message); | 501 | dispatchLocally(message); |
500 | } catch (RejectedExecutionException e) { | 502 | } catch (RejectedExecutionException e) { |
... | @@ -507,7 +509,21 @@ public class NettyMessagingManager implements MessagingService { | ... | @@ -507,7 +509,21 @@ public class NettyMessagingManager implements MessagingService { |
507 | log.error("Exception inside channel handling pipeline.", cause); | 509 | log.error("Exception inside channel handling pipeline.", cause); |
508 | context.close(); | 510 | context.close(); |
509 | } | 511 | } |
512 | + | ||
513 | + /** | ||
514 | + * Returns true if the given message should be handled. | ||
515 | + * | ||
516 | + * @param msg inbound message | ||
517 | + * @return true if {@code msg} is {@link InternalMessage} instance. | ||
518 | + * | ||
519 | + * @see SimpleChannelInboundHandler#acceptInboundMessage(Object) | ||
520 | + */ | ||
521 | + @Override | ||
522 | + public final boolean acceptInboundMessage(Object msg) { | ||
523 | + return msg instanceof InternalMessage; | ||
524 | + } | ||
510 | } | 525 | } |
526 | + | ||
511 | private void dispatchLocally(InternalMessage message) throws IOException { | 527 | private void dispatchLocally(InternalMessage message) throws IOException { |
512 | if (message.preamble() != preamble) { | 528 | if (message.preamble() != preamble) { |
513 | log.debug("Received {} with invalid preamble from {}", message.type(), message.sender()); | 529 | log.debug("Received {} with invalid preamble from {}", message.type(), message.sender()); | ... | ... |
... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
16 | package org.onlab.packet; | 16 | package org.onlab.packet; |
17 | 17 | ||
18 | import java.net.InetAddress; | 18 | import java.net.InetAddress; |
19 | +import java.net.UnknownHostException; | ||
19 | import java.net.Inet4Address; | 20 | import java.net.Inet4Address; |
20 | import java.net.Inet6Address; | 21 | import java.net.Inet6Address; |
21 | import java.nio.ByteBuffer; | 22 | import java.nio.ByteBuffer; |
... | @@ -142,6 +143,20 @@ public class IpAddress implements Comparable<IpAddress> { | ... | @@ -142,6 +143,20 @@ public class IpAddress implements Comparable<IpAddress> { |
142 | } | 143 | } |
143 | 144 | ||
144 | /** | 145 | /** |
146 | + * Returns the IP address as InetAddress. | ||
147 | + * | ||
148 | + * @return InetAddress | ||
149 | + */ | ||
150 | + public InetAddress toInetAddress() { | ||
151 | + try { | ||
152 | + return InetAddress.getByAddress(octets); | ||
153 | + } catch (UnknownHostException e) { | ||
154 | + // Should never reach here | ||
155 | + return null; | ||
156 | + } | ||
157 | + } | ||
158 | + | ||
159 | + /** | ||
145 | * Computes the IP address byte length for a given IP version. | 160 | * Computes the IP address byte length for a given IP version. |
146 | * | 161 | * |
147 | * @param version the IP version | 162 | * @param version the IP version | ... | ... |
-
Please register or login to post a comment