OS2 World Community Forum
OS/2, eCS & ArcaOS - Technical => Programming => Topic started by: Neil Waldhauer on September 14, 2019, 10:41:23 pm
-
We keep on having announcements. The screen shot is from 3.04, the current release is 3.08.
Running 3.08 is unchanged from 3.06. Is there some way to run NetRexx on OS/2 that I overlooked?
java -jar NetRexxF.jar -exec hello
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/eclipse/j
dt/internal/compiler/tool/EclipseCompiler : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at org.netrexx.process.NetRexxC.process(NetRexxC.java:417)
at org.netrexx.process.NetRexxC.main2(NetRexxC.java:338)
at org.netrexx.process.NetRexxC.main2(NetRexxC.java:318)
at org.netrexx.process.NetRexxC.main2(NetRexxC.java:314)
at org.netrexx.process.NetRexxC.main(NetRexxC.java:168)
-
We keep on having announcements. The screen shot is from 3.04, the current release is 3.08.
Running 3.08 is unchanged from 3.06. Is there some way to run NetRexx on OS/2 that I overlooked?
I'm not using any of RexxLA's NetRexxes, but of course there's a possibility that the alleged "OS/2 compatibility" is not perfect yet. They may or may not be using OS/2 as such: http://ibm-netrexx.215625.n3.nabble.com/NetRexx-3-08-GA-released-td4028427.html (http://ibm-netrexx.215625.n3.nabble.com/NetRexx-3-08-GA-released-td4028427.html). Bug?
-
Here's a version of NetRexxC.cmd that is somewhat more sofisticated as it's based on my javarun code that tries to find and use the available java engine on the machine.
//Jan-Erik
/* Translate and compile a NetRexx program */
/* */
/* use as: NetRexxC hello [file2]... */
/* */
/* which will use the NetRexx translator to */
/* translate hello.nrx to hello.java */
/* then will use javac to compile hello.java */
/* */
/* OPTIONS keywords may be added (with a -) before or */
/* after the file specification, along with the extra */
/* flags known to NetRexxC (such as -keep). For */
/* example: */
/* */
/* NetRexxC -keep -format -comments hello */
/* */
/* Invoke with no parameters for a full list of flags. */
/* */
/* To run the class after compilation, specify -run as */
/* an option word. Each file will be run in turn. */
/* */
/* NetRexxC -run hello */
/* */
/* Multiple programs may be specified; in this case */
/* they are all run (if requested) after all compiles. */
/* */
/* ---------- */
/* 1996.09.02 -- handle Warnings from NetRexxC (rc=1) */
/* 1996.12.14 -- use COM.ibm.netrexx.process */
/* 1998.05.25 -- pass NETREXX_JAVA setting to java.exe */
/* 2011.09.01 -- use org.netrexx.process */
/* 2011.09.01 -- remove -xms4M */
parse arg args
w=wordpos('-run', args)
if w>0 then do; run=1; args=delword(args,w,1); end; else run=0
w=wordpos('-nocompile', args)
if w>0 then do; noc=1; end; else noc=0
/* ----- Translate & Compile ----- */
parse source system .
select /* system-specific options */
when system='OS/2' then do
'@echo off'
PARSE SOURCE . . this
CALL SysGetEA this, 'J_PATH', 'j_path'
if LENGTH( j_path ) < 2 THEN DO
SAY 'Searching for installed version of JAVA'
PARSE UPPER VALUE rxFind( 'JAVA.EXE', ' -version', 'OPENJDK VERSION "1.' ) WITH j_path'\BIN'.
IF LENGTH( j_path ) > 0 THEN
CALL SysPutEA this, 'J_PATH', j_path
end
IF TRANSLATE( RIGHT( j_path, 4 ) ) = '\BIN' THEN
j_path = LEFT( j_path, LENGTH( j_path ) - 4 )
CALL SysGetEA this, 'NETRX_PATH', 'netrx_path'
if LENGTH( netrx_path ) < 2 THEN DO
SAY 'Searching for installed version of NetRexx'
PARSE UPPER VALUE rxFind( 'NetRexxC.jar' ) WITH netrx_path'\LIB'.
IF LENGTH( netrx_path ) > 0 THEN
CALL SysPutEA this, 'NETRX_PATH', netrx_path
end
objID = 'NRXC'
netrx_name = 'NetRexxKing'
IF wpsObjectExist( '<WP_'objID'>' ) = 0 THEN
DO
setupstring = 'OBJECTID=<WP_'objID'>;EXENAME='this';PARAMETERS=[Type "-run" (without quotes) to run compiled script] %**P\%**F;ASSOCFILTER=*.nrx;ICONFILE='netrx_path'\'netrx_name'.ico;'
IF SysCreateObject( 'WPProgram', 'NetRexx Compiler / Run', '<WP_DEVFLDR>', setupstring, 'U' ) <> 1 THEN
CALL SysCreateObject 'WPProgram', 'NetRexx Compiler / Run', '<WP_DESKTOP>', setupstring, 'U'
CALL rxAddBigIcon netrx_path'\'netrx_name'.png', '<WP_'objID'>'
END
PARSE UPPER VALUE this WITH this'\BIN'.
IF 0 = POS( this'\LIB', TRANSLATE( VALUE( 'PATH',, 'OS2ENVIRONMENT' ) ) ) THEN
CALL VALUE 'PATH', this'\lib;'VALUE( 'PATH',, 'OS2ENVIRONMENT' ), 'OS2ENVIRONMENT'
IF 0 = POS( TRANSLATE( j_path )'\BIN', TRANSLATE( VALUE( 'PATH',, 'OS2ENVIRONMENT' ) ) ) THEN
CALL VALUE 'PATH', '.;'j_path'\bin;'j_path'\lib;'VALUE( 'PATH',, 'OS2ENVIRONMENT' ), 'OS2ENVIRONMENT'
/* Add option -norestart for OS/2s 1.0.2+ java.exe, for better display */
'java -version 2>&1|rxqueue'; parse pull . '1.' subv ' '
PARSE VALUE subv WITH subv'_'.
javaopts = ''
if subv>=6.0 then CALL VALUE 'CLASSPATH', '.;'this'\lib\NetRexxC.jar;'j_path'\lib\tools.jar', 'ENVIRONMENT'
else if subv>=4.1 then NOP
else if subv>=0.2 then javaopts='-norestart'; else if subv <> '' then do; say subv; javaopts='-noasyncgc'; end
/* Add any options from NETREXX_JAVA environment variable */
if subv < 4.2 then
do
nrjava=value('NETREXX_JAVA',,'ENVIRONMENT')
if nrjava\='' then javaopts=javaopts nrjava
end
else
javaopts=value('NETREXX_JAVA',,'ENVIRONMENT')
end
otherwise
/* Add any options from NETREXX_JAVA environment variable */
javaopts=value('NETREXX_JAVA',,'ENVIRONMENT')
end
do queued(); parse pull .; end
old_trace = TRACE( 'O' )z
'java -version'
'java ' javaopts 'org.netrexx.process.NetRexxC' args
CALL TRACE old_trace
/* ----- Run ----- */
if rc<=1 & run then do
if noc then say 'Run option ignored as -nocompile specified'
else do
/* This section of code is still OS/2-specific */
do forever /* find the file parameters */
parse var args file args
if file='' then leave
if left(file,1)='-' then iterate
filename=filespec('n', file); parse var filename fn '.' fe
/* Now determine the exact case of the class, for java commands */
file=fn'.class'
call SysFileTree file, 'foo.', 'FO'
if foo.0<>1 then do
if foo.0=0 then say 'Cannot find file:' file
if foo.0>1 then
say 'File "'file'" is not a unique specification'
exit 1;
end
file = filespec( 'Name', foo.1 ) /* is now correct case */
parse var file fn '.' fe
say 'Running' fn '...'
'java' fn
end
end
end
ELSE
PARSE PULL
exit rc
rxChk: PROCEDURE
DO WHILE QUEUED() > 0; PARSE PULL; END;
org_trace = TRACE( 'O' )
'@'||ARG(1)||ARG(2)||' 2>>&1 | RXQUEUE'
CALL TRACE org_trace
DO WHILE QUEUED() > 0
IF POS( TRANSLATE( ARG(3) ), TRANSLATE( LINEIN( 'QUEUE:' ) ) ) > 0 THEN
IF LENGTH( ARG(4) ) > 0 THEN RETURN ARG(4)
END
RETURN ''
rxFind: PROCEDURE EXPOSE !_msg_!.
PARSE VALUE REVERSE( SysSearchPath( 'PATH', ARG(1) ) ) WITH .'\'fpath
fpath = REVERSE( fpath )
IF ARG() > 1 & LENGTH( fpath ) > 0 THEN
fspec = rxChk( fpath'\'ARG(1), ARG(2), ARG(3), fpath )
ELSE IF STREAM( fpath'\'ARG(1), 'C', 'QUERY EXISTS' ) <> '' THEN
fspec = fpath
ELSE fspec = ''
IF LENGTH( fspec ) > 0 THEN RETURN fspec
CALL LINEOUT 'STDERR', VALUE( 'PROGRAMS',,'ENVIRONMENT' )
CALL SysFileTree VALUE( 'PROGRAMS',,'ENVIRONMENT' )||'\*'||ARG(1), 'file.', 'SFO'
DO i = 1 TO file.0
PARSE VALUE REVERSE( file.i ) WITH .'\'fspec
IF ARG() > 1 THEN
fspec = rxChk( file.i, ARG(2), ARG(3), REVERSE( fspec ) )
ELSE
fspec = REVERSE( fspec )
IF LENGTH( fspec ) > 0 THEN RETURN fspec
END
drives = SysDriveMap( 'C:', 'USED' )
DO j = 1 TO WORDS( drives )
CALL LINEOUT 'STDERR', SUBWORD( drives, j, 1 )
CALL SysFileTree SUBWORD( drives, j, 1 )||'\*'||ARG(1), 'file.', 'SFO'
DO i = 1 TO file.0
PARSE VALUE REVERSE( file.i ) WITH .'\'fspec
IF ARG() > 1 THEN
fspec = rxChk( file.i, ARG(2), ARG(3), REVERSE( fspec ) )
ELSE
fspec = REVERSE( fspec )
IF LENGTH( fspec ) > 0 THEN RETURN fspec
END
END
RETURN ''
rxAddBigIcon: PROCEDURE EXPOSE !_msg_!. java_path
crlf = D2C(13)D2C(10)
bigicons_dir = VALUE( 'BIGICONS',, 'ENVIRONMENT' )
bigicon = FILESPEC( 'N', ARG(1) )
objid = ARG(2)
IF LENGTH( bigicons_dir ) > 0 THEN
DO
IF STREAM( ( bigicons_dir'\'bigicon ), 'C','QUERY EXISTS') = '' THEN
IF SysCopyObject( ARG(1), bigicons_dir ) = 0 THEN
RETURN 1
IF STREAM( bigicons_dir'\bigicons.txt', 'C', 'QUERY EXIST' ) <> '' THEN
DO
f_size = STREAM( bigicons_dir'\bigicons.txt', 'C', 'QUERY SIZE' )
IF f_size > 0 THEN
DO
input = CHARIN( bigicons_dir'\bigicons.txt', 1, f_size )
CALL STREAM bigicons_dir'\bigicons.txt', 'C', 'CLOSE'
PARSE UPPER VALUE input WITH pre'"'(bigicon)'"'post
IF LENGTH( post ) > 0 THEN RETURN 2
PARSE UPPER VALUE input WITH pre'"'(objid)'"'post
IF LENGTH( post ) > 0 THEN RETURN 3
PARSE VALUE input WITH pre'[OBJECTID]'mid(crlf)(crlf)'['post
input = pre'[OBJECTID]'STRIP( STRIP( mid, 'T', D2C(10) ), 'T', D2C(13) )||crlf||LEFT( '"'objid'"', 28 )'"'bigicon'"'crlf||crlf'['post
CALL SysFileDelete bigicons_dir'\bigicons.txt'
CALL CHAROUT bigicons_dir'\bigicons.txt', input
CALL STREAM bigicons_dir'\bigicons.txt', 'C', 'CLOSE'
END
ELSE RETURN 4
END
END
RETURN 0
/* Code borrowed from REXX Tips & Tricks v3.60 */
wpsObjectExist: PROCEDURE /* parameter: '<new_wps_object_id>', return: 1 exist, 0 doesn't exist, 43 error */
PARSE ARG objID
rc = 43 /* init return/error code 43 = routine not found */
SIGNAL ON SYNTAX NAME ObjectExistError
IF SUBSTR( objID, 2, 1 ) <> ":" THEN
IF LEFT( objID, 1 ) <> "<" & RIGHT( objID, 1 ) <> ">" THEN
objID = "<" || objID || ">"
/* create the object and see if it fail */
tempRC = SysCreateObject( "WPFolder", "TestObject", "<WP_NOWHERE>", "OBJECTID=" || objID || ";", "FAIL" )
IF tempRC = 1 THEN
DO
CALL SysDestroyObject objID
rc = 0
END
ELSE
rc = 1
ObjectExistError:
RETURN rc
Script has now been modified to support 4OS2 as well.
Sept 18, 2019
-
/* This section of code is still OS/2-specific */
do forever /* find the file parameters */
parse var args file args
if file='' then leave
if left(file,1)='-' then iterate
filename=filespec('n', file); parse var filename fn '.' fe
An usual quality improvement: if this is supposed to be OS/2-specific Rexx code, without overdoing it, then you should support entered valid file name arguments like "C:\NetRexx test\text.txt", or "", or "test file.class, or "C:\CONFIG.SYS", each including the quote(s).
/* Unverified, common code to be inserted */
if left(file,1)='"' then do
args=file args
parse var args '"' file '"' args
end
-
That part of the code come from the original NetRexxC.cmd and was left alone as it is/was a design decision by the NetRexx Team.
/* Unverified, common code to be inserted */
if left(file,1)='"' then do
args=file args
parse var args '"' file '"' args
end
-
The modified NetRexxC.cmd nearly works. It gets through the Java version problem, and only fails for running hello. I only quoted the end of the output to show what is happening. hello.class is on the libpath, path and classpath.
By the way, every time I run NetRexxC, the path gets longer. Paths longer than 1024 bytes overwrite kernel memory, so this should be avoided.
Program hello.nrx
Compilation of 'hello.nrx' successful
hello.class
Cannot find file: hello.class
So if I need updated NetRexxC.cmd, do I also need some updated NetRexxR.cmd?
-
That part of the code come from the original NetRexxC.cmd and was left alone as it is/was a design decision by the NetRexx Team.
If posted as some generic solution or reference here, not by the NetRexx Team but by you, then such a solution or reference is broken too. I'm not using their non-OS/2 software. So I'm not going to report a bug, nor will I fix their broken software for myself. Actually it'll be an old bug in IBM's code.
Please note exactly the same bug applies to quite a few OS/2 Rexx apps, regardless of the author. Hence the sample code.
-
So if I need updated NetRexxC.cmd, do I also need some updated NetRexxR.cmd?
Both appear to be worth checking, because it seems to be about as old as IBM Object Rexx for Windows. I can see a few possible updates for my old copy of NetRexxC.cmd, so there are reasons to assume OS/2 wasn't the target OS. No support for valid CLI file name arguments with quote(s) is a sample, and so is the mixed use of both ENVIRONMENT and OS2ENVIRONMENT.
The different package Rexx2Nrx may have an own, possibly conflicting NetRexxC.cmd file name. Which, in my case, is an eCS 1.2-customized version of Rexx2Nrx' original NetRexxC.bat file. Presumably written for Windows, because the file name Externals.bat is a little bit too long for x:\OS2\MDOS\COMMAND.COM.
-
Use the program object instead of command line over and over again...
but ok, here's the modification you need.
IF 0 = POS( this'\lib', TRANSLATE( VALUE( 'PATH',, 'OS2ENVIRONMENT' ) ) ) THEN
CALL VALUE 'PATH', this'\lib;'VALUE( 'PATH',, 'OS2ENVIRONMENT' ), 'OS2ENVIRONMENT'
IF 0 = POS( TRANSLATE( j_path )'\BIN', TRANSLATE( VALUE( 'PATH',, 'OS2ENVIRONMENT' ) ) ) THEN
CALL VALUE 'PATH', '.;'j_path'\bin;'j_path'\lib;'VALUE( 'PATH',, 'OS2ENVIRONMENT' ), 'OS2ENVIRONMENT'
[D:\PROGRAMS\NETREXX\BIN]netrexxc hello.nrx -run
openjdk version "1.6.0_27"
OpenJDK Runtime Environment (build 1.6.0_27-b01-GA5)
OpenJDK Client VM (build 20.0-b12, mixed mode)
NetRexx portable processor 3.08-GA build 1,582-20190906-1850
Copyright (c) RexxLA, 2011,2019. All rights reserved.
Parts Copyright (c) IBM Corporation, 1995,2008.
Program hello.nrx
Compilation of 'hello.nrx' successful
Running hello ...
hello
The modified NetRexxC.cmd nearly works. It gets through the Java version problem, and only fails for running hello. I only quoted the end of the output to show what is happening. hello.class is on the libpath, path and classpath.
By the way, every time I run NetRexxC, the path gets longer. Paths longer than 1024 bytes overwrite kernel memory, so this should be avoided.
Program hello.nrx
Compilation of 'hello.nrx' successful
hello.class
Cannot find file: hello.class
So if I need updated NetRexxC.cmd, do I also need some updated NetRexxR.cmd?
You distribute the runtime libarary NetRexxR.jar with your application.
It's possible to write a NetRexxR.cmd, but the users should run your app as any other java application.
-
That doesn't seem to help enough.
[k:\programs\netrexx3\lib] ..\bin\netrexxc2 -run hello
openjdk version "1.6.0_27"
OpenJDK Runtime Environment (build 1.6.0_27-b01-GA5)
OpenJDK Client VM (build 20.0-b12, mixed mode)
NetRexx portable processor 3.08-GA build 1,582-20190906-1850
Copyright (c) RexxLA, 2011,2019. All rights reserved.
Parts Copyright (c) IBM Corporation, 1995,2008.
Program hello.nrx
Compilation of 'hello.nrx' successful
hello.class
Cannot find file: hello.class
-
but ok, here's the modification you need.
That modification is broken too, but since you don't seem to listen I cannot be arsed to point out yet another improvement.
-
Here (https://www.os2world.com/past-news/80-software/22618-netrexx-3-0-8-ga.html) the link points to a BETA; not to 3.0.8 GA. FWIW.
-
The problem is that the NetRexxC.cmd does not set classpath correctly. I'm not going to patch an increasingly bad REXX program, but rather I'll try to construct a useful one for the present day, that does not necessarily run original Java 1.1-based NetRexx from the 1990's.
-
Here ite set the class path to
.;D:\PROGRAMS\NETREXX\lib\NetRexxC.jar;D:\PROGRAMS\OPENJDK\lib\tools.jar
automatically as seen with
CALL TRACE 'I'
if subv>=6.0 then CALL VALUE 'CLASSPATH', '.;'this'\lib\NetRexxC.jar;'j_path'\lib\tools.jar', 'ENVIRONMENT'
What do you get?
Just add CALL TRACE 'I' right before the line and look for then output.
The problem is that the NetRexxC.cmd does not set classpath correctly. I'm not going to patch an increasingly bad REXX program, but rather I'll try to construct a useful one for the present day, that does not necessarily run original Java 1.1-based NetRexx from the 1990's.
//Jan-Erik
-
It seems to set classpath correctly, but then abandons it's work because it can't find hello.class.
Dir /N /B might work in CMD, but it's not useful with 4os2. Rexx has a lot of other ways to find filenames that don't depend on the exact syntax of CMD.
The script does work on CMD.
-
Ahh, yes, 4OS2 of course in combination with the unchanged part of the code.
Suggestions how to alter that section?
It seems to set classpath correctly, but then abandons it's work because it can't find hello.class.
Dir /N /B might work in CMD, but it's not useful with 4os2. Rexx has a lot of other ways to find filenames that don't depend on the exact syntax of CMD.
The script does work on CMD.
-
I'm not sure about any edge cases. This will work for my purposes, at least for now.
/* Now determine the exact case of the class, for java commands */
file=fn'.class'
call SysFileTree file, 'foo.', 'FO'
if foo.0<>1 then do
if foo.0=0 then say 'Cannot find file:' file
if foo.0>1 then do; do queued(); parse pull .; end
say 'File "'file'" is not a unique specification'
end
exit 1;
end
file = filespec('Name', foo.1) /* is now correct case */
-
Added you modifications to the script.
-
I decided to test if OS/2 Warp 4 (GA) could support getting values from the environment.
say value('path',,'environment')
gives "incorrect call to routine", while
say value('path',,'os2environment')
works, just fine. Both work OK in ArcaOS. When did REXX gain the ability to use 'environment' as well as 'os2environment'?
-
When did REXX gain the ability to use 'environment' as well as 'os2environment'?
Presumably you'll be using a different Rexx interpreter anyway, because of not having applied any Y2K OS/2 FixPak w.r.t. Rexx. That FixPak is about as GA as it gets, due to the number of languages still supported by IBM back then. The FixPak introduced new Rexx functionalities.
If a customer isn't using a Y2K-proof OS/2 install, e.g. Microsoft's OS/2 1.0, and you are using a non-Y2K OS/2 Rexx interpreter to not use Y2K functionalities by mistake during the creation of a solution for such a customer, then perhaps still use OS2ENVIRONMENT. Otherwise use ENVIRONMENT. It saves a few bytes, your code will be more portable, and e.g. there's no confusing WINOS2ENVIRONMENT. IIRC IBM's Object Rexx for Windows uses ENVIRONMENT too. Hence the portability of code using that.
If a Y2K-proof Rexx interpreter doesn't support ENVIRONMENT, then that would be a problem. AFAICT OS/2 Warp 4 GA isn't Y2K-proof, including its Rexx interpreter.
-
AFAICT OS/2 Warp 4 GA isn't Y2K-proof, including its Rexx interpreter.
Yup. IBM shipped some of the Warp Version 4 boxes with a large blue sticker that said:
"YEAR 2000 READY when applicable IBM FixPaks are installed. Certain add-on features in this package are not Year 2000 ready, including: Certain device drivers, BonusPak, Application Sampler CD, WarpExplorer, TCP/IP DOS for OS/2 Warp (Winsock). Netware Client 2.11, Java 1.0.1. For details about the above and any other features that may be identified by IBM as not Year 2000 ready see: http://ps.software.ibm.com"
-
I'm curious to know which FixPak upgraded Rexx.'
I'm aware that for the subject software, NetRexx, it doesn't matter. The minimum requirement for OpenJDK 6 (and therefore NetRexx) is FixPak 13.
-
I'm curious to know which FixPak upgraded Rexx.'
FixPaks (or new OSes), not FixPak (or new OS).
For example, IIRC an OS/2 Warp 3 FixPak broke PMREXX (functional change: a.o. ADDRESS() no longer returns PMREXX, so you cannot make sure that RxMessageBox() will work anymore).
All newer Y2K FixPaks changed Rexx (functionally), and those FixPaks will be as GA as possible (i.e. not just for the few eCS and ArcaOS languages).
Object Rexx changed ("Classic") Rexx (functional changes like ANSI's DATE() with more than one argument, syntax checking).
So please use Object Rexx to check the syntax of distributed apps (including but not limited to a.o. VX-REXX), try to avoid using e.g. DATE() with more than one argument for code not used just by you, and it'll be safe to assume that someones Rexx is Y2K-proof and that PMREXX is broken. If not, then you're probably dealing with some exotic system ("Microsoft OS/2 1.0") and perhaps should use the same Rexx interpreter as that customer, to rule out using newer code (i.e. the Class Rexx of Object Rexx, or Y2K functionalities). Y2K is documented by IBM, and Object Rexx is a matter of (not) having executed SWITCHRX.
Edit: and REXXUTIL.DLL was upgraded once or twice with new functions, like SysBootDrive().