[ https://issues.apache.org/jira/browse/AMQ-5298?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14080100#comment-14080100 ]
Timothy Bish commented on AMQ-5298: ----------------------------------- The test to demonstrate this is a modification of testRetainedMessage in MQTTTest.java {code} @Test(timeout = 120 * 1000) public void testRetainedMessageOnVirtualTopic() throws Exception { MQTT mqtt = createMQTTConnection(); mqtt.setKeepAlive((short) 2); final String RETAIN = "RETAIN"; final String TOPICA = "VirtualTopic/TopicA"; final String[] clientIds = { null, "foo", "durable" }; for (String clientId : clientIds) { LOG.info("Running test loop with Client ID: {}", clientId); mqtt.setClientId(clientId); mqtt.setCleanSession(!"durable".equals(clientId)); BlockingConnection connection = mqtt.blockingConnection(); connection.connect(); // set retained message and check connection.publish(TOPICA, RETAIN.getBytes(), QoS.EXACTLY_ONCE, true); connection.subscribe(new Topic[]{new Topic(TOPICA, QoS.AT_LEAST_ONCE)}); Message msg = connection.receive(5000, TimeUnit.MILLISECONDS); assertNotNull("No retained message for " + clientId, msg); assertEquals(RETAIN, new String(msg.getPayload())); msg.ack(); assertNull(connection.receive(500, TimeUnit.MILLISECONDS)); // test duplicate subscription connection.subscribe(new Topic[]{new Topic(TOPICA, QoS.AT_LEAST_ONCE)}); msg = connection.receive(15000, TimeUnit.MILLISECONDS); assertNotNull("No retained message on duplicate subscription for " + clientId, msg); assertEquals(RETAIN, new String(msg.getPayload())); msg.ack(); assertNull(connection.receive(500, TimeUnit.MILLISECONDS)); connection.unsubscribe(new String[]{"TopicA"}); // clear retained message and check that we don't receive it connection.publish(TOPICA, "".getBytes(), QoS.AT_MOST_ONCE, true); connection.subscribe(new Topic[]{new Topic(TOPICA, QoS.AT_LEAST_ONCE)}); msg = connection.receive(500, TimeUnit.MILLISECONDS); assertNull("Retained message not cleared for " + clientId, msg); connection.unsubscribe(new String[]{"TopicA"}); // set retained message again and check connection.publish(TOPICA, RETAIN.getBytes(), QoS.EXACTLY_ONCE, true); connection.subscribe(new Topic[]{new Topic(TOPICA, QoS.AT_LEAST_ONCE)}); msg = connection.receive(5000, TimeUnit.MILLISECONDS); assertNotNull("No reset retained message for " + clientId, msg); assertEquals(RETAIN, new String(msg.getPayload())); msg.ack(); assertNull(connection.receive(500, TimeUnit.MILLISECONDS)); // re-connect and check connection.disconnect(); connection = mqtt.blockingConnection(); connection.connect(); connection.subscribe(new Topic[]{new Topic(TOPICA, QoS.AT_LEAST_ONCE)}); msg = connection.receive(5000, TimeUnit.MILLISECONDS); assertNotNull("No reset retained message for " + clientId, msg); assertEquals(RETAIN, new String(msg.getPayload())); msg.ack(); assertNull(connection.receive(500, TimeUnit.MILLISECONDS)); connection.unsubscribe(new String[]{"TopicA"}); connection.disconnect(); } } {code} > MQTT Transport can generate class cast exception when subscription is to a > Virtual Topic > ---------------------------------------------------------------------------------------- > > Key: AMQ-5298 > URL: https://issues.apache.org/jira/browse/AMQ-5298 > Project: ActiveMQ > Issue Type: Bug > Components: MQTT > Affects Versions: 5.10.0 > Reporter: Timothy Bish > Fix For: 5.11.0 > > > When a client subscribes to a Virtual Topic and sends a duplicate > subscription request the method that resends the old retained messages tries > to cast the destination from the TopicRegion is finds to a Topic but in this > case it would be a VirtualTopicIntercepter and an exception is thrown > disconnecting the client. -- This message was sent by Atlassian JIRA (v6.2#6252)