javaapache-camelactivemq-artemis

Can't send large message to ActiveMQ Artemis with Qpid JMS


I try to read a large file from disk and send it to a queue on ActiveMQ Artemis. Every time I try I get the same exception:

Caused by: jakarta.jms.MessageFormatException: Only objectified primitive objects and String types are allowed but was: java.io.BufferedInputStream@3a8489ac type: class java.io.BufferedInputStream
    at org.apache.qpid.jms.message.JmsMessagePropertySupport.checkValidObject(JmsMessagePropertySupport.java:121)
    at org.apache.qpid.jms.message.JmsMessagePropertyIntercepter.setProperty(JmsMessagePropertyIntercepter.java:725)
    at org.apache.qpid.jms.message.JmsMessage.setObjectProperty(JmsMessage.java:348)
    at org.apache.camel.component.jms.JmsBinding.createJmsMessageForType(JmsBinding.java:661)
    at org.apache.camel.component.jms.JmsBinding.createJmsMessage(JmsBinding.java:568)
    at org.apache.camel.component.jms.JmsBinding.createJmsMessage(JmsBinding.java:525)
    at org.apache.camel.component.jms.JmsBinding.makeJmsMessage(JmsBinding.java:348)
    at org.apache.camel.component.jms.JmsProducer$2.createMessage(JmsProducer.java:325)
    at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.doSendToDestination(JmsConfiguration.java:616)
    at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.lambda$send$0(JmsConfiguration.java:574)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:507)
    ... 39 more

It seems to me this will never work because while debugging the code I found a place where a property by the lib is set message.setObjectProperty("JMS_AMQ_InputStream", is); and this property will never be valid because it is an InputStream. Any idea how to solve this?

    if (endpoint.isArtemisStreamingEnabled()) {
        LOG.trace("Optimised for Artemis: Streaming payload in BytesMessage");
        InputStream is = context.getTypeConverter().mandatoryConvertTo(InputStream.class, exchange, body);
        message.setObjectProperty("JMS_AMQ_InputStream", is);
        LOG.trace("Optimised for Artemis: Finished streaming payload in BytesMessage");
    } else {

Source

public static void setProperty(JmsMessage message, String name, Object value) throws JMSException {
    PropertyIntercepter jmsPropertyExpression = PROPERTY_INTERCEPTERS.get(name);

    if (jmsPropertyExpression == null || !jmsPropertyExpression.isAlwaysWritable()) {
        message.checkReadOnlyProperties();
    }
    checkPropertyNameIsValid(name, message.isValidatePropertyNames());
    checkValidObject(value);

    if (jmsPropertyExpression != null) {
        jmsPropertyExpression.setProperty(message, value);
    } else {
        message.getFacade().setProperty(name, value);
    }
}

Source

public static void checkValidObject(Object value) throws MessageFormatException {
    boolean valid = value instanceof Boolean ||
                    value instanceof Byte ||
                    value instanceof Short ||
                    value instanceof Integer ||
                    value instanceof Long ||
                    value instanceof Float ||
                    value instanceof Double ||
                    value instanceof Character ||
                    value instanceof String ||
                    value == null;

    if (!valid) {
        throw new MessageFormatException("Only objectified primitive objects and String types are allowed but was: " + value + " type: " + value.getClass());
    }
}

Source


Solution

  • The JMS_AMQ_InputStream property is exclusively for the Core JMS client implementation. According to the stack-trace, you're attempting to use this property with the Qpid JMS client implementation which won't work.

    You either need to change your classpath to reference the Core JMS client libraries or stop using the JMS_AMQ_InputStream property.