[ 
https://issues.apache.org/jira/browse/CASSANDRA-2684?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ed Anuff updated CASSANDRA-2684:
--------------------------------

    Description: 
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.








  was:
I get the following exception:

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

Tracing it down, I find that IntegerType's getString method() looks like this:

    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);
    }
    
TBaseHelper.byteBufferToByteArray() looks like this:

  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;
  }

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.









> 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
>            Reporter: Ed Anuff
>
> 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

Reply via email to