JVM RunUnit - Call (String, Object []) Problem

Hello out there ...

I have the following JVM Cobol Programm "XUSERVG" (compiled with ILSMARTLINKAGE) ... stub below :

LINKAGE SECTION.
*----------------

01 SL-EXT-UEBERGABE PIC 9(7).
01 S-EXT-UEBERGABE.
 02 SHARK-LEN PIC X(2).
 02 EXT-UEBERGABE PIC X(50).

01 SL-USERVG-IO PIC 9(7).
01 S-USERVG-IO.
 02 SHARK-LEN PIC X(2).
 02 USERVG-IO PIC X(4085).


PROCEDURE DIVISION
USING
BY VALUE SL-EXT-UEBERGABE
BY REFERENCE S-EXT-UEBERGABE
BY VALUE SL-USERVG-IO
BY REFERENCE S-USERVG-IO.


The Call in Java looks like :

int SExtUebergabeLen = 815;
SExtUebergabe sExtUebergabe = new SExtUebergabe();
int SUservgIoLen = 4711;
SUservgIo sUservgIo = new SUservgIo();

XUSERVG xuservg = new XUSERVG ();

RunUnit runUnit = new RunUnit();

runUnit.Add((IObjectControl) xuservg);

// retValue = xuservg.XUSERVG(SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo);

Object params [] = {SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo};
retValue = runUnit.Call("de.lv1871.cobol.XUSERVG", params);

runUnit.StopRun();

The "direct" call to xuservg.XUSERVG (...) works like a charm. But using runUnit.Call ("de.lv1871.cobol.XUSERVG", params)
results in :

com.microfocus.cobol.program.COBOLProgramCallException: 181 Invalid parameter error [package de.lv1871.cobol.XUSERVG]
(argument type mismatch)
at com.microfocus.cobol.program.ProcedurePointer.callReturningObject(Unknown Source)
at com.microfocus.cobol.program.ProcedurePointer.callReturningObject(Unknown Source)
at com.microfocus.cobol.runtime.core.RuntimeSessionManager.staticExecuteObject(Unknown Source)
at com.microfocus.cobol.runtime.core.RuntimeSessionManager.staticExecute(Unknown Source)
at com.microfocus.cobol.runtime.core.RuntimeSessionManager.execute(Unknown Source)
at com.microfocus.cobol.runtimeservices.RunUnit.Call(Unknown Source)
at de.lv1871.cobol.javastubs.Uservg.callProgram(Uservg.java:48)
at de.lv1871.cobol.junit.UservgTestcase.testUservg(UservgTestcase.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
... 33 more

The documentation is now so helpfull on this topic. Maybe somebody has a clue what is going on.

Kind regards

Michael

  • You should be using either the RunUnit.Add method and then invoking the class that has been added directly or using the RunUnit.Call method to call a program that has not yet been instantiated or added.

    You should not be using both the Add and Call methods togerther.

    If you are using ilsmartlinkage then it is recommended that you use the following:

    RunUnit runUnit = new RunUnit();

    runUnit.Add(xuservg);

    int retValue = xuservg.XUSERVG(SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo);

    This will add the instantiated program to the new RunUnit and then call it using the parameter classes created by ilsmartlinkage.

    Thanks.

  • Hello,

    based on your answer I have tested two ways

    int SExtUebergabeLen = 815;
    SExtUebergabe sExtUebergabe = new SExtUebergabe();
    int SUservgIoLen = 4711;
    SUservgIo sUservgIo = new SUservgIo();

    RunUnit runUnit = new RunUnit();

    XUSERVG xuservg = (XUSERVG) getCallable(); // creates an instance of XUSERVG
    runUnit.Add((IObjectControl) xuservg);
    retValue = xuservg.XUSERVG(SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo);

    This works like a charm but runUnit.Call is not working (or at least I do not understand how to use it) so :

    int SExtUebergabeLen = 815;

    SExtUebergabe sExtUebergabe = new SExtUebergabe();
    int SUservgIoLen = 4711;
    SUservgIo sUservgIo = new SUservgIo();

    RunUnit runUnit = new RunUnit(); // XUSERVG is not instanciated and added to the RunUnit

    Object params [] = {SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo};
    retValue = runUnit.Call("de.lv1871.cobol.XUSERVG", params);

    Is resulting in the exception:

    com.microfocus.cobol.program.COBOLProgramCallException: 181 Invalid parameter error [package de.lv1871.cobol.XUSERVG]

    (argument type mismatch)
    at com.microfocus.cobol.program.ProcedurePointer.callReturningObject(Unknown Source)
    at com.microfocus.cobol.program.ProcedurePointer.callReturningObject(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.staticExecuteObject(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.staticExecute(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.execute(Unknown Source)
    at com.microfocus.cobol.runtimeservices.RunUnit.Call(Unknown Source)
    at de.lv1871.cobol.javastubs.Uservg.callProgram(Uservg.java:46)

    ......

    runUnit.Call would be much easier for me. I have LOTS of Calls to Cobol and I could make great use of the more generic Method "Call".

    Kind regards

  • Hello,

    based on your answer I have tested two ways

    int SExtUebergabeLen = 815;
    SExtUebergabe sExtUebergabe = new SExtUebergabe();
    int SUservgIoLen = 4711;
    SUservgIo sUservgIo = new SUservgIo();

    RunUnit runUnit = new RunUnit();

    XUSERVG xuservg = (XUSERVG) getCallable(); // creates an instance of XUSERVG
    runUnit.Add((IObjectControl) xuservg);
    retValue = xuservg.XUSERVG(SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo);

    This works like a charm but runUnit.Call is not working (or at least I do not understand how to use it) so :

    int SExtUebergabeLen = 815;

    SExtUebergabe sExtUebergabe = new SExtUebergabe();
    int SUservgIoLen = 4711;
    SUservgIo sUservgIo = new SUservgIo();

    RunUnit runUnit = new RunUnit(); // XUSERVG is not instanciated and added to the RunUnit

    Object params [] = {SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo};
    retValue = runUnit.Call("de.lv1871.cobol.XUSERVG", params);

    Is resulting in the exception:

    com.microfocus.cobol.program.COBOLProgramCallException: 181 Invalid parameter error [package de.lv1871.cobol.XUSERVG]

    (argument type mismatch)
    at com.microfocus.cobol.program.ProcedurePointer.callReturningObject(Unknown Source)
    at com.microfocus.cobol.program.ProcedurePointer.callReturningObject(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.staticExecuteObject(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.staticExecute(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.execute(Unknown Source)
    at com.microfocus.cobol.runtimeservices.RunUnit.Call(Unknown Source)
    at de.lv1871.cobol.javastubs.Uservg.callProgram(Uservg.java:46)

    ......

    runUnit.Call would be much easier for me. I have LOTS of Calls to Cobol and I could make great use of the more generic Method "Call".

    Kind regards

  • Hello,

    based on your answer I have tested two ways

    int SExtUebergabeLen = 815;
    SExtUebergabe sExtUebergabe = new SExtUebergabe();
    int SUservgIoLen = 4711;
    SUservgIo sUservgIo = new SUservgIo();

    RunUnit runUnit = new RunUnit();

    XUSERVG xuservg = (XUSERVG) getCallable(); // creates an instance of XUSERVG
    runUnit.Add((IObjectControl) xuservg);
    retValue = xuservg.XUSERVG(SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo);

    This works like a charm but runUnit.Call is not working (or at least I do not understand how to use it) so :

    int SExtUebergabeLen = 815;

    SExtUebergabe sExtUebergabe = new SExtUebergabe();
    int SUservgIoLen = 4711;
    SUservgIo sUservgIo = new SUservgIo();

    RunUnit runUnit = new RunUnit(); // XUSERVG is not instanciated and added to the RunUnit

    Object params [] = {SExtUebergabeLen, sExtUebergabe, SUservgIoLen, sUservgIo};
    retValue = runUnit.Call("de.lv1871.cobol.XUSERVG", params);

    Is resulting in the exception:

    com.microfocus.cobol.program.COBOLProgramCallException: 181 Invalid parameter error [package de.lv1871.cobol.XUSERVG]

    (argument type mismatch)
    at com.microfocus.cobol.program.ProcedurePointer.callReturningObject(Unknown Source)
    at com.microfocus.cobol.program.ProcedurePointer.callReturningObject(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.staticExecuteObject(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.staticExecute(Unknown Source)
    at com.microfocus.cobol.runtime.core.RuntimeSessionManager.execute(Unknown Source)
    at com.microfocus.cobol.runtimeservices.RunUnit.Call(Unknown Source)
    at de.lv1871.cobol.javastubs.Uservg.callProgram(Uservg.java:46)

    ......

    runUnit.Call would be much easier for me. I have LOTS of Calls to Cobol and I could make great use of the more generic Method "Call".

    Kind regards

  • I have been testing this here and there appears to be some limitations on the types of parameters that can be passed when using RunUnit.Call as everything has to be packaged into an Object [].

    In particular it doesn't seem to work well with the classes generated by ilsmartlinkage.

    I would recommend that you open up a support incident with customer care so we can research this issue further.

    Thanks

  • Verified Answer

    I believe that I have a solution for you.

    The objects that are being generated by the ilsmartlinkage directive need their reference to be passed rather than the object itself, eg:

         Object params [] = {SExtUebergabeLen, sExtUebergabe.get_Reference(), SUservgIoLen, sUservgIo.get_Reference()};

    I tried this here with my test program and it then worked successfully.

    Thanks.

  • Many thanks. This works perfect. I think you should update the documentation with this infomation.

  • I agree and I have reported this to our docs folks as a bug and it will be added to the documentation in a subsequent product release.

    Thanks.