fix(activemq): restore xmlns on <broker> and correct pendingMessageLimitStrategy structure - #211
Merged
natechadwick merged 1 commit intoSep 8, 2026
Conversation
After PR #208/#209 restored the xmlns on <broker> (so the XSD loads), the post-T2.12 default DocumentBuilderFactory keeps validating and catches the next layer of T2.2 element-name bugs in the same file: SAXParseException; lineNumber: 61; columnNumber: 68; cvc-complex-type.2.4.a: Invalid content was found starting with element '{"http://activemq.apache.org/schema/core":constantPendingMessageLimit}'. One of '{"http://activemq.apache.org/schema/core":fileQueueCursor, "http://activemq.apache.org/schema/core":storeCursor, "http://activemq.apache.org/schema/core":vmQueueCursor, WC[##other:"http://activemq.apache.org/schema/core"]}' is expected. The T2.2 PR mixed up two superficially similar ActiveMQ policy mechanisms that do very different things: T2.2 wrote XSD expects What it controls --------------- ---------------------- ------------------- <pendingQueuePolicy> <pendingMessageLimitStrategy> (parent) cap on count per consumer <constantPending- <constantPending- (child) constant MessageLimit MessageLimitStrategy cap with 'limit' value="1000"/> limit="1000"/> attribute <pendingQueuePolicy> selects the queue cursor (fileQueueCursor / storeCursor / vmQueueCursor) -- i.e., how pending messages are *stored*, not how many are kept. The XSD's <xs:any namespace='##other'/> wildcard on that element does NOT allow <constantPendingMessageLimit> because the element is in the same ActiveMQ namespace, not a different one. Hence "Invalid content was found starting with element constantPendingMessageLimit." Fix: replace the wrong parent/child pair with the correct XSD-valid <pendingMessageLimitStrategy>/<constantPendingMessageLimitStrategy> pair, and use the `limit` attribute (not `value`). The "cap pending message count per queue" intent of the original T2.2 block is preserved. This PR also pulls in the #208 fix (xmlns on <broker> + the explanatory comment). The #208 PR (#209) is still open and is superseded by this one; it can be closed without merging. Refs #208, #210 > Co-Authored by Mavis Mavis-Code using MiniMax-M3 with agent mavis.
This was referenced Sep 8, 2026
Closed
natechadwick
approved these changes
Sep 8, 2026
natechadwick
deleted the
bugfix/210-activemq-pending-message-limit-strategy
branch
September 8, 2026 18:22
natechadwick
pushed a commit
that referenced
this pull request
Sep 8, 2026
…in + ConnectionFactory (#213) * fix(activemq): two XSD-namespace-correct element bugs from T2.2 PR #166 After PR #208/#209 restored the xmlns on <broker> (so the XSD loads), the post-T2.12 default DocumentBuilderFactory keeps validating and catches the next layer of T2.2 element-name bugs in the same file: SAXParseException; lineNumber: 61; columnNumber: 68; cvc-complex-type.2.4.a: Invalid content was found starting with element '{"http://activemq.apache.org/schema/core":constantPendingMessageLimit}'. One of '{"http://activemq.apache.org/schema/core":fileQueueCursor, "http://activemq.apache.org/schema/core":storeCursor, "http://activemq.apache.org/schema/core":vmQueueCursor, WC[##other:"http://activemq.apache.org/schema/core"]}' is expected. The T2.2 PR mixed up two superficially similar ActiveMQ policy mechanisms that do very different things: T2.2 wrote XSD expects What it controls --------------- ---------------------- ------------------- <pendingQueuePolicy> <pendingMessageLimitStrategy> (parent) cap on count per consumer <constantPending- <constantPending- (child) constant MessageLimit MessageLimitStrategy cap with 'limit' value="1000"/> limit="1000"/> attribute <pendingQueuePolicy> selects the queue cursor (fileQueueCursor / storeCursor / vmQueueCursor) -- i.e., how pending messages are *stored*, not how many are kept. The XSD's <xs:any namespace='##other'/> wildcard on that element does NOT allow <constantPendingMessageLimit> because the element is in the same ActiveMQ namespace, not a different one. Hence "Invalid content was found starting with element constantPendingMessageLimit." Fix: replace the wrong parent/child pair with the correct XSD-valid <pendingMessageLimitStrategy>/<constantPendingMessageLimitStrategy> pair, and use the `limit` attribute (not `value`). The "cap pending message count per queue" intent of the original T2.2 block is preserved. This PR also pulls in the #208 fix (xmlns on <broker> + the explanatory comment). The #208 PR (#209) is still open and is superseded by this one; it can be closed without merging. Refs #208, #210 > Co-Authored by Mavis Mavis-Code using MiniMax-M3 with agent mavis. * fix(activemq): add in-VM user credentials to simpleAuthenticationPlugin + ConnectionFactory The T2.2 ActiveMQ hardening PR (#166/#167) configured `<simpleAuthenticationPlugin anonymousAccessAllowed="false"/>` but did not add any users and did not update the in-VM ActiveMQConnectionFactory in perc-mq.xml / ear/WEB-INF/jetty-env.xml to provide credentials. The in-VM transport (vm://localhost) sends anonymous (no user / no password) connections by default, so every JMS listener (PERCUSSION.EMAIL, PERCUSSION.PUBLISHING, PERCUSSION.NOTIFICATIONS) gets `User name [null] or password is invalid` and retries in a 5-second FixedBackOff loop (currentAttempts climbs to 30+ within a minute). Fix has three parts: 1. activemq.xml: add a single 'rhythmyx' user to the simpleAuthenticationPlugin via the userPasswords and userGroups attributes. userGroups 'users,admins' grants both consume/produce on queues/topics and admin operations; the default ActiveMQ SimpleAuthorizationMap is permissive (no <simpleAuthorizationMap> is required to grant access to PERCUSSION.* queues). anonymousAccessAllowed stays 'false' so the security posture is preserved for any future network listener. 2. perc-mq.xml: configure the Jetty-bound ActiveMQConnectionFactory (java:/ConnectionFactory) with setUserName / setPassword via Jetty's <Property> indirection. Operators can override the default at install time via -Dactivemq.username=... / -Dactivemq.password=... 3. ear/WEB-INF/jetty-env.xml: same change for the webapp-scoped ActiveMQConnectionFactory (jms/ConnectionFactory). Default credentials are 'rhythmyx' / 'rhythmyx' (placeholder, not a secret). Operators opening a network listener (adding a <transportConnector>) MUST change the password and add a per-listener user. The comment in activemq.xml points at this requirement. This PR is built on top of #211 (the activemq.xml XSD-validity fixes); once both merge, the broker should start cleanly, the in-VM connection should authenticate, and the JMS listeners should reach steady state without retries. Refs #212 > Co-Authored by Mavis Mavis-Code using MiniMax-M3 with agent mavis.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two T2.2 ActiveMQ hardening regressions in
system/Tools/jetty/defaults/etc/activemq/activemq.xml, both surfaced by the post-T2.12 strict XSD validation:xmlnson<broker>(the fix(activemq): restore xmlns on <broker> element (regression from T2.2 PR #166 reformat) #208 fix — supersedes the still-open fix(activemq): restore xmlns on <broker> element (regression from T2.2 PR #166 reformat) #209 PR)After the
#208xmlns fix lands, XSD validation loadsactivemq.xsdand then immediately rejects the next layer of T2.2 element-name bugs at line 61:What's actually wrong (the #210 piece)
The T2.2 PR mixed up two ActiveMQ policy mechanisms that look similar but mean very different things:
<pendingQueuePolicy><pendingMessageLimitStrategy><constantPendingMessageLimit value="1000"/><constantPendingMessageLimitStrategy limit="1000"/>limitattribute (notvalue)<pendingQueuePolicy>is for selecting the queue cursor (how pending messages are stored:fileQueueCursor/storeCursor/vmQueueCursor). It is not a cap on count. The XSD's<xs:any namespace='##other'/>wildcard on that element does not allow<constantPendingMessageLimit>because the element is in the same ActiveMQ namespace, not a different one.The "cap pending message count per queue" intent of the original T2.2 block is preserved with the corrected elements.
Diff
Why bundled into one PR
The
#208xmlns fix and the#210element-name fix are both in the same file, both surface under the same root cause (post-T2.12 strict XSD validation), and were originally written as a T2.2 hardening followup. The#208PR (#209) is still open and unmerged; this PR includes that change and supersedes it. After this lands,#209can be closed without merging.Why this only surfaced now (and not earlier)
The T2.12 hardening PR set
FEATURE_SECURE_PROCESSING=trueon the defaultDocumentBuilderFactory, which makes Xerces more aggressive about loading and applying schema URLs fromxsi:schemaLocation. Pre-T2.12, the parser was looser aboutelementFormDefault='qualified'mismatches and silently ignored unreferenced elements; post-T2.12, every element in<broker>is validated againstactivemq.xsdand any typo becomes a hard failure. The activemq.xml has been technically malformed since the T2.2 PR was merged, but the parser only just got strict enough to surface the bug.There may be more layers of T2.2 typos after this one — XSD validation typically fails on the first error, so the rest of the file is unvalidated. We'll find out on the next restart.
Verification
python3 -c "import xml.etree.ElementTree as ET; ET.parse('...activemq.xml')"— well-formed.<broker>is inhttp://activemq.apache.org/schema/core;<pendingMessageLimitStrategy>and<constantPendingMessageLimitStrategy>are too.Failed to load: class path resource [activemq.xml]ERROR chain disappears fromserver.log. The in-VM broker starts;PERCUSSION.EMAIL,PERCUSSION.PUBLISHING,PERCUSSION.NOTIFICATIONSJMS listeners connect cleanly.xmllint --schema activemq.xsd activemq.xml --noout(if xmllint is available) — exits 0.Refs #208, #210