Installation and getting reported bug: - unzip the zip-archive, change into subdirectory - make sure Java can be found, e.g. issue "java -version" on the command line - if Java cannot be found, locate "java.exe" and add its path to the environment variable PATH before proceeding; - Java must be of the same bitness as ooRexx - run "createSetupFile.rex" which creates a "setEnv.cmd" - run generated "setEnv.cmd" which sets the environment (PATH and CLASSPATH) - the Rexx scripts that demonstrate the problem can be started either with (Rexx will execute the script): rexx.exe PROBLEM_*.testGroup > out.txt 2>&1 or (Java will load Rexx and then execute the supplied script): rexxj2.cmd PROBLEM_*.testGroup > out.txt 2>&1 - it may be the case, that the scripts need to be executed multiple times, before exhibiting the reported problem (alternate the starting with "rexx" and "rexxj2") Addtional information: Setup used when reported bug was witnessed: - ooRexx 4.2.0, 32-bit - ooTestUnit, 4.2.0, Snapshot 6 (from ooRexx-sourceforge file section; files enclosed in zip archive) - BSF4ooRexx (latest beta, enclosed in zip archive) - tested with 32-bit Java 1.7 (build 1.7.0_80-b15) Execution of Rexx scripts: - original ooRexx thread invokes the Java JSR-223 support, where (on the Java side via JNI) another Rexx interpreter instance gets created and used to execute the supplied ooRexx script in the same thread, then returning to the caller -> so in this setup there are two different Rexx interpreter instances that run in the same thread (one Rexx interpreter instance is created and controlled via the JSR-223 framework, ie. the javax.script package introduced in Java 6) - the supplied Rexx script gets the testgroup instance ("self") as an argument to allow it to send assert messages without incurring any additional overhead Problem scripts and brief description: 1 subdirectory PROBLEM_01_UNINIT ================================ To run (you may have to repeat this a couple of times before becoming able to see the reported problem, sometimes there are even crashes) enter: rexx PROBLEM_UNINIT_JSR_223.testGroup > uninit_test_01.txt 2>&1 rexxj2 PROBLEM_UNINIT_JSR_223.testGroup > uninit_test_01.txt 2>&1 ------------------- "PROBLEM_UNINIT_JSR_223.testGroup" will eventually exhibit two different problems: 1 too many stack frames for UNINIT methods (as if part of the stack frames are from another method) - just look-up the *txt-files and search the string "BSF.CLS: BSF_REFERENCE::UNINIT()" which are followed by the erroneous stack frames listed from within the UNINIT method 2 UNINIT method run in any Rexx interpreter instances, instead of being run in the interpreter instance which created the object (the INIT method was carried out); the problem for BSF4ooRexx: each Rexx proxy that gets created for a Java object in the Rexx INIT method will assign the index name used for storing the Java object in the BSF registry; the UNINIT method then will deregister the reference to the Java object in the BSF registry and if that reference counter drops to 0, the Java object will get deregistered on the Java side; the code was developed and worked under the assumption that like .local the INIT and UNINIT method run in the same Rexx interpreter instance. At the Java side a RexxAndJava object gets created for each Rexx inteprerter instance (actually by separate instances of BSFManager). Each BSFManager maintains its own copy of the Java BSF registry to which Rexx scripts executed via the BSFManager's RexxAndJava object get access to, knowing the index value used to store the Java object. Now, if ooRexx runs the UNINIT methods on either Rexx interpreter instance it may be the case that the wrong BSF registry gets the references to the Java objects reduced, eventually removing the Java object. Any subsequent invocation of a method on the Rexx proxy will yield a runtime error, as now the method is run against the index string value supplied to RexxAndJava. As the destructor method is a very special method (like the constructor) in the lifetime of an object it should be run by the Rexx interpreter instance that ran the constructor method. (Maybe each Rexx object has a field with the Rexx interpreter instance pointer stored with it, such that when processing pending UNINIT messages the interpreter instance could easily determine by inspecting the target object whether to run or skip an UNINIT message). Here are arbitrary text-files that captured the output of some test-runs: "uninit_run_01.txt" ------------------- This run stopped with an error, caused by sending the Rexx proxy a message for the Java object, but the Java object got deregistered from the Java BSF registry in the meantime. The Java pendants for the two Rexx interpreter instances are "RexxAndJava@789869" (R1, Rexx interpreter instance # 1) and "RexxAndJava@1de4376" (R2, Rexx interpreter instance # 2). For the Java object "javax.script.SimpleBindings@25491d" there is one Rexx proxy (an instance of the Rexx class BSF in BSF.CLS) created in R1 only, but multiple Rexx proxy objects in R2. The Rexx proxies in R2 are the ones that get garbage collected at runtime, however the UNINIT method of the R2 Rexx objects are sometimes run in the context of R1, causing the R1 Java BSF registry to be affected. The first Rexx proxy object, representing "SimpleBindings@25491d", gets created in line # 117, in R1 (its identityHash~d2x is [FE5051C]). The Rexx proxy object (using "~identityHash~d2x") [FE7D928], representing "SimpleBindings@25491d" got created in R2 (line # 3426). R1 runs the uninit of that Rexx proxy object (line # 4466) causing the removal of the Java object from the Java BSF registry of R1. Later, when using that Rexx proxy object in the still running Rexx script in R1 will yield the error in line # 5824. "uninit_run_02.txt" ------------------- This run happened to run successfully to its end (no failures, no errors). "uninit_run_03.txt" ------------------- This run exhibits a runtime error due to the same reason as in "uninit_run_01.txt", just at a different point in time during its execution. 2 subdirectory PROBLEM_02_ARG ============================= To run (you may have to repeat this a couple of times before becoming able to see the reported problem, sometimes there are even crashes) enter: rexx PROBLEM_ARG_JSR_223_rexx.testGroup > arg_test_01.txt 2>&1 rexxj2 PROBLEM_ARG_JSR_223_rexx.testGroup > arg_test_01.txt 2>&1 ------------------- "PROBLEM_ARG_JSR_223_rexx.testGroup" will eventually exhibit two problems in the Rexx script that gets run via JSR-223, i.e. in the Rexx interpreter instance # 2 (R2) in the Rexx program defined in the lines 134-191 and executed via JSR-223 in line # 203 ('res=re~eval(rexxCode)'): "arg_run_01.txt" ---------------- This run will exhibit an error in the statement defined in line # 144 ("use arg jobj, nrEntries"), where neither arguments seem to be given, such that instead their names (strings in uppercase) are used instead. In this run this occurred in the 42nd loop executing that Rexx script. "arg_run_02.txt" ---------------- This run will exhibit an error in the ARG()-BIF used in the statement in line # 142 (the line "sdir=bsf.scriptContext2Rexx(arg(arg())~scriptContext) -- a Rexx directory ..."). The last argument will always be a Rexx directory object that has an entry named "scriptContext". After executing flawlessly and repeatedly (running the Rexx program without changing anything), all of a sudden a string "CMD" gets returned instead! Line # 44915 in "arg_run_02.txt" depicts the Rexx script that gets executed (defined in the loop in the lines # 199-206 in "PROBLEM_ARG_JSR_223_rexx.testGroup") and in line # 45014 the actual loop number is documentd: 46. So this run successfully executed the same code 45 times already! 3 subdirectory PROBLEM_03_BLOCK =============================== To run enter either: rexx PROBLEM_UNINIT_JSR_223.testGroup > block_test_01.txt 2>&1 or rexxj2 PROBLEM_UNINIT_JSR_223.testGroup > block_test_01.txt 2>&1 After a few seconds press repeatedly "Ctl-C" to end the hanging program. ------------------- "PROBLEM_BLOCK_JSR_223_rexx.testGroup" will immediately exhibit the problem, that it hangs when executing the "STRING" method (but not any of the assert-methods). Adding the unguarded keyword to the string method (in OOREXXUNIT.CLS, class "TestCase") has not changed that behaviour. "PROBLEM_BLOCK_JSR_223_rexx.testGroup" (running in the Rexx interpreter instance # 1, R1) defines a Rexx script in the lines 102-131 and when invoking it via JSR-223 (which creates and uses another Rexx interpreter instance # 2, R2) "self" is supplied as an argument to allow that script to excercise asserts, which works. However, when getting the default string value from that Rexx object in R2 (explicitly or implicitly invoking the "string" method) the program hangs. "block_run_01.txt" ------------------ This run will show the output until the program hangs/blocks. Line # 140 will show the output from the Rexx script being executed in R2 until it hangs (line # 427, "Rexx Program #2g: jobj~string: (as of 2015-07-25 will block, unguarding string-method in class TestCase does not help)"). Vienna, 2015-07-26, Rony G. Flatscher