I am sending JAXB Object to Rabbit MQ via Java.
JAXBContext jaxbContext = JAXBContext.newInstance(MyDTO.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
java.io.StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(deliveryrequest, sw);
ConnectionFactory factory = new ConnectionFactory() ;
//TODO change the hardcoding to the properties file
factory.setHost("rabbitmq.host.net");
factory.setUsername("user");
factory.setPassword("pass");
Channel channel ;
Connection connection;
Map<String, Object> args = new HashMap<String, Object>();
String haPolicyValue = "all";
args.put("x-ha-policy", haPolicyValue);
connection = factory.newConnection();
channel = connection.createChannel();
//TODO change the hardcoding to the properties file
channel.queueDeclare("upload.com.some.queue", true, false, false, args);
//TODO change the hardcoding to the properties file
channel.basicPublish("com.some.exchange", "someroutingKey",
new AMQP.BasicProperties.Builder().contentType("text/plain")
.deliveryMode(2).priority(1).userId("guest").build(),
sw.toString().getBytes());
I am using Camel in different application to read this.
<camel:route id="myRoute">
<camel:from uri="RabbitMQEndpoint" />
<camel:to uri="bean:MyHandler" />
</camel:route>
Handler is using the Jaxb object redone in camel side
@Handler
public void handleRequest(MyDTO dto) throws ParseException {
I am getting the error which I did not expect to get.
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: byte[] to the required type: com.mycompany.MyDTO with value [B@1b8d3e42
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:181)
at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:99)
Solution is appreciated.
Your message body type from rabbit is a byte[], and you want to call a bean which as MyDTO type. You have a type mismatch. And Camel cannot find a type converter that can convert the message body from byte[] to your MyDTO type.
Is the byte[] data from Rabbit in XML format? And do you have JAXB annotations on MyDTO classes, so you could use JAXB to marshal that from xml to Java ?
It is Jaxb object. I was under impression that if i move the publisher too Camel. Things will be sorted out.
I changed the publisher to the following.
@EndpointInject(context = "myContext" , uri = "direct:myRoute")
private ProducerTemplate sendAMyContext;
And in method I called
@Override
public MyResponse putMyCall(
MyRequest myrequest) {
sendMyContext.sendBody(myrequest);
My camel route is simple one
<camel:camelContext id="MyContext" autoStartup="true" xmlns="http://camel.apache.org/schema/spring">
<camel:endpoint id="myQueue" uri="${my.queue.1}" />
<camel:route>
<camel:from uri="direct:myRoute"/>
<camel:to uri="bean:mySendHandler"/>
<camel:convertBodyTo type="String"></camel:convertBodyTo>
<camel:to uri="ref:myQueue" />
</camel:route>
</camel:camelContext>
I added the handler to convert the Jaxb object to string(because of error)
public class MySendHandler {
@Handler
public String myDelivery( MyRequest myRequest) throws ParseException, JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(MyRequest.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
java.io.StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(attributedDeliveryRequest, sw);
return sw.toString();
}
Still the same error
[SpringAMQPConsumer.SpringAMQPExecutor-1] WARN org.springframework.amqp.support.converter.JsonMessageConverter (JsonMessageConverter.java:111) - Could not convert incoming message with content-type [text/plain]
SpringAMQPConsumer.SpringAMQPExecutor-1] ERROR org.apache.camel.processor.DefaultErrorHandler (MarkerIgnoringBase.java:161) - Failed delivery for (MessageId: ID-Con ExchangeId: ID-65455-1380873539452-3-2).
Exhausted after delivery attempt: 1 caught: org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[Message: <XML>]
org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[Message: <xml>
.....
Caused by: org.apache.camel.InvalidPayloadException: No body available of type: MyDTO but has value: [B@7da255c of type: byte[] on: Message: <xml>
. Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: byte[] to the required type: MyDeliveryDTO with value [B@7da255c]
at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:101)
at org.apache.camel.builder.ExpressionBuilder$38.evaluate(ExpressionBuilder.java:934)
... 74 more
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: byte[] to the required type: MyDTO with value [B@7da255c
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:181)
at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:99)
... 75 more
My receiving camel route is as below
<camel:route id="processVDelivery">
<camel:from uri="aVEndpoint" />
<camel:to uri="bean:myDataHandler" />
</camel:route>
I added
<camel:convertBodyTo type="String"></camel:convertBodyTo>
to it and it gave me error that it cannot convert it from string to the object
adding this
<camel:unmarshal></camel:unmarshal>
-------------------------
Answer to the question will be all your mashaller have to be part of classpath
---------------------------------
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>${jackson.version}</version>
</dependency>
------- Also you can the custom marshaller using dataformat
<camel:dataFormats>
<camel:jaxb id="name" contextPath="com.something"/>
</camel:dataFormats
make sure that you keep jaxb.index file in com.something package with the root level Jaxb object name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With