On 14.08.2022 13:41, Rick McGuire wrote:
One question and a couple of suggestions.

- Is the AttachThread() being done on the same instance as the originating rexx code where the call on syntax was made or a different instance.
The same instance.
- The method NativeActivation::checkConditions() is where the raised exceptions are processed when your external routine returns. Understanding why that code is not raising the exception on the calling Rexx code would be helpful. - This might be easier to debug if you can take Java completely out of the picture. That is, have an external call that does an AttachThread(), does a SendMessage(), does a DetachThread(), then does a RaiseException() with the call context. I suspect you'll probably see the same problem, and that simple type of scenario would be much easier to debug.

Tried to come up with such a test case but have not been successful so far (those attempts caused the posting about ThrowException).

---rony




On Sun, Aug 14, 2022 at 7:24 AM Rony G. Flatscher <rony.flatsc...@wu.ac.at> 
wrote:

    Sorry, one thing is wrong in my synopsis (over the past days too many 
different test cases and
    attempts): the call to the Java side in this case is not carried out via 
the unknown method
    but directly with invoking the native routine BSF.

    ---

    The last thing I tried was making sure that in the native routine that 
creates the exception
    and carries out RaiseException1()  that it would use the RexxCallContext 
everywhere (and not
    use RexxCallContext-threadContext which should work anyway). It did not 
change this observation.

    The use of SetContextVariable() in the native routine that creates the 
exception works and the
    variables are available upon return to the BSF unknown method.

    In the meantime I added a native method BsfCheckCondition() and calling it 
immediately upon
    return to the Rexx side returns .false/0.

    ---rony

    On 14.08.2022 12:47, Rony G. Flatscher wrote:

    O.K. before trying one more thing "in the dark" here a synopsis:

      * all calls are carried out on the same thread (no multithreading)
      * Rexx starts, using BSF4ooRexx Java gets demand loaded, the native code 
stores the
        primodal Rexx instance ("ri")
      * a Rexx program sends a message to a Java object (a BSF instance)
      * the BSF unknown method defines a 'signal on syntax' condition handler 
and sets up and
        carries out the call to the native routine BSF()
          o the native routine BSF() sets up and carries out the call into Java
          o the Java method in this use case will cause a Rexx object to be 
sent a message, in
            the course the native code
              + ri->AttachThread(), sets up and carries out the call into Rexx
              + a Rexx condition occurs causing a Java Throwable to be created 
using the Rexx
                condition information
              + ri->DetachThread()
              + the Java Throwable gets thrown, control returns to Java
          o the Java method returns to native code with the thrown Java 
Throwable active
            (jenv->ExceptionCheck() returns true)
          o the native code creates a Rexx exception using data from the Java 
Throwable, adds the
            Java Throwable object to additional() to allow access from Rexx to 
it, then does a
            context->RaiseException1() wich is active (tested with 
RexxCondition() immediately
            before returning from native code to Rexx); here to illustrate that 
section, both
            tests (using the RexxCallContext and its contained threadContext) 
return true:
            #if defined (DEBUG_BSF_FUNCTION)
                 fprintf(stderr, "*** *** DEBUG_BSF_FUNCTION: BSF() 5c: about to return with NULL: 
context->CheckCondition()=%d | context->threadContext->CheckCondition()=%d\n", 
context->CheckCondition(), context->threadContext->CheckCondition());
                 fflush(stderr);
            #endif
                         return NULLOBJECT;
          o a return NULLOBJECT in native code returns to the Rexx caller (the 
unknown method)
      * the BSF unknown method does not transfer control to the syntax label, 
the condition has
        been cleared between returning from native code and transferring 
control back to the BSF
        unknown method

    ---rony



    On 12.08.2022 16:00, Rony G. Flatscher wrote:
    On 11.08.2022 21:13, Rony G. Flatscher wrote:

    In an ooRexx package there are the following statements:

        ... cut ...

        ::ROUTINE xBSF                   PUBLIC   EXTERNAL "LIBRARY BSF4ooRexx BSF   
              "

        ... cut ...

        ::CLASS BSF

        ::ATTRIBUTE rBSF CLASS

        ::METHOD init    CLASS
           expose rBSF
           rBSF =.routines["XBSF"]   -- fetch and store routine object
           ... cut ...

        ::METHOD unknown UNGUARDED
           ... cut ...
           signal on syntax

           self~class~rBSF~callWith(arr)  -- invoke external routine
           return bsf.wrap(result)
        syntax:
           ... cut ...
           co=condition('o')
           call ppJavaExceptionChain(co,.true)
           raise propagate

    So a native routine BSF() gets defined and named in the package as the 
public routine xBSF
    which in the class constructor for the class BSF gets fetched from the 
.routines directory
    and stored as a routine object with a class attribute named rBSF. In the 
BSF instance
    method unknown this routine object gets fetched from the class attribute 
and using CALLWITH
    it gets invoked supplying a Rexx array with arguments.

    The native routine BSF() in this case may raise an exception using

         rtc->RaiseException(Rexx_Error_Incorrect_call_user_defined, ra);

    However, upon return from the native routine BSF the raised exception does 
not get trapped
    in the ooRexx unknown method such that the code after the syntax label does 
not get executed.

    Doing instead

        res=xbsf("invoke", j4, "sendMessageScoped", "abc", "1", "2", "3")

    traps the rtc->RaiseException() condition ("abc" in this test will not 
yield a Rexx class
    object).

    Sorry, the above statement is not equivalent, it needs to be rewritten as

        jArgs=bsf.createJavaArrayOf("java.lang.Object", 1, 2, 3) -- with or 
without quotes
        res=xbsf("invoke", j4, "sendmessageScoped", "info", "abc", jArgs)

    it then behaves as within the unknown method. In this variant a "Error 
44.1:  No data
    returned from function "XBSF"." error will get raised.

    Here the version that is equivalent to the one in the unknown method and 
does not trigger
    the syntax handler on the Rexx code either:

        call xbsf "invoke", j4, "sendmessageScoped", "info", "abc", jArgs

    context->CheckCondition() immediately before returning to the calling Rexx 
program will be
    true in the native code however the syntax handler does not get triggered.

    For debugging purposes the native code defines context variables
    [context->SetContextVariable("BSF_ERROR_MESSAGE",msg) and
    context->SetContextVariable("BSF_ERROR_OBJECT",javaThrowable)] which are 
available and can
    be used from the caller's context (which the test program does).

    Tried to come up with a stand alone example that would exhibit this 
behaviour, so far
    without success.

    If there is anything I could do to become able to shed more light into 
this, please let me know.

_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to