Summary
The T2.2 ActiveMQ hardening PR (#166/#167) reformatted the <broker> element in system/Tools/jetty/defaults/etc/activemq/activemq.xml onto multiple lines and accidentally dropped the xmlns="http://activemq.apache.org/schema/core" attribute that was on the element. Without that attribute, <broker> and its children fall into the default http://www.springframework.org/schema/beans namespace, and the Xerces XSD validator (correctly) rejects the file with:
SAXParseException; lineNumber: 32; columnNumber: 44; cvc-complex-type.2.4.a:
Invalid content was found starting with element
'{"http://www.springframework.org/schema/beans":broker}'.
One of '{"http://www.springframework.org/schema/beans":description, ...
"http://www.springframework.org/schema/beans":bean, ...}' is expected.
The XSD validator is doing the right thing — <broker> is declared in activemq.xsd under the http://activemq.apache.org/schema/core target namespace, not under the Spring beans namespace. The error first appears at 12:38:00 on 2026-09-08 (the first startup with the merged T2.12 PR's JAXP hardening in effect, which made the parser strict enough to actually catch this), and repeats 157+ times in jetty/base/logs/server.log — every JMS listener that tries to connect to the in-VM broker fails to refresh its connection.
Why it manifested now (and not earlier)
Before T2.12, the default DocumentBuilderFactory was the bare Xerces default, which loads XSDs but applies them with the parser's default tolerance for elementFormDefault="qualified" mismatches in the root document. The T2.12 PR's PSDocumentBuilderFactoryImpl still doesn't change the namespace behaviour, but the parser is now in a state where the missing xmlns shows up as a hard validation error. Pre-T2.12, the file likely loaded with a warning that the rest of the system swallowed. Either way, the activemq.xml is genuinely malformed without that attribute and the fix is to put it back.
The diff that introduced the regression
Pre-T2.2 (working):
<broker useShutdownHook="false" useJmx="false" persistent="true"
deleteAllMessagesOnStartup="true"
xmlns="http://activemq.apache.org/schema/core"
brokerName="localhost"
dataDirectory="data/activemq-data">
Post-T2.2 (broken — xmlns dropped during reformat):
<broker
useShutdownHook="false"
useJmx="false"
persistent="true"
deleteAllMessagesOnStartup="false"
advisorySupport="false"
brokerName="localhost"
dataDirectory="data/activemq-data">
The xmlns="http://activemq.apache.org/schema/core" is the only thing that puts <broker> and its children (destinationPolicy, plugins, transportConnectors, etc.) into the ActiveMQ namespace where the XSD expects them.
Plan
- Restore the
xmlns="http://activemq.apache.org/schema/core" attribute on the <broker> element.
- Add a short comment on the line explaining that the xmlns is required for the XSD to validate the broker block (so a future reformat doesn't drop it again).
- Branch
bugfix/<this-issue>-activemq-broker-xmlns; commit, GPG-sign, push, open PR.
Verification
python3 -c "import xml.etree.ElementTree as ET; ET.parse('.../activemq.xml')" — well-formed (it always was).
- After deploy + restart: the
Failed to load: class path resource [activemq.xml] ERROR chain disappears from server.log. The PERCUSSION.EMAIL and PERCUSSION.PUBLISHING JMS listeners connect cleanly.
xmllint --schema activemq.xsd activemq.xml --noout (if xmllint is available) — exits 0.
Co-Authored by Mavis Mavis-Code using MiniMax-M3 with agent mavis.
Summary
The T2.2 ActiveMQ hardening PR (#166/#167) reformatted the
<broker>element insystem/Tools/jetty/defaults/etc/activemq/activemq.xmlonto multiple lines and accidentally dropped thexmlns="http://activemq.apache.org/schema/core"attribute that was on the element. Without that attribute,<broker>and its children fall into the defaulthttp://www.springframework.org/schema/beansnamespace, and the Xerces XSD validator (correctly) rejects the file with:The XSD validator is doing the right thing —
<broker>is declared inactivemq.xsdunder thehttp://activemq.apache.org/schema/coretarget namespace, not under the Spring beans namespace. The error first appears at 12:38:00 on 2026-09-08 (the first startup with the merged T2.12 PR's JAXP hardening in effect, which made the parser strict enough to actually catch this), and repeats 157+ times injetty/base/logs/server.log— every JMS listener that tries to connect to the in-VM broker fails to refresh its connection.Why it manifested now (and not earlier)
Before T2.12, the default
DocumentBuilderFactorywas the bare Xerces default, which loads XSDs but applies them with the parser's default tolerance forelementFormDefault="qualified"mismatches in the root document. The T2.12 PR'sPSDocumentBuilderFactoryImplstill doesn't change the namespace behaviour, but the parser is now in a state where the missingxmlnsshows up as a hard validation error. Pre-T2.12, the file likely loaded with a warning that the rest of the system swallowed. Either way, the activemq.xml is genuinely malformed without that attribute and the fix is to put it back.The diff that introduced the regression
Pre-T2.2 (working):
Post-T2.2 (broken —
xmlnsdropped during reformat):The
xmlns="http://activemq.apache.org/schema/core"is the only thing that puts<broker>and its children (destinationPolicy, plugins, transportConnectors, etc.) into the ActiveMQ namespace where the XSD expects them.Plan
xmlns="http://activemq.apache.org/schema/core"attribute on the<broker>element.bugfix/<this-issue>-activemq-broker-xmlns; commit, GPG-sign, push, open PR.Verification
python3 -c "import xml.etree.ElementTree as ET; ET.parse('.../activemq.xml')"— well-formed (it always was).Failed to load: class path resource [activemq.xml]ERROR chain disappears fromserver.log. ThePERCUSSION.EMAILandPERCUSSION.PUBLISHINGJMS listeners connect cleanly.xmllint --schema activemq.xsd activemq.xml --noout(if xmllint is available) — exits 0.