On 30.06.2023 09:44, Rony G. Flatscher wrote:
On 28.06.2023 17:26, Tom Ross wrote:
Please check out the examples in the COBOL Programming Guide, in
Part 6. Developing object-oriented programs

GO here:https://www.ibm.com/support/pages/node/611415
Select which release you are interested in and then
click "Product Documentation"

thank you, Tom. Could get to <https://www.ibm.com/support/pages/node/611415#64> and from there to the programming guide at <https://publibfp.dhe.ibm.com/epubs/pdf/igy6pg40.pdf>.

It seems that OO COBOL allows interacting with Java via JNI (Java native interface) only. 6.4 adds the ability to invoke static Java methods without OO COBOL.

Not having any of the necessary infrastructure (mainframe ;) , OO COBOL and Java) there is nothing I could do. So maybe just hinting of what would become possible if anyone with the OO COBOL-Java skills would come with showing how to code the following Java program in OO COBOL.

Such an example would serve as a nutshell example that would demonstrate how to invoke scripts from OO COBOL in any scripting language for which an implementation of javax.script.Engine exists including supplying arguments (stored in a Java array of type java.lang.Object) and fetching the result.

To make this as flexible (and thereby as usable) as possible, the following Java program will take the name of a file containing a script as a single argument, and then will load with the help of the Java scripting framework the appropriate scripting engine to execute the script, and supply as an argument the name of a Java system property which the script should return to the caller.

Here the Java code that should be transcribed to COBOL:

   import javax.script.*;
   import java.io.File;
   import java.io.FileReader;

   class Test
   {
        public static void main (String args[])
        {
            if (args.length==0)
            {
                System.err.println("file name missing...");
                System.exit(-1);
            }
            String fileName         = args[0];    // get filename
            String extension        = 
fileName.substring(fileName.lastIndexOf(".")+1);
            ScriptEngineManager sem = new ScriptEngineManager();
            ScriptEngine        se  = sem.getEngineByExtension(extension);

            Object result = null;
            try
            {
                ScriptContext sc    = se.getContext();
                    // add filename
                sc.setAttribute(se.FILENAME, fileName  , sc.ENGINE_SCOPE);
                    // add some arbitrary arguments
                Object scriptArgs[] = new Object [] { "first", "", "trois", null, 
"cinque" };
                sc.setAttribute(se.ARGV    , scriptArgs, sc.ENGINE_SCOPE);
                    // create a FileReader from File
                FileReader f        = new FileReader(new File(fileName));
                result=se.eval(f);  // read and execute script
            }
            catch (Throwable t)
            {
                System.err.println("Oops, some exception occurred: "+t);
            }
            System.out.println("script's result: "+result);
            System.exit(0);
        }
   }

Here a Rexx file (can be any Rexx script):

   parse source s
   say "source :" s
   parse version v
   say "version:" v
   say "there are" arg() "arguments supplied:"
   do i=1 to arg()
       say "   #" i":" arg(i)
   end
   return 43

The Java program "Test", once compiled can then be used to run any script (not only Rexx) from a script file where the file extension determines which scripting language should get loaded to run the script in the file. Here an example of running the Java program supplying the name of a file containing a Rexx script:

   G:\tmp\bsf4oorexx\cobol>java Test rexxscript.rex
   REXXout>source : WindowsNT SUBROUTINE rexxscript_ori.rex
   REXXout>version: REXX-ooRexx_5.1.0(MT)_64-bit 6.05 6 Jun 2023
   REXXout>there are 6 arguments supplied:
   REXXout>   # 1: first
   REXXout>   # 2:
   REXXout>   # 3: trois
   REXXout>   # 4: The NIL object
   REXXout>   # 5: cinque
   REXXout>   # 6: a Slot.Argument
   script's result: 43

---

The script code can also be supplied directly as a String to the script engine's eval() method "res=eval(String scriptCode)", such that you could load the script code from a database in case you have it stored as such. The possibilities are endless.

As you can see, one can submit any value/object as an argument to the script and fetch any result of the script.

---

It would be interesting to see the above Java code transcribed to COBOL, so anyone with the necessary skills please give a helping hand for the community! :)

The result would be enabling COBOL programmers to invoke any kind of scripts in any kind of languages from COBOL exploiting the Java scripting framework.

Such scripts could e.g. dive deep into Java and serve the COBOL programs probably in an easier manner from then on. E.g., the following ooRexx script returns a sorted list of all the Java system properties of the currently running JVM in a string array:

   clzSystem     = bsf.loadClass("java.lang.System")
   properties    = clzSystem~getProperties   -- get the System properties
   arrSortedKeys = properties~makeArray~sort -- let ooRexx sort the array
          -- create Java array of appropriate size
   strArray      = bsf.createJavaArray("java.lang.String", arrSortedKeys~items)
   do counter c key over arrSortedKeys
       strArray[c]=key":" properties~getProperty(key)
   end
   return strArray

   ::requires BSF.CLS      -- load the bidirectional ooRexx-Java bridge

As you can see everything becomes possible, only the sky is then the limit for COBOL programmers who become able to invoke such scripts. :)

Again, any COBOL programmers who would take on this little task?

---rony

Maybe one more idea: as 6.4 allows for using static Java methods one could come up with a Java class having static methods for running scripts from files and from strings. This way it is much easier for the COBOL programmer to invoke scripts.

Such a Java class could look like this:

   import java.io.File;
   import java.io.FileNotFoundException;
   import java.io.FileReader;
   import javax.script.ScriptContext;
   import javax.script.ScriptEngine;
   import javax.script.ScriptEngineManager;
   import javax.script.ScriptException;

   class ScriptingFramework4COBOL
   {
        public static void main (String args[]) throws ScriptException, 
FileNotFoundException
        {
            System.out.println( "runScriptFromFile("+args[0]+",null): "+
   runScriptFromFile(args[0],null));
            System.out.println("...");

            String scriptCode = "parse source s; say .dateTime~new':' s";
   System.out.println("runScriptFromString(\"rexx\","+scriptCode+"),null): "+
   runScriptFromString("rexx",scriptCode,null) );
            System.exit(0);
        }


        public static Object runScriptFromFile (String fileName, Object [] 
scriptArgs) throws
   ScriptException, FileNotFoundException
        {
            if (fileName == null)
            {
                throw new ScriptException ("fileName must not be null");
            }
            String extension        = 
fileName.substring(fileName.lastIndexOf(".")+1);
            ScriptEngineManager sem = new ScriptEngineManager();
            ScriptEngine        se  = sem.getEngineByExtension(extension);
            if (se == null)
            {
                throw new ScriptException ("cannot load script engine for extension: 
"+extension);
            }

            Object result = null;
            ScriptContext sc    = se.getContext();
                // add filename
            sc.setAttribute(se.FILENAME, fileName  , sc.ENGINE_SCOPE);
                // script arguments to add?
            if (scriptArgs != null)
            {
                sc.setAttribute(se.ARGV    , scriptArgs, sc.ENGINE_SCOPE);
            }
                // create a FileReader from File
            FileReader f        = new FileReader(new File(fileName));
            result=se.eval(f);  // read and execute script

            return result;
        }


        public static Object runScriptFromString (String scriptEngineName, 
String scriptCode,
   Object [] scriptArgs) throws ScriptException, FileNotFoundException
        {
            if (scriptEngineName == null)
            {
                throw new ScriptException ("scriptEngineName must not be null");
            }
            if (scriptCode == null)
            {
                throw new ScriptException ("scriptCode must not be null");
            }
            ScriptEngineManager sem = new ScriptEngineManager();
            ScriptEngine        se  = sem.getEngineByName(scriptEngineName);
            if (se == null)
            {
                throw new ScriptException ("cannot load script engine with name: 
"+scriptEngineName);
            }

            Object result = null;
            ScriptContext sc    = se.getContext();
                // add filename
            sc.setAttribute(se.FILENAME, "via_runScriptFromString" , 
sc.ENGINE_SCOPE);
                // script arguments to add?
            if (scriptArgs != null)
            {
                sc.setAttribute(se.ARGV    , scriptArgs, sc.ENGINE_SCOPE);
            }
                // create a FileReader from File
            result=se.eval(scriptCode);         // read and execute script

            return result;
        }
   }

It defines two static Java methods with the following signatures:

   public static Object runScriptFromFile (String fileName, Object [] 
scriptArgs)
   public static Object runScriptFromString (String scriptEngineName, String 
scriptCode, Object []
   scriptArgs)

If no arguments are needed one can supply null instead or an empty Java Object 
array.

The Java main method in the above program demonstrates calling both static 
methods.

---

Would be very interested how a COBOL program looks like that invokes both static methods runScriptFromFile() and runScriptFromString().

---rony



----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to