Undefined Behavior Causing ClassCastException

Discussion in 'Plugin Development' started by Icyene, Aug 25, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Icyene

    Hello!

    I am trying to make a function to which you give a block, a List<Integer[]>, and it transforms the rules based on:

    Iterating through the list until the Integer Array [0] is equal to the block.getTypeId(), and then setting it to Integer Array[1].

    My code:

    Code:
    public void transform(Block toTransform,
            List<Integer[]> transformations) {
    
        final int blockId = toTransform.getTypeId();
    
        for (Integer[] toCheck: transformations) {
            if (toCheck[0] == blockId) {
            toTransform.setTypeId(toCheck[1]);
            return;
            }
    
        }
    
        }
    
    A simple enough function. The List<Integer[]> I am giving it is:

    Code:
    public List<Integer[]> aListIntegerArray = Arrays
            .asList(new Integer[][] {
                { 18, 0 }, { 2, 3 }, { 1, 4 } });
    
    And yet it throws this exception:

    Code:
    java.lang.ClassCastException: java.util.ArrayList cannot be cast to [Ljava.lang.Integer;
    
    It might be just me, but I do not see where I am trying to cast from an arraylist to an integer. Heck, I'm not even using integers. The exception occurs on this line:

    Code:
    for (Integer[] toCheck: transformations) {...
    
    But from what I know that shouldn't cause any problems.

    Any help would be greatly appreciated!
     
  2. Offline

    Giant

    Your list holds only an Integer[], yet you are attempting to assign it an Integer[][], now admittedly I don't use basic java arrays alot, but I think this is your issue?
     
  3. Offline

    Icyene

    Mmm... How could I have missed that... Yes, I've changed to Integer[], yet the error persists...
     
  4. Offline

    Courier

    Hmm... Maybe try using int[]? I'm pretty sure you can use primitive arrays in generics.
     
  5. Offline

    Icyene

  6. Offline

    Courier

    I just tried this, and it works fine:
    Code:java
    1. public static void main(String[] args)
    2. {
    3. int[][] intArAr = new int[][] {{00, 01}, {10, 11}, {20, 21}};
    4.  
    5. List<int[]> intArList = Arrays.asList(intArAr);
    6.  
    7. int[][] intArAr2 = new int[3][2];
    8. intArList.toArray(intArAr2);
    9.  
    10. System.out.println("array:");
    11. for(int[] k : intArAr)
    12. System.out.println(String.format("{%1$02d, %2$02d}", k[0], k[1]));
    13.  
    14. System.out.println("list:");
    15. for(int[] k : intArList)
    16. System.out.println(String.format("{%1$02d, %2$02d}", k[0], k[1]));
    17.  
    18. System.out.println("array 2:");
    19. for(int[] k : intArAr2)
    20. System.out.println(String.format("{%1$02d, %2$02d}", k[0], k[1]));
    21. }
    Output:
    Code:
    array:
    {00, 01}
    {10, 11}
    {20, 21}
    list:
    {00, 01}
    {10, 11}
    {20, 21}
    array 2:
    {00, 01}
    {10, 11}
    {20, 21}
     
  7. Offline

    Sagacious_Zed Bukkit Docs

    If you don't know what you are doing with reflection, safer if you stay away from it.

    But from the stack trace i would say you are trying to set an array into yaml, which you cannot do, use a java collection.
     
  8. Offline

    Giant

    Just tested it with your code, well the array part anyhow, and it seems to me it converts in the way it should.

    Edit: actually, what bothers me in your issue, now that I look at it, is that it seems to send an ArrayList, though Arrays.asList, returns a List. Are you absolutely certain that is the line the issue occurs on?
     
  9. Offline

    Icyene

    I do know how to use reflection. I've known how to use it for 2 years now :) The error itself doesn't seem to haveto do with the way I'm configuring, rather that snakeyaml can't add int[] (which as you said).

    The traceback says "Primitive arrays are not yet fully supported at this point". I guess by that they mean that int[] aren't supported. However, I have tested it with Integer[], String[] et al, and it worked fully.
     
  10. Offline

    Sagacious_Zed Bukkit Docs

    yea, Integer and String are not primitives.
     
  11. Offline

    Giant

    Are you absolutely certain that that line is what is causing the issue? As the reason I've stated in my previous post seems a bit off for that line...
     
  12. Offline

    Icyene

    So you tried the transformations and they worked without errors? Yes, I am absolutely, 101% sure that it is that line. I'll try List<List<Integer>> and see if that changes anything.
     
  13. Offline

    Giant

    I have indeed made the List<Integer[]> using your method, and have also successfully looped trough it using your for loop. (for(Integer[] toCheck : transformations)). I therefore came to the conclusion that this was not the issue. And went back to looking at your error, and figured it to be odd that it is thrown as ArrayList, seeing how trying to store the creation of the List<Integer[]> into an ArrayList<Integer[]> throws an error...

    Of course that might be because I forgot a type cast or such, but yea, seemed odd to me...
     
  14. Offline

    Icyene

    Giant Fixed it. When faced with stupid errors do stupid things. The list is now a List<List<Integer>>, and my method looks like this:

    Code:
    public void transform(Block toTransform,
            List<List<Integer>> transformations) {
    
        final int blockId = toTransform.getTypeId();
    
        for (List<Integer> toCheck: transformations) {
            if (toCheck.get(0) == blockId) {
            toTransform.setTypeId(toCheck.get(1));
            return;
            }
    
        }
    
        }
    
    While it does work, it does not get to the root of why it was failing before. Ah well.
     
  15. Offline

    Giant

    Well, for the reason why it fails, I think we should actually go a step further back! As in the place where you actually call "transform".
     
  16. Offline

    Icyene

    Basically this:

    Code:
    Storm.util.transform(strikeLocation.getBlock(),
                Storm.config.Lightning_Melter_Block__Transformations);
    
    Where the array is 12, 20. Basically at this point it makes sand melt into glass when struck. Storm.util is where the transform method is. The Lighting.... is the List<Integer[]>. strikeLocation is the location of the strike. Obviously :p
     
  17. Offline

    Giant

    And why do I have a suspicion that this:
    Code:
    Storm.config.Lightning_Melter_Block__Transformations
    returns List<List<Integer>> instead of your own List<Integer[]> that you created before? :p
     
  18. Offline

    Icyene

    Perhaps... But I swear it was List<Integer> in the config class...
     
  19. Offline

    Giant

    It may go in as that, but what goes in, doesn't always come out! :D (As opposed to that what goes up must come down method, which is kind of flawed but oh well...)
     
Thread Status:
Not open for further replies.

Share This Page