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;
publicclassTestJava{
publicstaticvoidtestByteArr(byte[] keyBytes){
System.out.println("keyBytes getClass() = " + keyBytes.getClass() );
System.out.println("keyBytes toString() = " + keyBytes.toString() );
}
publicstaticvoidtestByte(byte obj){
System.out.println("byte getClass() = " + ((Object)obj).getClass().getName() );
System.out.println("byte toString() = " + ((Object)obj).toString() );
}
publicstaticvoidtestStr(String obj){
System.out.println("obj getClass() = " + ((Object)obj).getClass().getName() );
System.out.println("obj toString() = " + obj );
}
publicstaticvoidtestObj(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") // worksdo test.testByte($C(40)) // workstry {
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...
Comments
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)Thank you @Enrico Parisi -- works perfectly.
I learned two things... the %getall/setall AND (the one I should have figured) that I could have set a primitive data type like set bytesArrayIn=javaGate.new("byte[3]") --- I hadn't thought that one through...
Thanks heaps - should help me complete this task