0

For a project of mine i am working with the Java Native Interface (JNI).

My project contains a JNI System that calls a function on de C++ side with a port parameter. This function than returns a Object array as written in the comments below, the problem is stated in the last comment:

public Integer SpawnNewConnectionHandler(Integer Port) throws WrapperException {
    //Creation of the object array that will hold the result
    Object[] result;

    //Get the result object array from the external library. Length of the array is either 1 or 2.
    //While debugging i found out that it contains two elements of the type int (Not integer, but its basetype).
    //This means that nothing on the c++ side went wrong.
    result = spawnNewServerConnectionHandler(Port);

    //Error coming from the SDK should be handled here. (Code snipped as the if clause checking for it, is not being called.)
    //The snipped will throw a WrapperException if the length of the array returned is not 1.

    //The debugger will break here and show me that before executing this line both of the result objects are not empty,
    //So result[0] and result[1] are filled with data, for result[1] it is a 1 or higher. For result[0] is is the number 0. (Returned as a fact that everything went alright while executing.)
    //During execution of this line the program crashes and shows a NullPointerException.
    //
    //I found out that it is impossible for it to cast the object, stored in the object array as a int into a Integer.
    //Doing this manually while debugging shows the following error message:
    //"Unable to cast numeric value to java.lang.Integer."
    return (Integer) result[1];
}

Does anybody know a solution to this problem, or at least why it is giving me this weird error?

Filburt
  • 17,626
  • 12
  • 64
  • 115
  • Have you tried declaring `Object[] result` as `int[] result`? I suspect you've got a primitive array, in which case your return would look like `Integer.valueOf(result[1])`. – sigpwned Feb 02 '14 at 16:24
  • sigpwned, i do have a ObjectArray containing Integers that is returned by the external library. If i try to cast that is gives me an error, while compiling, and it says that the two types are incompatible. – user3263144 Feb 02 '14 at 17:06
  • there is a difference between a `int[]` and an `Integer[]` array. Namely, the first is a primitive type, and the second is an object type. Based on your comment below about `{int[2]@2559}`, it's clear you have a primitive array on your hands. Just a moment -- I'll respond with some code I think it would be useful to try. – sigpwned Feb 02 '14 at 17:41
  • Yeah i know, but the conversion does somehow not work, the compilers throws an error complaining about incompatible types, expecting int[] found java.lang.object[]. – user3263144 Feb 02 '14 at 19:21

2 Answers2

1

Casting does not change the type of the object. In order to cast result[1] to Integer, result[1] must BE an integer already.

You do not say what type of objects are in the array. I know the array is declared Object, but that means that the objects in the array could be anything, since any object can be a subclass of object.

You say the values in the arrays have values, but you do not say how you know that or what kind of values you have. The error message you sort-of give doesn't really match your sort-of explanation. So it's hard to say exactly what is going on. But you don't have an Integer object to cast, that's why the cast doesn't work.

arcy
  • 12,845
  • 12
  • 58
  • 103
  • While debugging i stop the code before executing the return line and it says result = {int[2]@2559} (the last four numbers change as it is the memory location). – user3263144 Feb 02 '14 at 17:03
  • I agree this appears to be an array of int -- I presume you can return "new Integer(result[1]);" – arcy Feb 02 '14 at 21:44
1

Based on your comment to @rcook, it appears that you have an int[] array, not an Integer[]. The difference here is that int is a primitive type and Integer is an object type.

Try this:

public Integer SpawnNewConnectionHandler(Integer Port) throws WrapperException {
    //Creation of the object array that will hold the result
    int[] result;

    //Get the result object array from the external library. Length of the array is either 1 or 2.
    //While debugging i found out that it contains two elements of the type int (Not integer, but its basetype).
    //This means that nothing on the c++ side went wrong.
    result = (int[]) spawnNewServerConnectionHandler(Port);

    //Error coming from the SDK should be handled here. (Code snipped as the if clause checking for it, is not being called.)
    //The snipped will throw a WrapperException if the length of the array returned is not 1.

    //The debugger will break here and show me that before executing this line both of the result objects are not empty,
    //So result[0] and result[1] are filled with data, for result[1] it is a 1 or higher. For result[0] is is the number 0. (Returned as a fact that everything went alright while executing.)
    //During execution of this line the program crashes and shows a NullPointerException.
    //
    //I found out that it is impossible for it to cast the object, stored in the object array as a int into a Integer.
    //Doing this manually while debugging shows the following error message:
    //"Unable to cast numeric value to java.lang.Integer."
    return Integer.valueOf(result[1]);
}

Note that I've replaced all references to Object[] with int[].

sigpwned
  • 6,957
  • 5
  • 28
  • 48
  • I tried that, it gives an incompatible type error; expected int[] found java.lang.object[] when i try to compile it. – user3263144 Feb 02 '14 at 19:20
  • Did you write the JNI declaration for `spawnNewServerConnectionHandler()`? If so, you may need to change the declaration return type to `int[]`. – sigpwned Feb 02 '14 at 20:04
  • Yes i wrote the JNI Declaration using javah. And i know it works if i let it return an jIntArray. But that is not solving the problem in the long run. My second JNI function that i need to call after this returns both a string and a integer. Which means that i need to use a object array instead of a int[]. So i thought why not try to implement a general method and use the same system for both. – user3263144 Feb 02 '14 at 20:54
  • That's a very different concern than the one you posted! The code you posted isn't working because you're trying to treat an `int[]` like an `Integer[]`. If you need to know how to create an `Object[]` or an `Integer` in JNI, you may find [this question](http://stackoverflow.com/questions/7260376/how-to-create-an-object-with-jni) useful. However, you'd probably be better off returning a custom object that contains a `String` and an `int` rather than an `Object[]`. – sigpwned Feb 02 '14 at 21:29
  • Is it actually possible to do such kind of things with JNI, i mean use custom objects? Hmm that would be a nice concept actually. I will take a look at it thanks for the tip! – user3263144 Feb 02 '14 at 21:40