[
https://issues.apache.org/jira/browse/AMQ-5381?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Brian D. Johnson updated AMQ-5381:
----------------------------------
Description:
Changes made in ActiveMQ 5.9.1, AMQ-4887,
[[cb5c29d02d02dc7f7fa4f5c1a97bd2a59078bccd|https://github.com/apache/activemq/commit/cb5c29d02d02dc7f7fa4f5c1a97bd2a59078bccd#diff-c0b18b235652457c810fe322bce65e31]]
introduced a bug in {{ActiveMQBytesMessage}} which results in a
{{java.util.zip.ZipException: incorrect header check}} being thrown at
{{org.apache.activemq.command.ActiveMQBytesMessage.restoreOldContent(ActiveMQBytesMessage.java:883)}}
when a consumer attempts to reuse a received {{ActiveMQBytesMessage}}.
This bug is triggered under a unique set of circumstances:
# A message is published by a JMS client with compression *_disabled_* on its
{{ActiveMQConnection}}
# The message is consumed by a JMS client with compression *_enabled_* on its
{{ActiveMQConnection}}
# The JMS consumer makes the received message writable in order to modify and
reuse it:
{code}
message.setReadOnlyProperties(false);
message.setReadOnlyBody(false);
{code}
# The JMS consumer modifies the message, triggering a call to
{{ActiveMQBytesMessage.initializeWriting()}}
The problem within {{ActiveMQBytesMessage.initializeWriting()}} is that the
method determines whether the message should be compressed _when it is
published_ (based on its current connection) BEFORE it has restored the
message's original content. In the example above, the message's original
{{compressed}} flag is changed from {{false}} to {{true}}, resulting in
{{restoreOldContent()}} trying to decompress message contents which were never
compressed.
{code}
private void initializeWriting() throws JMSException {
checkReadOnlyBody();
if (this.dataOut == null) {
this.bytesOut = new ByteArrayOutputStream();
OutputStream os = bytesOut;
this.dataOut = new DataOutputStream(os);
}
// should compression be used when publishing this message??
ActiveMQConnection connection = getConnection();
if (connection != null && connection.isUseCompression()) {
compressed = true;
}
// restore the message's old content
restoreOldContent();
}
{code}
-A simple solution would be to move the {{restoreOldContent()}} method call
before the {{connection.isUseCompression()}} conditional in
{{ActiveMQBytesMessage.initializeWriting()}}.-
+Had a chance to look into this problem further. The best fix would be to only
set the 'compressed' flag when the message's 'contents' are stored, instead of
whenever the message is initialized for writing.+
was:
Changes made in ActiveMQ 5.9.1, AMQ-4887,
[[cb5c29d02d02dc7f7fa4f5c1a97bd2a59078bccd|https://github.com/apache/activemq/commit/cb5c29d02d02dc7f7fa4f5c1a97bd2a59078bccd#diff-c0b18b235652457c810fe322bce65e31]]
introduced a bug in {{ActiveMQBytesMessage}} which results in a
{{java.util.zip.ZipException: incorrect header check}} being thrown at
{{org.apache.activemq.command.ActiveMQBytesMessage.restoreOldContent(ActiveMQBytesMessage.java:883)}}
when a consumer attempts to reuse a received {{ActiveMQBytesMessage}}.
This bug is triggered under a unique set of circumstances:
# A message is published by a JMS client with compression *_disabled_* on its
{{ActiveMQConnection}}
# The message is consumed by a JMS client with compression *_enabled_* on its
{{ActiveMQConnection}}
# The JMS consumer makes the received message writable in order to modify and
reuse it:
{code}
message.setReadOnlyProperties(false);
message.setReadOnlyBody(false);
{code}
# The JMS consumer modifies the message, triggering a call to
{{ActiveMQBytesMessage.initializeWriting()}}
The problem within {{ActiveMQBytesMessage.initializeWriting()}} is that the
method determines whether the message should be compressed _when it is
published_ (based on its current connection) BEFORE it has restored the
message's original content. In the example above, the message's original
{{compressed}} flag is changed from {{false}} to {{true}}, resulting in
{{restoreOldContent()}} trying to decompress message contents which were never
compressed.
{code}
private void initializeWriting() throws JMSException {
checkReadOnlyBody();
if (this.dataOut == null) {
this.bytesOut = new ByteArrayOutputStream();
OutputStream os = bytesOut;
this.dataOut = new DataOutputStream(os);
}
// should compression be used when publishing this message??
ActiveMQConnection connection = getConnection();
if (connection != null && connection.isUseCompression()) {
compressed = true;
}
// restore the message's old content
restoreOldContent();
}
{code}
A simple solution would be to move the {{restoreOldContent()}} method call
before the {{connection.isUseCompression()}} conditional in
{{ActiveMQBytesMessage.initializeWriting()}}.
> ActiveMQBytesMessage mishandles restoration of old message contents
> -------------------------------------------------------------------
>
> Key: AMQ-5381
> URL: https://issues.apache.org/jira/browse/AMQ-5381
> Project: ActiveMQ
> Issue Type: Bug
> Components: JMS client
> Affects Versions: 5.9.1, 5.10.0
> Reporter: Brian D. Johnson
> Labels: easyfix
>
> Changes made in ActiveMQ 5.9.1, AMQ-4887,
> [[cb5c29d02d02dc7f7fa4f5c1a97bd2a59078bccd|https://github.com/apache/activemq/commit/cb5c29d02d02dc7f7fa4f5c1a97bd2a59078bccd#diff-c0b18b235652457c810fe322bce65e31]]
> introduced a bug in {{ActiveMQBytesMessage}} which results in a
> {{java.util.zip.ZipException: incorrect header check}} being thrown at
> {{org.apache.activemq.command.ActiveMQBytesMessage.restoreOldContent(ActiveMQBytesMessage.java:883)}}
> when a consumer attempts to reuse a received {{ActiveMQBytesMessage}}.
> This bug is triggered under a unique set of circumstances:
> # A message is published by a JMS client with compression *_disabled_* on its
> {{ActiveMQConnection}}
> # The message is consumed by a JMS client with compression *_enabled_* on its
> {{ActiveMQConnection}}
> # The JMS consumer makes the received message writable in order to modify and
> reuse it:
> {code}
> message.setReadOnlyProperties(false);
> message.setReadOnlyBody(false);
> {code}
> # The JMS consumer modifies the message, triggering a call to
> {{ActiveMQBytesMessage.initializeWriting()}}
> The problem within {{ActiveMQBytesMessage.initializeWriting()}} is that the
> method determines whether the message should be compressed _when it is
> published_ (based on its current connection) BEFORE it has restored the
> message's original content. In the example above, the message's original
> {{compressed}} flag is changed from {{false}} to {{true}}, resulting in
> {{restoreOldContent()}} trying to decompress message contents which were
> never compressed.
> {code}
> private void initializeWriting() throws JMSException {
> checkReadOnlyBody();
> if (this.dataOut == null) {
> this.bytesOut = new ByteArrayOutputStream();
> OutputStream os = bytesOut;
> this.dataOut = new DataOutputStream(os);
> }
> // should compression be used when publishing this message??
> ActiveMQConnection connection = getConnection();
> if (connection != null && connection.isUseCompression()) {
> compressed = true;
> }
> // restore the message's old content
> restoreOldContent();
> }
> {code}
> -A simple solution would be to move the {{restoreOldContent()}} method call
> before the {{connection.isUseCompression()}} conditional in
> {{ActiveMQBytesMessage.initializeWriting()}}.-
> +Had a chance to look into this problem further. The best fix would be to
> only set the 'compressed' flag when the message's 'contents' are stored,
> instead of whenever the message is initialized for writing.+
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)