3

I have an activemq broker and I want to split its configuration into multiple files. I want to prepare a separate configuration file, which will be generated automatically and which will contain only definitions of queues.

File 1: activemq.xml

<beans ...>
  <broker ...>

  </broker>
</beans>

File 2: queues.xml

<beans ...>
  <broker ...>
    <destinations>
      <queue physicalName="q1"/>
    </destinations>
  </broker>
</beans>

I tried to use:

Spring import:

<import resource="queues.xml"/>

but got

ERROR: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.activemq.xbean.XBeanBrokerService#1' defined in class path resource [queues.xml]: Invocation of init method failed; nested exception is javax.management.InstanceAlreadyExistsException: org.apache.activemq:type=Broker,brokerName=localhost org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.activemq.xbean.XBeanBrokerService#1' defined in class path resource [queues.xml]: Invocation of init method failed; nested exception is javax.management.InstanceAlreadyExistsException: org.apache.activemq:type=Broker,brokerName=localhost

XInclude:

activemq.xml:

<beans ...
  xmlns:xi="http://www.w3.org/2001/XInclude"
>
  <broker ...>
    <xi:include href="queues.xml" parse="xml"/>
  </broker>

</beans>

but got

ERROR: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 142 in XML > document from class path resource [activemq.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 142; columnNumber: 45; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'xi:include'. org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 142 in XML document from class path resource [activemq.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 142; columnNumber: 45; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'xi:include'.

Xml entities activemq.xml

<!DOCTYPE beans [
<!ENTITY queues SYSTEM "queues.xml">
]>
<beans ...>
  <broker ...>
    &queues;
  </broker>
</beans>

but got

ERROR: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 28 in XML document from class path resource [activemq.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 28; columnNumber: 3; Element type "beans" must be declared. org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 28 in XML document from class path resource [activemq.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 28; columnNumber: 3; Element type "beans" must be declared.

Any ideas? Thanks in advance.

Vihar
  • 3,626
  • 2
  • 24
  • 47
rattaman
  • 506
  • 3
  • 15
  • I know now why the entity approach doesn't work. I use XSD based Spring configuration files for configuring ActiveMQ broker and when I add the entity definition, it switches to DTD validation instead of the XSD and this is why it complains about element beans not being defined. So the entity is being defined correctly, but the very usage of the DTD is problematic and so this solution is a dead way. – rattaman Feb 03 '15 at 16:46

4 Answers4

2

I asked at activemq forums and someone posted a solution there. Here is an answer solution at activemq forum. You can use XML entities, but you have to disable XML validation, so you have to start with: bin/activemq start 'xbean:conf/activemq.xml?validate=false'

rattaman
  • 506
  • 3
  • 15
1

For anyone trying to do this on Openshift's JBoss AMQ (+6.2) xPaaS images, there's a launch.sh script that needs to be modified in the container with the line:

exec $AMQ_HOME/bin/activemq console 'xbean:$AMQ_HOME/conf/activemq.xml?validate=false'

Note the use of 'console' rather than 'start'. As per the OP's desired to split the configuration, you can define multiple configuration files using the DOCTYPE file reference.

From there you can add custom authorization policy entries etc and mount this configuration with config maps.

If you do this, you'll likely break the readinessProbe.sh as well (it can't parse the XML elements you introduce like '&destinationpolicy;'). Fortunately this script is really only interested in the ports (which it could get from ENV!) so a quick solution/hack is to strip away the naughty lines before parsing the XML.

ted-k42
  • 356
  • 3
  • 12
0

these really are spring configuration problems

  • javax.management.InstanceAlreadyExistsException is caused when you try to create 2 beans with same name,so in your configuration please check if you are trying to create 2 beans with identical names.
  • The matching wildcard is strict, but no declaration can be found for element 'xi:include' this error occurs when ddo not have your namespace configured(i.e 'xi' is not a configured namespace for this spring configuration, you need to explicitly define it)
  • SAX parse exception is generally thrown when your xml is not well formed or it doesnt adhere to particular DTD

hope this helps!

Good luck!

Vihar
  • 3,626
  • 2
  • 24
  • 47
  • Thank you for your answer. I am aware of the meaning of those error messages, what I don't know is to how to amend them or find another way to do what I want to do. InstanceAlreadyExists - is there a way to have two broker elements apply to the same broker? xs:include - I defined the namespace, but apparently the XML parser doesn't support the XInclude (this is a dead end, as I don't want to add additional dependencies). SAX parse - from what I read, it should be ok, but I don't have any exeprience with defining XML entities, so maybe someone could tell me, what I'm doing wrong. – rattaman Jan 14 '15 at 10:11
  • for this you need to post entire code ,without it we cant sense the problem from here – Vihar Jan 14 '15 at 10:18
  • @Vihar, why can't you see the problem based on what the OP's already posted? It seems pretty clear to me... – Tim Jan 14 '15 at 22:47
0

I've wanted to do this myself but haven't yet found time to try it, so I'm hoping you'll find a way to make it work.

The only idea I've come up with is to try to use Spring's inheritance feature to declare a superclass bean with the common elements/attributes and a subclass bean (with parent=superClassBeanID) that provides the ones that aren't standard. Note that you don't need multiple files for this approach; define both beans in the same file so you don't have to worry about that particular pain point.

Even if it works, this approach wouldn't let you override attributes and elements below the first level, but it might be good enough for what you need. And as I said, I've made no attempt to test this, so it might fail miserably.

Tim
  • 2,027
  • 15
  • 24
  • Well, I need to use the existing configuration schema which uses custom elements and so I don't think it will work. Thank you for your answer. – rattaman Feb 03 '15 at 16:50
  • Too bad; I kept checking back to see if you'd posted a solution, hoping you'd found a way to get it to work so I could do the same thing. – Tim Feb 03 '15 at 17:08
  • I asked at activemq forums and someone posted a solution there. Here is an answer. [link](http://activemq.2283324.n4.nabble.com/Split-ActiveMQ-broker-configuration-into-multiple-files-tp4690947.htm) You can use XML entities, but you have to disable XML validation, so you have to start with: `bin/activemq start 'xbean:conf/activemq.xml?validate=false'` – rattaman Feb 10 '15 at 14:57