activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Andy (JIRA)" <j...@apache.org>
Subject [jira] Commented: (AMQ-2696) DefaultJDBCAdapter returns incorrect value that prevents ActiveMQ from starting.
Date Mon, 19 Apr 2010 14:56:33 GMT

    [ https://issues.apache.org/activemq/browse/AMQ-2696?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=58948#action_58948
] 

Andy commented on AMQ-2696:
---------------------------


   [[ Old comment, sent by email on Thu, 15 Apr 2010 11:33:28 +0200 ]]

Hi Dejan,

It's going to be difficult to create a test case, but is easy to 
reproduce if you have any JDBC adapter configured.

<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#postgresql-activemq-ds">
<adapter>
<postgresql-jdbc-adapter/>
</adapter>
</jdbcPersistenceAdapter>
</persistenceAdapter>

Just change the DataSource database to an empty test database and let 
ActiveMQ create new empty tables.

Stop ActiveMQ.

Manually add one dummy row to the empty 'activemq_acks' table:

INSERT INTO activemq_acks(container, sub_dest, client_id, sub_name, 
selector, last_acked_id) VALUES ('topic://a', 'topic://a', 'a', 'a', 
'a', 555);

Start ActiveMQ.

It will try to load message id 555 - which does not exist, and will drop 
a NullPointerException.

The code in doGetLastMessageStoreSequenceId uses Math.max(seq1, seq2) to 
determine the next sequence id, so this is then definitely not safe to 
use in getLastMessageBrokerSequenceId() to load a message by id.

I suppose a test case using something like Derby could be created - 
without looking, is Derby on the default test classpath?

Andy.



> DefaultJDBCAdapter returns incorrect value that prevents ActiveMQ from starting.
> --------------------------------------------------------------------------------
>
>                 Key: AMQ-2696
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2696
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Message Store
>    Affects Versions: 5.3.1
>         Environment: Vista 64bit
>            Reporter: Andy
>            Assignee: Dejan Bosanac
>            Priority: Critical
>             Fix For: 5.4.0
>
>
> org.apache.activemq.store.jdbcJDBCPersistenceAdapter.getLastMessageBrokerSequenceId()
calls:
> org.apache.activemq.store.jdbc.adapter.DefaultJDBCAdapter:
> The call to doGetLastMessageStoreSequenceId will return the max acks table id if the
max msgs id is less.
> The result is used to seed the sequenceGenerator:
> long seq =  getAdapter().doGetLastMessageStoreSequenceId(c);
> sequenceGenerator.setLastSequenceId(seq);
> However the next call to set the brokerSeq variable will fail if the seq variable has
been seeded with the max acks id, as 'doGetMessageById' expects a valid msgs id.
> long brokerSeq = 0;
>             if (seq != 0) {
>             	Message last = (Message)wireFormat.unmarshal(new ByteSequence(getAdapter().doGetMessageById(c,
seq)));
>             	brokerSeq = last.getMessageId().getBrokerSequenceId();
>             }
>             return brokerSeq;
> If 'seq' is not a valid msgs id (I presume because the message has expired and/or been
removed) then this causes a NullPointerException in ByteSequence, which is not caught, and
this leads to a complete failure to start ActiveMQ.
> The solution is not simple if the tables are in production, and is compounded even further
by durable subscribers that cannot simply be deleted from the acks table.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message