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.

---rony

P.S.: Here the Rexx test program:

   parse source  s; say s
   parse version v; say v
   say .bsf4rexx~display.version
   call test_plain_rexx
   call test_rexx_proxy

   ::requires BSF.CLS

   ::class class_level1
   ::method info
      return "info<< CLASS_LEVEL1 >>info <<arg()="arg()">>"

   ::class class_level2 mixinclass class_level1
   ::method info
      return "info<< CLASS_LEVEL2 >>info <<arg()="arg()">>"

   ::class class_level3 mixinclass class_level1
   ::method info
      return "info<< CLASS_LEVEL3 >>info <<arg()="arg()">>"

   ::class class_level4 subclass class_level2 inherit class_level3
   ::method info
      return "info<< CLASS_LEVEL4 >>info <<arg()="arg()">>"

   ::routine test_plain_rexx
       say .context~name":"
       say
       t4=.class_level4~new
       say "t4~info:" t4~info
       say "t4~info:" t4~info(1,2,3)
       say "t4~info:class_level3:" t4~info:.class_level3
       say "t4~info:class_level2:" t4~info:.class_level2
       say "t4~info:class_level1:" t4~info:.class_level1
       say "-"~copies(79)


   ::routine test_rexx_proxy -- via Java
       say .context~name":"
       say
       t4=.class_level4~new
       say "t4~info:" t4~info

       j4=BsfCreateRexxProxy(t4)   -- will box the Rexx object in a Java object 
(of type RexxProxy which allows sending messages to the boxed Rexx object)

       -- now send the boxed Rexx object various messages from the Java side

       say "j4:" pp(j4) "j4~sendMessage0('info'):" j4~sendMessage0('info')
       say "j4:" pp(j4) "j4~sendMessage3('info',1,2,3):" 
j4~sendMessage3('info',1,2,3)
       say "-"~copies(79)

       say "j4:" pp(j4) "j4~sendMessageScoped('info',.class_level3,.nil):" 
j4~sendMessageScoped('info', .class_level3, .nil)
       say "j4:" pp(j4) "j4~sendMessageScoped('info',.class_level2,.nil):" 
j4~sendMessageScoped('info', .class_level2, .nil)
       say "j4:" pp(j4) "j4~sendMessageScoped('info',.class_level1,.nil):" 
j4~sendMessageScoped('info', .class_level1, .nil)

       jArgs=bsf.createJavaArrayOf("java.lang.Object", 1, 2, 3) -- arguments 
must be boxed as a Java array object
       say "j4:" pp(j4) "j4~sendMessageScoped('info',.class_level3,.nil):" 
j4~sendMessageScoped('info', .class_level3, jArgs)
       say "j4:" pp(j4) "j4~sendMessageScoped('info',.class_level2,.nil):" 
j4~sendMessageScoped('info', .class_level2, jArgs)
       say "j4:" pp(j4) "j4~sendMessageScoped('info',.class_level1,.nil):" 
j4~sendMessageScoped('info', .class_level1, jArgs)
   -- up to here everything works already
   say

   -- intentionally creating a syntax condition: the string ABC does not denote 
a class object, hence
   -- a condition must be raised
   signal on syntax
       say "--->hi from test.rex"
       -- j4~sendMessageScoped('info', abc          , jArgs)
       say "j4:" j4
       -- res=xbsf("invoke", j4, "sendmessageScoped", "info", "abc", jArgs)
       call xbsf "invoke", j4, "sendmessageScoped", "info", "abc", jArgs

       -- we never should get here, but we do
       say "result:" result   -- there is no result so
       say "\-/"~copies(40)
       say
       say "BSF_ERROR_MESSAGE:"
       say bsf_error_message
       say
       say "\-/"~copies(40)
       say "BSF_ERROR_OBJECT:"
       say BSF_ERROR_OBJECT
       say "\-/"~copies(40)
       say "BSF_ERROR_OBJECT~toString:" BSF_ERROR_OBJECT~toString
       say "\-/"~copies(40)
       cause=BSF_ERROR_OBJECT~getCause
       say
       say "cause:" cause
       say "\-/"~copies(40)
       str=cause~toString
       say
       say "getCause~toString:" pp(str)
       say "\-/"~copies(40)
       -- j4~sendMessageScoped('info', abc          , jArgs)
       say "<---hi from test.rex"
       return


   syntax:   -- signal on syntax
       co=condition('o')
       call ppJavaExceptionChain(co,.true) -- show chain of Java Throwables
       say .line": test.rex" "--"

       raise propagate

The output currently:

   F:\work\svn\bsf4oorexx\branches\850\bsf4oorexx.dev\source_cc>test
   WindowsNT COMMAND 
F:\work\svn\bsf4oorexx\branches\850\bsf4oorexx.dev\source_cc\test.rex
   REXX-ooRexx_5.0.0(MT)_64-bit 6.05 10 Aug 2022
   ooRexx 5.0.0 r12499 (10 Aug 2022) / BSF 850.20220811 / Java 17.0.3.1 
(released: 2022-04-22), 64-bit (amd64) / Windows 10.0.19043
   TEST_PLAIN_REXX:

   t4~info: info<< CLASS_LEVEL4 >>info <<arg()=0>>
   t4~info: info<< CLASS_LEVEL4 >>info <<arg()=3>>
   t4~info:class_level3: info<< CLASS_LEVEL3 >>info <<arg()=0>>
   t4~info:class_level2: info<< CLASS_LEVEL2 >>info <<arg()=0>>
   t4~info:class_level1: info<< CLASS_LEVEL1 >>info <<arg()=0>>
   
-------------------------------------------------------------------------------
   TEST_REXX_PROXY:

   t4~info: info<< CLASS_LEVEL4 >>info <<arg()=0>>
   j4: [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] j4~sendMessage0('info'): info<< 
CLASS_LEVEL4 >>info <<arg()=0>>
   j4: [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] j4~sendMessage3('info',1,2,3): info<< 
CLASS_LEVEL4 >>info <<arg()=3>>
   
-------------------------------------------------------------------------------
   j4: [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] 
j4~sendMessageScoped('info',.class_level3,.nil): info<< CLASS_LEVEL3 >>info 
<<arg()=0>>
   j4: [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] 
j4~sendMessageScoped('info',.class_level2,.nil): info<< CLASS_LEVEL2 >>info 
<<arg()=0>>
   j4: [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] 
j4~sendMessageScoped('info',.class_level1,.nil): info<< CLASS_LEVEL1 >>info 
<<arg()=0>>
   j4: [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] 
j4~sendMessageScoped('info',.class_level3,.nil): info<< CLASS_LEVEL3 >>info 
<<arg()=3>>
   j4: [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] 
j4~sendMessageScoped('info',.class_level2,.nil): info<< CLASS_LEVEL2 >>info 
<<arg()=3>>
   j4: [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] 
j4~sendMessageScoped('info',.class_level1,.nil): info<< CLASS_LEVEL1 >>info 
<<arg()=3>>

   --->hi from test.rex
   j4: org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994
   result: RESULT
   
\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/

   BSF_ERROR_MESSAGE:
   BSF4ooRexx/routine/BSF(), error 3: Java exception occurred: 
[org.apache.bsf.BSFException: BSF4ooRexx subfunction "invoke":
            bean:        [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] --> type: 
<org.rexxla.bsf.engines.rexx.RexxProxy>
            method:      [sendmessageScoped] not found or execution error!

            -> check method name=[sendmessageScoped] (caseless o.k., but 
correct spelling?)
            -> check supplied arguments (correct number, correct types?):
                    arg # 1: Rexx argument=[info] --> Java value="info" 
type=<java.lang.String>
                    arg # 2: Rexx argument=[abc] --> Java value="abc" 
type=<java.lang.String>
                    arg # 3: Rexx argument=[[Ljava.lang.Object;@aec6354] --> Java 
value="[Ljava.lang.Object;@aec6354" type=<[Ljava.lang.Object;>
   ]

   
\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/
   BSF_ERROR_OBJECT:
   org.apache.bsf.BSFException@1963006a
   
\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/
   BSF_ERROR_OBJECT~toString: org.apache.bsf.BSFException: BSF4ooRexx subfunction 
"invoke":
            bean:        [org.rexxla.bsf.engines.rexx.RexxProxy@6ae40994] --> type: 
<org.rexxla.bsf.engines.rexx.RexxProxy>
            method:      [sendmessageScoped] not found or execution error!

            -> check method name=[sendmessageScoped] (caseless o.k., but 
correct spelling?)
            -> check supplied arguments (correct number, correct types?):
                    arg # 1: Rexx argument=[info] --> Java value="info" 
type=<java.lang.String>
                    arg # 2: Rexx argument=[abc] --> Java value="abc" 
type=<java.lang.String>
                    arg # 3: Rexx argument=[[Ljava.lang.Object;@aec6354] --> Java 
value="[Ljava.lang.Object;@aec6354" type=<[Ljava.lang.Object;>

   
\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/

   cause: org.rexxla.bsf.engines.rexx.RexxException@41975e01
   
\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/

   getCause~toString: [org.rexxla.bsf.engines.rexx.RexxException: 
BSF4ooRexx/routine/jniRexxSendMessageToRexxObject(), error 4b: argument 
scope=[abc
   ] does not resolve to an ooRexx class object]
   
\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/
   <---hi from test.rex


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

Reply via email to