[
https://issues.apache.org/jira/browse/CASSANDRA-2684?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jonathan Ellis updated CASSANDRA-2684:
--------------------------------------
Component/s: Core
Priority: Minor (was: Major)
Affects Version/s: 0.7.0
Fix Version/s: 0.8.0
0.7.7
> IntergerType uses Thrift method that attempts to unsafely access backing
> array of ByteBuffer and fails
> ------------------------------------------------------------------------------------------------------
>
> Key: CASSANDRA-2684
> URL: https://issues.apache.org/jira/browse/CASSANDRA-2684
> Project: Cassandra
> Issue Type: Bug
> Components: Core
> Affects Versions: 0.7.0
> Reporter: Ed Anuff
> Assignee: Ed Anuff
> Priority: Minor
> Fix For: 0.7.7, 0.8.0
>
> Attachments: 2684.txt
>
>
> I get the following exception:
> {noformat}
> ERROR 13:27:38,153 Fatal exception in thread Thread[ReadStage:36,5,main]
> java.lang.RuntimeException: java.lang.UnsupportedOperationException
> at
> org.apache.cassandra.utils.WrappedRunnable.run(WrappedRunnable.java:34)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> at java.lang.Thread.run(Thread.java:680)
> Caused by: java.lang.UnsupportedOperationException
> at java.nio.ByteBuffer.array(ByteBuffer.java:940)
> at
> org.apache.thrift.TBaseHelper.byteBufferToByteArray(TBaseHelper.java:264)
> at
> org.apache.thrift.TBaseHelper.byteBufferToByteArray(TBaseHelper.java:251)
> at
> org.apache.cassandra.db.marshal.IntegerType.getString(IntegerType.java:136)
> at
> org.apache.cassandra.db.marshal.AbstractCompositeType.getString(AbstractCompositeType.java:131)
> at org.apache.cassandra.db.Column.getString(Column.java:228)
> at
> org.apache.cassandra.db.filter.SliceQueryFilter.collectReducedColumns(SliceQueryFilter.java:123)
> at
> org.apache.cassandra.db.filter.QueryFilter.collectCollatedColumns(QueryFilter.java:130)
> at
> org.apache.cassandra.db.ColumnFamilyStore.getTopLevelColumns(ColumnFamilyStore.java:1303)
> at
> org.apache.cassandra.db.ColumnFamilyStore.getColumnFamily(ColumnFamilyStore.java:1188)
> at
> org.apache.cassandra.db.ColumnFamilyStore.getColumnFamily(ColumnFamilyStore.java:1145)
> at org.apache.cassandra.db.Table.getRow(Table.java:385)
> at
> org.apache.cassandra.db.SliceFromReadCommand.getRow(SliceFromReadCommand.java:61)
> at
> org.apache.cassandra.service.StorageProxy$LocalReadRunnable.runMayThrow(StorageProxy.java:641)
> at
> org.apache.cassandra.utils.WrappedRunnable.run(WrappedRunnable.java:30)
> ... 3 more
> {noformat}
> Tracing it down, I find that IntegerType's getString method() looks like this:
> {code:title=IntegerType.java|borderStyle=solid}
> public String getString(ByteBuffer bytes)
> {
> if (bytes == null)
> return "null";
> if (bytes.remaining() == 0)
> return "empty";
> return new
> java.math.BigInteger(TBaseHelper.byteBufferToByteArray(bytes)).toString(10);
> }
> {code}
>
> TBaseHelper.byteBufferToByteArray() looks like this:
> {code:title=TBaseHelper.java|borderStyle=solid}
> public static byte[] byteBufferToByteArray(ByteBuffer byteBuffer) {
> if (wrapsFullArray(byteBuffer)) {
> return byteBuffer.array();
> }
> byte[] target = new byte[byteBuffer.remaining()];
> byteBufferToByteArray(byteBuffer, target, 0);
> return target;
> }
> public static boolean wrapsFullArray(ByteBuffer byteBuffer) {
> return byteBuffer.hasArray()
> && byteBuffer.position() == 0
> && byteBuffer.arrayOffset() == 0
> && byteBuffer.remaining() == byteBuffer.capacity();
> }
> public static int byteBufferToByteArray(ByteBuffer byteBuffer, byte[]
> target, int offset) {
> int remaining = byteBuffer.remaining();
> System.arraycopy(byteBuffer.array(),
> byteBuffer.arrayOffset() + byteBuffer.position(),
> target,
> offset,
> remaining);
> return remaining;
> }
> {code}
> The second overloaded implementation of byteBufferToByteArray is calling the
> bytebuffer's array() method.
> Suggested fixes:
> 1) Don't use TBaseHelper in IntegerType.getString(), use
> ByteBufferUtil.getArray()
> 2) Report problem upstream to Thrift.
> 3) Find a better way to deserialize BigIntegers that doesn't require an array
> copy.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira