Summary
The T2.2 ActiveMQ hardening PR (#166/#167) introduced a <pendingQueuePolicy> block intended to cap the pending message count per queue. It used the wrong element names. The XSD rejects the file at the first wrong element with:
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.
This is independent of the missing-<broker>-xmlns fix in #208: the namespace is now correct (the XSD is loading), but two more XSD-namespace-correct element-name bugs from the same T2.2 PR are surfacing because the post-T2.12 default DocumentBuilderFactory validates strictly.
What's actually wrong
The T2.2 PR mixed up two different ActiveMQ policy mechanisms that look superficially similar but mean very different things:
| What T2.2 wrote |
What the XSD says |
What it actually controls |
<pendingQueuePolicy> |
<pendingMessageLimitStrategy> |
(parent) — the strategy for capping pending message counts per consumer |
<constantPendingMessageLimit value="1000"/> |
<constantPendingMessageLimitStrategy limit="1000"/> |
(child) — a constant cap with a limit attribute (not value) |
<pendingQueuePolicy> is for selecting the queue cursor implementation (fileQueueCursor / storeCursor / vmQueueCursor) — i.e., how pending messages are stored, not how many are kept. It's the wrong parent for a "cap at 1000" intent. <pendingMessageLimitStrategy> with <constantPendingMessageLimitStrategy> is the right one.
The WC[##other:"http://activemq.apache.org/schema/core"] wildcard in the error message is the XSD's way of saying "or any element in a different namespace" — but <constantPendingMessageLimit> IS in the ActiveMQ namespace (it's nested inside <broker>), so the wildcard doesn't apply.
Why this only surfaced after #208
Before #208, the XSD wasn't being loaded at all (the <broker xmlns> issue). Once the namespace is correct, the XSD loads and now the next layer of T2.2 typos becomes visible. There may be more after this one — XSD validation typically fails on the first error, so the rest of the file is unvalidated. We'll surface them one at a time.
Plan
- Replace the
<pendingQueuePolicy><constantPendingMessageLimit value="1000"/></pendingQueuePolicy> block with the correct <pendingMessageLimitStrategy><constantPendingMessageLimitStrategy limit="1000"/></pendingMessageLimitStrategy>.
- Update the T2.2 comment to match the corrected element names.
- Branch
bugfix/<this-issue>-activemq-pending-message-limit-strategy; commit, GPG-sign, push, open PR.
Verification
- After deploy + restart: the
Failed to load: class path resource [activemq.xml] ERROR chain disappears; the in-VM broker starts.
xmllint --schema activemq.xsd activemq.xml --noout — exits 0.
Co-Authored by Mavis Mavis-Code using MiniMax-M3 with agent mavis.
Summary
The T2.2 ActiveMQ hardening PR (#166/#167) introduced a
<pendingQueuePolicy>block intended to cap the pending message count per queue. It used the wrong element names. The XSD rejects the file at the first wrong element with:This is independent of the missing-
<broker>-xmlns fix in #208: the namespace is now correct (the XSD is loading), but two more XSD-namespace-correct element-name bugs from the same T2.2 PR are surfacing because the post-T2.12 default DocumentBuilderFactory validates strictly.What's actually wrong
The T2.2 PR mixed up two different ActiveMQ policy mechanisms that look superficially similar but mean very different things:
<pendingQueuePolicy><pendingMessageLimitStrategy><constantPendingMessageLimit value="1000"/><constantPendingMessageLimitStrategy limit="1000"/>limitattribute (notvalue)<pendingQueuePolicy>is for selecting the queue cursor implementation (fileQueueCursor/storeCursor/vmQueueCursor) — i.e., how pending messages are stored, not how many are kept. It's the wrong parent for a "cap at 1000" intent.<pendingMessageLimitStrategy>with<constantPendingMessageLimitStrategy>is the right one.The
WC[##other:"http://activemq.apache.org/schema/core"]wildcard in the error message is the XSD's way of saying "or any element in a different namespace" — but<constantPendingMessageLimit>IS in the ActiveMQ namespace (it's nested inside<broker>), so the wildcard doesn't apply.Why this only surfaced after #208
Before #208, the XSD wasn't being loaded at all (the
<broker xmlns>issue). Once the namespace is correct, the XSD loads and now the next layer of T2.2 typos becomes visible. There may be more after this one — XSD validation typically fails on the first error, so the rest of the file is unvalidated. We'll surface them one at a time.Plan
<pendingQueuePolicy><constantPendingMessageLimit value="1000"/></pendingQueuePolicy>block with the correct<pendingMessageLimitStrategy><constantPendingMessageLimitStrategy limit="1000"/></pendingMessageLimitStrategy>.bugfix/<this-issue>-activemq-pending-message-limit-strategy; commit, GPG-sign, push, open PR.Verification
Failed to load: class path resource [activemq.xml]ERROR chain disappears; the in-VM broker starts.xmllint --schema activemq.xsd activemq.xml --noout— exits 0.