A few quick notes for those not familiar with oorexx: While in rexx everything is a string, in oorexx everything is an object, even strings, and you can invoke any string BIF as a method.
While rexx supports only call by value, oorexx supports both call by value and call by reference. The ~ operator is a method invocation. There are some subtleties that you probably won't need for a long while. Collection classes generally have [] and []= methods; these are implicitly invoked by constructs like foo = bar[baz] and foo[bar] = baz. -- Shmuel (Seymour J.) Metz http://mason.gmu.edu/~smetz3 ________________________________________ From: IBM Mainframe Discussion List [[email protected]] on behalf of Rony G. Flatscher [[email protected]] Sent: Wednesday, June 22, 2022 7:44 AM To: [email protected] Subject: An ooRexx sample for the Java sample program ... (Re: Some UNIX file usage questions Hi Andrew, thank you for this Java program. I took the liberty to transform it to ooRexx (untested) which should do the same as your Java program: /* load the Java class into ooRexx, it will understand ooRexx messages */ MvsConsole = bsf.loadClass("com.ibm.jzos.MvsConsole") if MvsConsole~isListening<>1 then /* same as .true in ooRexx */ MvsConsle~startMvsCommandListener rexxCallBack = .CommandCallback~new /* create a Rexx value of type "CommandCallback" */ /* wrap/box the Rexx value/object as a Java value/object */ boxedCallBack = BsfCreateRexxProxy(rexxCallBack, , "com.ibm.jzos.MvsCommandCallback") MvsConsole~registerMvsCommandCallback(boxedCallBack) /* ... do whatever you need to do, if anything ... */ /* now wait until the stop event gets received in rexxCallBack */ rexxCallBack~waitForStop /* invocation will block */ ::requires "BSF.CLS" /* get ooRexx-Java bridge */ /* ooRexx class defines the Java methods it will serve. Invoking these Java methods will cause a message of the same name and same arguments to be sent to the ooRexx value/object which will search and invoke the appropriate ooRexx method here. */ ::class CommandCallback /* implements MvsCommandCallback methods */ ::method init /* runs when a value of this type gets created */ expose startTime /* access object variable (attribute) */ startTime=.DateTime~new /* remember current date and time */ ::method handleModify expose startTime /* access object variable (attribute) */ parse arg arg0 if arg0="REPORT" then say "Runtime:" startTime - .dateTime~new /* deduct current date and time */ else say arg0 "not recognized. Valid commands: REPORT" ::method handleStart /* do nothing */ ::method handleStop expose lock /* access object variable (attribute) */ lock = .false /* set lock to 0 */ return .false /* return 0 */ ::method waitForStop /* method to block caller until stop occurs */ expose lock /* access object variable (attribute) */ guard on when lock=.false/* wait until control variable is set to .false */ A few notes: - it is not necessary to know Java, one just needs to be able to understand the documentation of the Java classes that you wish to use from ooRexx, in this case e.g. <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.ibm.com%2Fdocs%2Fen%2Fsdk-java-technology%2F7.1%3Ftopic%3Djzos-mvsconsole&data=05%7C01%7Csmetz3%40gmu.edu%7Cd0e4b87d50ba4664a6b108da54449f9d%7C9e857255df574c47a0c00546460380cb%7C0%7C0%7C637914950984120596%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=81mxJn14roHtfUsM6L7GUcP3ZzlKR8MPLQnOzj8JRpo%3D&reserved=0> and <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.ibm.com%2Fdocs%2Fen%2Fsdk-java-technology%2F7.1%3Ftopic%3Djzos-mvscommandcallback&data=05%7C01%7Csmetz3%40gmu.edu%7Cd0e4b87d50ba4664a6b108da54449f9d%7C9e857255df574c47a0c00546460380cb%7C0%7C0%7C637914950984120596%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hRqEnsEZ2kjDogiDuAOrtSv9B1ShHTH6Op2rKR8PLts%3D&reserved=0>. Anyone on this list will be able to read the Java documentation of these Java classes and understand what is documented there, I am sure; - the statements that start with two colons (::) are directives to ooRexx; ooRexx will read a program, syntax check it, then carry out each directive one by one and at the end will start to execute the program with the statement starting at line 1 - the "::requires BSF.CLS" directive will cause ooRexx to call the ooRexx program BSF.CLS which will load the Java bridge and camouflage the strictly typed, case sensitive Java as the dynamically typed and caseless ooRexx - the "::class" directive will cause ooRexx to create a class (synonyms: type, structure) and remember its name - the "::method" directives will cause ooRexx to create methods, remember their names and the Rexx code going with them and assign those methods to the previously created class - any Rexx value (synonyms: object, instance) created from this class will understand all messages that are named as the methods therein: conceptually, every Rexx value/object/instance is like a living thing and understands messages it receives by searching a method by the name of the received message, invoke it (and supply arguments if any) and return any return value, if any Should there be any questions please do not hesitate and ask them. ---rony On 22.06.2022 07:31, Andrew Rowley wrote: > On 22/06/2022 9:03 am, Charles Mills wrote: >> Can one write a Started Task in Java? What would the JCL look like >> (neglecting >> application-specific items)? > > This is a basic Java program that runs and responds to MODIFY and STOP > commands: > > import java.time.*; > import com.ibm.jzos.MvsCommandCallback; > import com.ibm.jzos.MvsConsole; > > public class JavaStc > { > static volatile boolean stopped = false; > static final Instant startTime = Instant.now(); > > public static void main(String[] args) throws InterruptedException > { > if (!MvsConsole.isListening()) > { > MvsConsole.startMvsCommandListener(); > } > MvsConsole.registerMvsCommandCallback(new CommandCallback()); > > while (!stopped) > { > Thread.sleep(1000); > } > } > > static class CommandCallback implements MvsCommandCallback > { > public void handleModify(String arg0) > { > if (arg0.equals("REPORT")) > { > Duration runtime = Duration.between(JavaStc.startTime, > Instant.now()); > System.out.println("Runtime: " + runtime.toString()); > } > else > { > System.out.println(arg0 + " not recognized. Valid commands: > REPORT"); > } > } > > public void handleStart(String arg0) > { > // do nothing > } > > public boolean handleStop() > { > JavaStc.stopped = true; > return false; > } > } > } > > JCL to run it under the JZOS batch launcher (which allows you to access JCL > DDs from the Java > program): > > //G EXEC PGM=JVMLDM80,REGION=256M, > // PARM='/ JavaStc' > //* > //STEPLIB DD DISP=SHR,DSN=VENDOR.LINKLIBE > //* > //SYSPRINT DD SYSOUT=* > //SYSOUT DD SYSOUT=* > //STDOUT DD SYSOUT=* > //STDERR DD SYSOUT=* > //CEEDUMP DD SYSOUT=* > //ABNLIGNR DD DUMMY > //* > //STDENV DD * > export JAVA_HOME=/usr/lpp/java/J8.0 > > LIBPATH=/lib:/usr/lib:"${JAVA_HOME}"/bin > LIBPATH="$LIBPATH":"${JAVA_HOME}"/lib/s390 > LIBPATH="$LIBPATH":"${JAVA_HOME}"/lib/s390/j9vm > LIBPATH="$LIBPATH":"${JAVA_HOME}"/bin/classic > export LIBPATH="$LIBPATH": > > export CLASSPATH="/home/andrewr/java" > > IJO="-Xms16m -Xmx128m" > export IBM_JAVA_OPTIONS="$IJO " > > This JCL is adapted from the samples provided with JZOS. > > One quirk is that the modify commands need to specify APPL=, i.e. > MODIFY JOBNAME,APPL=REPORT > > The command callbacks happen on a different thread I think so you need to > consider > synchronization. Other than that it is quite simple. > > Andrew Rowley ---------------------------------------------------------------------- For IBM-MAIN subscribe / signoff / archive access instructions, send email to [email protected] with the message: INFO IBM-MAIN ---------------------------------------------------------------------- For IBM-MAIN subscribe / signoff / archive access instructions, send email to [email protected] with the message: INFO IBM-MAIN
