Uploaded image for project: 'ActiveMQ Classic'
  1. ActiveMQ Classic
  2. AMQ-8346

[AMQ 5.16.1] SubQueueSelectorCacheBrokerPlugin throws Unable to read persisted selector cache...it will be ignored! error

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 5.16.1, 5.16.2
    • 5.16.3, 5.17.0
    • Broker, Plugin
    • None
    • Tested/replicated in Windows Server 2012 R2 but I suspect it is non-OS dependent

    • Regression

    Description

      Hello,

      We have been using SubQueueSelectorCacheBrokerPlugin plugin for a while now and starting 5.16.0 we are getting an exception (Unauthorized deserialization attempt) and the Unable to read persisted selector cache...it will be ignored! error is displayed in the Broker's console/logs.

      AMQ is able to start and seems to be working OK despite this error. Is this expected?

      We have a client that is concerned about this error and we need to understand if there are any functional implications.

      We suspect that lower performance on Virtual Topics functionality (which seems to be related to the plugin) might be one technical implication but we are not sure. Can you please clarify this as well?

      Below information I was able to gather while trying to figure out the issue:

      Call stack from AMQ Broker logs

      jvm 1    | ERROR | Unable to read persisted selector cache...it will be ignored!

      jvm 1    | java.io.InvalidClassException: Unauthorized deserialization attempt; [Ljava.util.concurrent.ConcurrentHashMap$Segment;

      jvm 1    |      at org.apache.activemq.plugin.SubQueueSelectorCacheBroker$SubSelectorClassObjectInputStream.resolveClass(SubQueueSelectorCacheBroker.java:376)

      jvm 1    |      at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1886)

      jvm 1    |      at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)

      jvm 1    |      at java.base/java.io.ObjectInputStream.readArray(ObjectInputStream.java:1948)

      jvm 1    |      at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1588)

      jvm 1    |      at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)

      jvm 1    |      at java.base/java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:566)

      jvm 1    |      at java.base/java.util.concurrent.ConcurrentHashMap.readObject(ConcurrentHashMap.java:1448)

      jvm 1    |      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

      jvm 1    |      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

      jvm 1    |      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

      jvm 1    |      at java.base/java.lang.reflect.Method.invoke(Method.java:566)

      jvm 1    |      at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1160)

      jvm 1    |      at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2216)

      jvm 1    |      at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)

      jvm 1    |      at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)

      jvm 1    |      at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)

      jvm 1    |      at org.apache.activemq.plugin.SubQueueSelectorCacheBroker.readCache(SubQueueSelectorCacheBroker.java:201)

      jvm 1    |      at org.apache.activemq.plugin.SubQueueSelectorCacheBroker.<init>(SubQueueSelectorCacheBroker.java:93)

      jvm 1    |      at org.apache.activemq.plugin.SubQueueSelectorCacheBrokerPlugin.installPlugin(SubQueueSelectorCacheBrokerPlugin.java:46)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.addInterceptors(BrokerService.java:2514)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.createBroker(BrokerService.java:2374)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.getBroker(BrokerService.java:1054)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.getAdminConnectionContext(BrokerService.java:2645)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.startVirtualConsumerDestinations(BrokerService.java:2806)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.startDestinations(BrokerService.java:2636)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.doStartBroker(BrokerService.java:748)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.startBroker(BrokerService.java:742)

      jvm 1    |      at org.apache.activemq.broker.BrokerService.start(BrokerService.java:645)

      jvm 1    |      at org.apache.activemq.xbean.XBeanBrokerService.afterPropertiesSet(XBeanBrokerService.java:73)

      jvm 1    |      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

      jvm 1    |      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

      jvm 1    |      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

      jvm 1    |      at java.base/java.lang.reflect.Method.invoke(Method.java:566)

      jvm 1    |      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1

      jvm 1    |      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1685)

      jvm 1    |      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1615)

      jvm 1    |      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)

      jvm 1    |      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)

      jvm 1    |      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)

      jvm 1    |      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)

      jvm 1    |      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)

      jvm 1    |      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)

      jvm 1    |      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756)

      jvm 1    |      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)

      jvm 1    |      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)

      jvm 1    |      at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:64)

      jvm 1    |      at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:52)

      jvm 1    |      at org.apache.activemq.xbean.XBeanBrokerFactory$1.<init>(XBeanBrokerFactory.java:104)

      jvm 1    |      at org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104)

      jvm 1    |      at org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67)

      jvm 1    |      at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71)

      jvm 1    |      at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:54)

      jvm 1    |      at org.apache.activemq.console.command.StartCommand.runTask(StartCommand.java:87)

      jvm 1    |      at org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:63)

      jvm 1    |      at org.apache.activemq.console.command.ShellCommand.runTask(ShellCommand.java:154)

      jvm 1    |      at org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:63)

      jvm 1    |      at org.apache.activemq.console.command.ShellCommand.main(ShellCommand.java:104)

      jvm 1    |      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

      jvm 1    |      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

      jvm 1    |      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

      jvm 1    |      at java.base/java.lang.reflect.Method.invoke(Method.java:566)

      jvm 1    |      at org.apache.activemq.console.Main.runTaskClass(Main.java:262)

      jvm 1    |      at org.apache.activemq.console.Main.main(Main.java:115)

      jvm 1    |      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

      jvm 1    |      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

      jvm 1    |      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

      jvm 1    |      at java.base/java.lang.reflect.Method.invoke(Method.java:566)

      jvm 1    |      at org.tanukisoftware.wrapper.WrapperSimpleApp.run(WrapperSimpleApp.java:240)

      jvm 1    |      at java.base/java.lang.Thread.run(Thread.java:834)

      jvm 1    |  INFO | Apache ActiveMQ 5.16.1 (localhost, ID:<somehostnameweblurred>-57948-1626180862103-0:1) is starting

      Commit that might have introduced the behavior

      During my research I have stumbled upon this commit here (AMQ-7438) and I think it is related / caused by the changes done below:

      broker/src/main/java/org/apache/activemq/plugin/SubQueueSelectorCacheBroker.java
      +        @Override
      +        protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException
      Unknown macro: {+            if (!(desc.getName().equals("java.lang.String") || *desc.getName().startsWith("java.util.")*))
      Unknown macro: { +                throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName()); +            }
      +            return super.resolveClass(desc);+        }

      Disclaimer: My java skills are quite rusty

      I think that the condition may need to be adjusted because the desc showing up in the callstack (;[Ljava.util.concurrent.ConcurrentHashMap$Segment;) seems to start with java.util. if you exempt the trails before and maybe the check should take that into account as well:

      String Condition
      ;[L*java.util.*concurrent.ConcurrentHashMap$Segment; desc.getName().startsWith("java.util.")

       

      As far as replication steps are concerned, what we do is:

      1. Configure AMQ to have a set of Virtual Topics (attached  activemq.xml)
      2. Start AMQ
      3. Start at least 1 consumer for at least one of the Virtual Topics (we have 1 consumer that connects to all of them - this is customizable, we can have it connect to a subset of them) – that match the virtualTopic setup from activemq.xml
      4. Stop AMQ
      5. Start AMQ again
      6. Callstack from above shows up

      NOTE: sometime between steps 1 and 5 the file mentioned in SubQueueSelectorCacheBrokerPlugin setup gets generated:

      activemq.xml snippet

      <plugins>
         <bean xmlns="http://www.springframework.org/schema/beans"
                           id="subQueueSelectorCacheBroker"
                       class="org.apache.activemq.plugin.SubQueueSelectorCacheBrokerPlugin">
            <property name="persistFile" value="file:${activemq.data}/selectorcache.dat"/>
         </bean>
      </plugins>

      NOTE: this does not replicate in 5.15.9

      Kind regards,

      Adrian L.

      Attachments

        1. activemq.xml
          8 kB
          Adrian Lulea

        Activity

          People

            jbonofre Jean-Baptiste Onofré
            adrlulea Adrian Lulea
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: