[
https://issues.apache.org/jira/browse/AMQ-8346?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jean-Baptiste Onofré updated AMQ-8346:
--------------------------------------
Fix Version/s: (was: 5.16.3)
5.17.0
5.16.4
> [AMQ 5.16.1] SubQueueSelectorCacheBrokerPlugin throws Unable to read
> persisted selector cache...it will be ignored! error
> -------------------------------------------------------------------------------------------------------------------------
>
> Key: AMQ-8346
> URL: https://issues.apache.org/jira/browse/AMQ-8346
> Project: ActiveMQ
> Issue Type: Bug
> Components: Broker, Plugin
> Affects Versions: 5.16.1, 5.16.2
> Environment: {color:#172b4d}Tested/replicated in Windows Server 2012
> R2 but I suspect it is non-OS dependent{color}
> Reporter: Adrian Lulea
> Priority: Major
> Fix For: 5.17.0, 5.16.4
>
> Attachments: activemq.xml
>
>
> 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:+
> {panel:title=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;
> [L{color:#de350b}java.util.concurrent.ConcurrentHashMap$Segment{color};
> jvm 1 | at
> org.apache.activemq.plugin.SubQueueSelectorCacheBroker$SubSelectorClassObjectInputStream.resolveClass(SubQueueSelectorCacheBroker.java:376)
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1886){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.readArray(ObjectInputStream.java:1948){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1588){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:566){color}
> jvm 1 | at
> java.base/{color:#de350b}java.util.concurrent.ConcurrentHashMap{color}.readObject(ConcurrentHashMap.java:1448)
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.lang.reflect.Method.invoke(Method.java:566){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1160){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2216){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430){color}
> 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)
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.addInterceptors(BrokerService.java:2514){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.createBroker(BrokerService.java:2374){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.getBroker(BrokerService.java:1054){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.getAdminConnectionContext(BrokerService.java:2645){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.startVirtualConsumerDestinations(BrokerService.java:2806){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.startDestinations(BrokerService.java:2636){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.doStartBroker(BrokerService.java:748){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.startBroker(BrokerService.java:742){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerService.start(BrokerService.java:645){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.xbean.XBeanBrokerService.afterPropertiesSet(XBeanBrokerService.java:73){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.lang.reflect.Method.invoke(Method.java:566){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1{color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1685){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1615){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867){color}
> {color:#c1c7d0}jvm 1 | at
> org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:64){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:52){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.xbean.XBeanBrokerFactory$1.<init>(XBeanBrokerFactory.java:104){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:54){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.console.command.StartCommand.runTask(StartCommand.java:87){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:63){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.console.command.ShellCommand.runTask(ShellCommand.java:154){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:63){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.console.command.ShellCommand.main(ShellCommand.java:104){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.lang.reflect.Method.invoke(Method.java:566){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.console.Main.runTaskClass(Main.java:262){color}
> {color:#c1c7d0}jvm 1 | at
> org.apache.activemq.console.Main.main(Main.java:115){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.lang.reflect.Method.invoke(Method.java:566){color}
> {color:#c1c7d0}jvm 1 | at
> org.tanukisoftware.wrapper.WrapperSimpleApp.run(WrapperSimpleApp.java:240){color}
> {color:#c1c7d0}jvm 1 | at
> java.base/java.lang.Thread.run(Thread.java:834){color}
> {color:#c1c7d0}jvm 1 | INFO | Apache ActiveMQ 5.16.1 (localhost,
> ID:_<somehostnameweblurred>_-57948-1626180862103-0:1) is starting{color}
> {panel}
> {panel:title=Commit that might have introduced the behavior}
> During my research I have stumbled upon this commit
> [here|https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.mail-archive.com%2Fcommits%40activemq.apache.org%2Fmsg53657.html&data=04%7C01%7CAdrian.Lulea%40finastra.com%7C8f204c58c6284a703be408d94dd1f1ba%7C0b9b90da3fe1457ab340f1b67e1024fb%7C0%7C0%7C637626386377582467%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2Fn6tM1opMbc4Buia6r%2FrTVstigNd5AsffkaFhJVQrmA%3D&reserved=0]
>
> ([AMQ-7438|https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FAMQ-7438&data=04%7C01%7CAdrian.Lulea%40finastra.com%7C8f204c58c6284a703be408d94dd1f1ba%7C0b9b90da3fe1457ab340f1b67e1024fb%7C0%7C0%7C637626386377592470%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=8qMaS%2BQ0XN%2FSCwxJu71oJamCagU4YAlDD1tPVpwKqro%3D&reserved=0])
> 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 {
> + if (!(desc.getName().equals("java.lang.String") \|\|
> *desc.getName().startsWith("java.util.")*)) {
> + 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.*")|
>
> {panel}
> As far as replication steps are concerned, what we do is:
> # Configure AMQ to have a set of Virtual Topics (attached _activemq.xml_)
> # Start AMQ
> # 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_
> # Stop AMQ
> # Start AMQ again
> # Callstack from above shows up
> NOTE: sometime between steps 1 and 5 the file mentioned in
> _SubQueueSelectorCacheBrokerPlugin_ setup gets generated:
> {panel:title=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>
> {panel}
> NOTE: this does *not* replicate in *5.15.9*
> Kind regards,
> Adrian L.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)