use of com.rabbitmq.jms.util.RMQJMSException in project rabbitmq-jms-client by rabbitmq.
the class RMQObjectMessage method setObject.
@Override
public void setObject(Serializable object) throws JMSException {
if (isReadonlyBody())
throw new MessageNotWriteableException("Message not writeable");
try {
if (object == null) {
buf = null;
} else {
/*
* We have to serialise the object now
*/
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
out.writeObject(object);
out.flush();
buf = bout.toByteArray();
}
} catch (IOException x) {
throw new RMQJMSException(x);
}
}
use of com.rabbitmq.jms.util.RMQJMSException in project rabbitmq-jms-client by rabbitmq.
the class RMQStreamMessage method readPrimitiveType.
private Object readPrimitiveType(Class<?> type) throws JMSException {
if (!this.reading)
throw new MessageNotReadableException(NOT_READABLE);
if (this.readbuf != null) {
throw new MessageFormatException("You must call 'int readBytes(byte[])' since the buffer is not empty");
}
boolean success = true;
try {
this.bin.mark(0);
Object o = RMQMessage.readPrimitive(in);
if (o instanceof byte[]) {
if (type == ByteArray.class || type == Object.class) {
return o;
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "byte[]"));
}
} else if (type == ByteArray.class) {
if (o == null) {
return null;
}
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "byte[]"));
} else if (type == Boolean.class) {
if (o == null) {
return Boolean.FALSE;
} else if (o instanceof Boolean) {
return o;
} else if (o instanceof String) {
return Boolean.parseBoolean((String) o);
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "boolean"));
}
} else if (type == Byte.class) {
if (o instanceof Byte) {
return o;
} else if (o instanceof String) {
return Byte.parseByte((String) o);
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "byte"));
}
} else if (type == Short.class) {
if (o instanceof Byte) {
return (short) (Byte) o;
} else if (o instanceof Short) {
return o;
} else if (o instanceof String) {
return Short.parseShort((String) o);
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "byte"));
}
} else if (type == Integer.class) {
if (o instanceof Byte) {
return (int) (Byte) o;
} else if (o instanceof Short) {
return (int) (Short) o;
} else if (o instanceof Integer) {
return o;
} else if (o instanceof String) {
return Integer.parseInt((String) o);
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "int"));
}
} else if (type == Character.class) {
if (o instanceof Character) {
return o;
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "char"));
}
} else if (type == Long.class) {
if (o instanceof Byte) {
return (long) (Byte) o;
} else if (o instanceof Short) {
return (long) (Short) o;
} else if (o instanceof Integer) {
return (long) (Integer) o;
} else if (o instanceof Long) {
return o;
} else if (o instanceof String) {
return Long.parseLong((String) o);
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "long"));
}
} else if (type == Float.class) {
if (o instanceof Float) {
return (Float) o;
} else if (o instanceof String) {
return Float.parseFloat((String) o);
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "float"));
}
} else if (type == Double.class) {
if (o instanceof Float) {
return (double) (Float) o;
} else if (o instanceof Double) {
return (Double) o;
} else if (o instanceof String) {
return Double.parseDouble((String) o);
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "double"));
}
} else if (type == String.class) {
if (o == null) {
return null;
} else if (o instanceof byte[]) {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, "String"));
} else {
return o.toString();
}
} else if (type == Object.class) {
return o;
} else {
throw new MessageFormatException(String.format(UNABLE_TO_CAST, o, type.toString()));
}
} catch (NumberFormatException x) {
success = false;
throw x;
} catch (ClassNotFoundException x) {
success = false;
throw new RMQJMSException(x);
} catch (EOFException x) {
success = false;
throw new MessageEOFException(MSG_EOF);
} catch (UTFDataFormatException x) {
success = false;
throw new RMQMessageFormatException(x);
} catch (IOException x) {
success = false;
throw new RMQJMSException(x);
} catch (Exception x) {
success = false;
if (x instanceof JMSException) {
throw (JMSException) x;
} else {
throw new RMQJMSException(x);
}
} finally {
if (!success) {
this.bin.reset();
}
}
}
use of com.rabbitmq.jms.util.RMQJMSException in project rabbitmq-jms-client by rabbitmq.
the class RMQSession method declareRMQQueue.
/**
* Invokes {@link Channel#queueDeclare(String, boolean, boolean, boolean, java.util.Map)} to define a queue on the RabbitMQ broker
* this method invokes {@link RMQDestination#setDeclared(boolean)} with a true value
* @param dest - the Queue Destination object
* @param queueNameOverride name of queue to declare (if different from destination name)
* @param durableSubscriber - true if the subscriber ius
* @throws JMSException if an IOException occurs in the {@link Channel#queueDeclare(String, boolean, boolean, boolean, java.util.Map)} call
*/
private void declareRMQQueue(RMQDestination dest, String queueNameOverride, boolean durableSubscriber) throws JMSException {
logger.trace("declare RabbitMQ queue for destination '{}', explicitName '{}', durableSubscriber={}", dest, queueNameOverride, durableSubscriber);
String queueName = queueNameOverride != null ? queueNameOverride : dest.getQueueName();
String exchangeName = dest.getAmqpExchangeName();
String exchangeType = dest.amqpExchangeType();
/*
* We only want destinations to survive server restarts if
* 1. They are durable topic subscriptions OR
* 2. They are permanent queues
*/
boolean durable = durableSubscriber || (dest.isQueue() & (!dest.isTemporary()));
/*
* A queue is exclusive, meaning it can only be accessed by the current connection
* and will be deleted when the connection is closed if
* 1. It's a temporary destination OR
* 2. It's a non durable topic
*/
boolean exclusive = dest.isTemporary() || ((!dest.isQueue()) && (!durableSubscriber));
// new HashMap<String,Object>();
Map<String, Object> options = null;
if (dest.isQueue()) {
if (dest.noNeedToDeclareExchange()) {
logger.warn("no need to declare built-in exchange for queue destination '{}'", dest);
} else {
logger.trace("declare RabbitMQ exchange for queue destinations '{}'", dest);
try {
this.channel.exchangeDeclare(exchangeName, exchangeType, durable, // autoDelete
false, // internal
false, // object properties
null);
} catch (Exception x) {
throw new RMQJMSException(x);
}
}
}
/* broker queues declared for a non-durable topic that have an auto-generated name must go down with
consumer/producer or the broker will leak them until the connection is brought down
*/
boolean autoDelete = cleanUpServerNamedQueuesForNonDurableTopics ? !durable && queueNameOverride != null && !dest.isQueue() : false;
try {
/* Declare the queue to RabbitMQ -- this creates it if it doesn't already exist */
this.logger.debug("declare RabbitMQ queue name({}), durable({}), exclusive({}), auto-delete({}), properties({})", queueName, durable, exclusive, false, options);
this.channel.queueDeclare(queueName, durable, exclusive, autoDelete, // object properties
options);
/* Temporary or 'topic queues' are exclusive and therefore get deleted by RabbitMQ on close */
} catch (Exception x) {
this.logger.error("RabbitMQ exception on queue declare name({}), durable({}), exclusive({}), auto-delete({}), properties({})", queueName, durable, exclusive, autoDelete, options, x);
throw new RMQJMSException(x);
}
try {
/* Bind the queue to our exchange -- this allows publications to succeed. */
this.logger.debug("bind queue name({}), to exchange({}), with r-key({}), no arguments", queueName, exchangeName, queueName);
this.channel.queueBind(queueName, exchangeName, // routing key
queueName, // arguments
null);
} catch (Exception x) {
this.logger.error("RabbitMQ exception on queue declare name({}), durable({}), exclusive({}), auto-delete({}), properties({})", queueName, durable, exclusive, false, options, x);
throw new RMQJMSException(x);
}
dest.setDeclared(true);
}
use of com.rabbitmq.jms.util.RMQJMSException in project rabbitmq-jms-client by rabbitmq.
the class RMQSession method closeRabbitChannels.
private void closeRabbitChannels() throws JMSException {
// does not throw exception
this.clearBrowsingChannels();
if (this.channel == null)
return;
try {
this.channel.close();
} catch (ShutdownSignalException x) {
// nothing to do
} catch (Exception x) {
if (x instanceof IOException) {
IOException ioe = (IOException) x;
if (!(ioe.getCause() instanceof ShutdownSignalException)) {
this.logger.warn("RabbitMQ channel({}) failed to close on session {}", this.channel, this, ioe);
throw new RMQJMSException(ioe);
}
} else if (x instanceof TimeoutException) {
TimeoutException te = (TimeoutException) x;
this.logger.warn("RabbitMQ channel({}) timed out trying to close session {}", this.channel, this, te);
throw new RMQJMSException(te);
} else {
throw new RMQJMSException("Unexpected exception from channel.close()", x);
}
}
}
use of com.rabbitmq.jms.util.RMQJMSException in project rabbitmq-jms-client by rabbitmq.
the class RMQSession method acknowledgeMessage.
/**
* Acknowledges messages in this session.
* Invoked when the method {@link javax.jms.Message#acknowledge()} is called.
* @param message - the message to be acknowledged, or the carrier to acknowledge all messages
*/
void acknowledgeMessage(RMQMessage message) throws JMSException {
illegalStateExceptionIfClosed();
boolean individualAck = this.getIndividualAck();
// This assumption is new in RJMS 1.2.0 and is consistent with other implementations. It allows a form of group acknowledge.
boolean groupAck = true;
if (!isAutoAck() && !this.unackedMessageTags.isEmpty()) {
/**
* Per JMS specification of {@link Message#acknowledge()}, <i>if we ack the last message in a group, we will ack all the ones prior received</i>.
* <p>But, JMS spec 11.2.21 says:</p>
* <pre>"Note that the acknowledge method of Message acknowledges all messages
* received on that message's session."</pre>
* <p>
* The groupAck option acknowledges all previous messages in this session (and this one, too, if not acknowledged already).
* The individualAck option is set by session mode (CLIENT_INDIVIDUAL_ACKNOWLEDGE) and overrides groupAck (default) and acknowledges at most a single message.
* </p>
*/
synchronized (this.unackedMessageTags) {
try {
if (individualAck) {
long messageTag = message.getRabbitDeliveryTag();
// this message already acknowledged
if (!this.unackedMessageTags.contains(messageTag))
return;
/* ACK a single message */
// we ack the single message with this tag
this.getChannel().basicAck(messageTag, false);
this.unackedMessageTags.remove(messageTag);
} else if (groupAck) {
long messageTag = message.getRabbitDeliveryTag();
/**
* The tags that precede the given one, and the given one, if unacknowledged
*/
SortedSet<Long> previousTags = this.unackedMessageTags.headSet(messageTag + 1);
// no message to acknowledge
if (previousTags.isEmpty())
return;
/* ack multiple message up until the existing tag */
// we ack the latest one (which might be this one, but might not be)
this.getChannel().basicAck(// we ack the latest one (which might be this one, but might not be)
previousTags.last(), // and everything prior to that
true);
// now remove all the tags <= messageTag
previousTags.clear();
} else {
// this block is no longer possible (groupAck == true) after RJMS 1.2.0
// we ack the highest tag
this.getChannel().basicAck(// we ack the highest tag
this.unackedMessageTags.last(), // and everything prior to that
true);
this.unackedMessageTags.clear();
}
} catch (IOException x) {
this.logger.error("RabbitMQ exception on basicAck of message {}; on session '{}'", message, this, x);
throw new RMQJMSException(x);
}
}
}
}
Aggregations