[jira] Created: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

[jira] Created: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
ConcurrentLRUCache can throw class cast exception
-------------------------------------------------

                 Key: SOLR-2410
                 URL: https://issues.apache.org/jira/browse/SOLR-2410
             Project: Solr
          Issue Type: Bug
    Affects Versions: 4.0
            Reporter: Yonik Seeley
             Fix For: 4.0


ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/SOLR-2410?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13003668#comment-13003668 ]

Yonik Seeley commented on SOLR-2410:
------------------------------------

Here's the smallest version I could reproduce the issue with.

{code}
class CacheEntry<K,V> {
}

class PQueue<K,V> extends PriorityQueue<CacheEntry<K,V>> {
  public static void main(String[] args) {
    new PQueue<String,String>().tst();
  }

  PQueue() {
    super.initialize(1);
  }

  @Override
  protected boolean lessThan(CacheEntry<K,V> a, CacheEntry<K,V> b) {
    return true;
  }

  public CacheEntry<K,V> tst() {
    return heap[1];
  }
}
{code}

I just cut-n-pasted the code into BasicFunctionalityTest, run main() from my IDE, and presto:

{code}
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lorg.apache.solr.CacheEntry;
        at org.apache.solr.PQueue.tst(BasicFunctionalityTest.java:81)
        at org.apache.solr.PQueue.main(BasicFunctionalityTest.java:68)
{code}

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/SOLR-2410?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13003674#comment-13003674 ]

Yonik Seeley commented on SOLR-2410:
------------------------------------

Here's an even smaller version w/ no dependencies:

{code}
class C<T> {
}

class A<T1> {
  public T1[] arr = (T1[])(new Object[1]);
}

class B<T2> extends A<C<T2>> {
  public C<T2> tst() {
    return arr[0];
  }

  public static void main(String[] args) {
    new B<String>().tst();
  }
}
{code}


> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/SOLR-2410?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13003675#comment-13003675 ]

Dawid Weiss commented on SOLR-2410:
-----------------------------------

It's because there's a bug -- PriorityQueue declares a generic array:

  protected T[] heap;

but assigns an Object[] to it in:

    heap = (T[]) new Object[heapSize]; // T is unbounded type, so this unchecked cast works always

this is true only if heap is not exposed outside the class (and is the pattern used in JDK's ArrayDeque<E>, for  example). Unfortunately the compiler will insert casts if you have a subclass with a narrowed generic type to ensure the array is indeed of proper type. The solution is to:

1) allocate arrays of real component type (impossible if you don't know it in advance or don't have an existing array or its component). Example: Google Guava's ObjectArrays.newArray, as here:

http://guava-libraries.googlecode.com/svn/tags/release08/javadoc/com/google/common/collect/ObjectArrays.html#newArray(java.lang.Class, int)

2) cast superclass's array to (Object[]) first, then cast to the concrete component type. Here:

(CacheEntry<K,V>) ((Object[]) heap)[1];

3) Declare PriorityQueue's internal array as Object[] and provide a getter that casts components to (T)?

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/SOLR-2410?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13003676#comment-13003676 ]

Dawid Weiss commented on SOLR-2410:
-----------------------------------

Btw. this is exactly the reason Collections declare Object[] toArray() and not T[] toArray -- in the latter case the compiler adds casts to the expression's argument type and collections can't know their component type after type erasure. Eh, C#/.NET is so much more elegant with generics.

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/SOLR-2410?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13003682#comment-13003682 ]

Dawid Weiss commented on SOLR-2410:
-----------------------------------

Yonik, try this and it should be clear why the above doesn't work:

{noformat}

public class Example
{
    public static class A<T> {
        @SuppressWarnings("unchecked") // it is here for a reason :)
        public T[] array = (T[]) new Object [1];
    }
   
    public static void main(String [] args)
    {
        A<Integer> clazzA = new A<Integer>();
        System.out.println(clazzA.array[0]);
    }
}
{noformat}

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/SOLR-2410?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13003690#comment-13003690 ]

Yonik Seeley commented on SOLR-2410:
------------------------------------

Thanks Dawid!

bq. 2) cast superclass's array to (Object[]) first, then cast to the concrete component type. Here:

I tried this, but couldn't get it to work:

{code}

class Example
{
   public static class A<T> {
       @SuppressWarnings("unchecked") // it is here for a reason :)
       public T[] array = (T[]) new Object [1];
   }

   public static void main(String [] args)
   {
       A<Integer> clazzA = new A<Integer>();
       System.out.println(((Integer[])((Object[])clazzA.array))[0]);
   }
}
{code}

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Issue Comment Edited: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/SOLR-2410?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13003690#comment-13003690 ]

Yonik Seeley edited comment on SOLR-2410 at 3/7/11 11:40 PM:
-------------------------------------------------------------

Thanks Dawid!

bq. 2) cast superclass's array to (Object[]) first, then cast to the concrete component type. Here:

I tried this, but couldn't get it to work:

{code}

class Example
{
   public static class A<T> {
       @SuppressWarnings("unchecked") // it is here for a reason :)
       public T[] array = (T[]) new Object [1];
   }

   public static void main(String [] args)
   {
       A<Integer> clazzA = new A<Integer>();
       System.out.println(((Integer[])((Object[])clazzA.array))[0]);
   }
}
{code}

edit: I got it - you need to access the array as an Object[]

{code}
       System.out.println( (Integer) (((Object[])clazzA.array)[0]));
{code}

      was (Author: [hidden email]):
    Thanks Dawid!

bq. 2) cast superclass's array to (Object[]) first, then cast to the concrete component type. Here:

I tried this, but couldn't get it to work:

{code}

class Example
{
   public static class A<T> {
       @SuppressWarnings("unchecked") // it is here for a reason :)
       public T[] array = (T[]) new Object [1];
   }

   public static void main(String [] args)
   {
       A<Integer> clazzA = new A<Integer>();
       System.out.println(((Integer[])((Object[])clazzA.array))[0]);
   }
}
{code}
 

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Updated: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

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

Yonik Seeley updated SOLR-2410:
-------------------------------

    Attachment: SOLR-2410.patch

Here's a patch that reverts back to a normal PQ (non-generified).  This minimizes the chance of another generics related bug here since the code is so hard to hit.

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>         Attachments: SOLR-2410.patch
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Updated: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

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

Yonik Seeley updated SOLR-2410:
-------------------------------

    Attachment: SOLR-2410.patch

Here's the patch with a test added that normally manages to trip the exception.

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>         Attachments: SOLR-2410.patch, SOLR-2410.patch
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/SOLR-2410?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13003843#comment-13003843 ]

Dawid Weiss commented on SOLR-2410:
-----------------------------------

Yep, sorry for belated follow up, I went to sleep last night ;) The workaround is to access T[] as an Object[] -- the actual type of the object that is stored in that field. I like reverting to Object[] much more since this "feature" is quite nasty and puzzling, especially for people who haven't seen it before (I have seen it a few times, for example here: http://issues.carrot2.org/browse/HPPC-46). Glad I could help.

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>         Attachments: SOLR-2410.patch, SOLR-2410.patch
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[jira] Resolved: (SOLR-2410) ConcurrentLRUCache can throw class cast exception

JIRA jira@apache.org
In reply to this post by JIRA jira@apache.org

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

Uwe Schindler resolved SOLR-2410.
---------------------------------

    Resolution: Fixed

This was fixed by trunk revision: 1079707 (through LUCENE-2953)

> ConcurrentLRUCache can throw class cast exception
> -------------------------------------------------
>
>                 Key: SOLR-2410
>                 URL: https://issues.apache.org/jira/browse/SOLR-2410
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0
>            Reporter: Yonik Seeley
>             Fix For: 4.0
>
>         Attachments: SOLR-2410.patch, SOLR-2410.patch
>
>
> ConcurrentLRUCache throws a class cast exception.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]