Question
· Jan 14

IRIS (External language) JavaGateway - how to pass byte[] to Java Method

As part of a migration project from a bunch of java classes to IRIS, we need to maintain a few jar files due to some external dependencies.

The problem I am seeing is that I cannot pass a byte array ( byte[] ) from ObjectScript to the Java Class. I have tried a number of different ways

I have reproduced in a java class and Objectscript class:
Java Class:

package wrc;

public class TestJava {
    
    public static void testByteArr(byte[] keyBytes) {

        System.out.println("keyBytes getClass() = " + keyBytes.getClass() );
        System.out.println("keyBytes toString() = " + keyBytes.toString() );
    }

    public static void testByte(byte obj) {

        System.out.println("byte getClass() = " + ((Object)obj).getClass().getName() );
        System.out.println("byte toString() = " + ((Object)obj).toString() );
    }

    public static void testStr(String obj) {

        System.out.println("obj getClass() = " + ((Object)obj).getClass().getName() );
        System.out.println("obj toString() = " + obj );
    }

    public static void testObj(Object obj) {

        System.out.println("obj getClass() = " + ((Object)obj).getClass().getName() );
        System.out.println("obj toString() = " + obj.toString() );
    }

}

ObjectScript Class

Class POH.wrc Extends %RegisteredObject
{

ClassMethod testMe()
{

    #DIM javaGate As %External.JavaGateway = $SYSTEM.external.getJavaGateway()
    do javaGate.addToPath("C:\temp\wrc.jar")

    set test = javaGate.new("wrc.TestJava")

    do test.testStr("test string") // works
    do test.testByte($C(40)) // works
    try { 
        w !,"TRY #"_$I(TEST)
        do test.testByteArr($C(40) _ $C(41))
    } catch (e)
    {
        w " *** FAILED: " _ e.DisplayString()
    }

    try { 
        w !,"TRY #"_$I(TEST)
        set bArr = ##class(%ListOfDataTypes).%New()
        do bArr.Insert($C(40))
        do bArr.Insert($C(41))
        do test.testByteArr(bArr)
    } catch (e)
    {
        w " *** FAILED: " _ e.DisplayString()
    }

    try { 
        w !,"TRY #"_$I(TEST)
        #Dim arg As %Stream.GlobalBinary = ##Class(%Stream.GlobalBinary).%New()
        do arg.Write($C(40))
        do arg.Write($C(41))
        do test.testByteArr(arg)
    } catch (e)
    {
        w " *** FAILED: " _ e.DisplayString()
    }

    try { 
        w !,"TRY #"_$I(TEST)
        #Dim argc As %Stream.GlobalCharacter = ##Class(%Stream.GlobalCharacter).%New()
        do argc.Write($C(40))
        do argc.Write($C(41))
        do test.testByteArr(argc)
    } catch (e)
    {
        w " *** FAILED: " _ e.DisplayString()
    }
}

}

Each fail with:
TRY #x *** FAILED: <GATEWAY> java.lang.IllegalArgumentException sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) argument type mismatch

The String and Byte tests above work fine...

Product version: IRIS 2024.1
$ZV: IRIS for Windows (x86-64) 2024.1.2 (Build 398U) Thu Oct 3 2024 14:01:59 EDT
Discussion (2)2
Log in or sign up to continue

To exchange (in/out) ObjectScript collections (arrays/lists) and streams to/from Java using the new $system.external interface you use the "magical undocumented" %getall() and %setall() methods.

You can get some sample code of using it in the Open Exchange project samples-dynamicgateway-java.

For example for streams you can try something like:

        w !,"TRY #"_$I(TEST)
        #Dim argc As %Stream.GlobalCharacter = ##Class(%Stream.GlobalCharacter).%New()
        do argc.Write($C(40))
        do argc.Write($C(41))
		Set bytesArrayIn=javaGate.new("byte["_argc.Size_"]")
		Do bytesArrayIn.%setall(argc)
        do test.testByteArr(bytesArrayIn)