[OpenVMS, Apache/Ant, libffi, jffi, JRuby] Building Jruby on your OpenVMS server
PRODUCT: JRuby Version 1.6.3 (modified by the author) jffi-1.0 (modified by the author) Apache/Ant Version 1.7.1 (modified by the author) libffi Version 3.0.9 (modified by the author) Itanium(R) Assembler Version 7.00.4326 HP GNV Version 2.1-3 Either MMK Version 4.1 or HP MMS Version 3.8-2 HP C Version 7.2-022 or above J2SE(TM) Development Kit (JDK) 6.0-2 for OpenVMS Itanium servers
OP/SYS: OpenVMS IA64 Version 8.3-1H1
SOURCE: Philippe Vouters Fontainebleau/France
LOW-COST HIGH-TECH: http://techno-star.fr
OVERVIEW: This article provides somes guidelines on how to rebuild JRuby Version 1.6.3 onto your OpenVMS Itanium server. What this JRuby 1.6.3 for OpenVMS version adds compare to JRuby 1.5.3 is ODS-2 and ODS-5 VMS file syntaxes support. For VMS ODS-2 and ODS-5 file syntaxes you may use in your Ruby code, refer to the examples at : ../tima/OpenVMS-Java-Unix-CRTL_API_decc$translate_name-Java_solution.html Except the main entry point, this JRuby 1.6.3 source code incorporates all the Java source code found at right above URL.
*** CAUTION *** This sample procedure has been tested using HP MMS V3.8-2, J2SE (TM) Development Kit (JDK) 6.0, GNV V2.1-3, HP MMS V3.8-2 and HP C V7.2-022 on OpenVMS IA64 V8.3-1H1. However, we cannot guarantee its effectiveness because of the possibility of error in transmitting or implementing it. It is meant to be used as a template for writing your own procedure, and may require modification for use on your system.
JRUBY and ALPHA SERVERS: Although the DCL procedure hereafter is designed for Alpha OpenVMS servers, this has not been tested due to lack of available hardware with enough physical memory or lack of available hardware running the latest J2SE for OpenVMS Alpha servers software. The DCL procedure below should require at least 4GB of physical memory and J2SE Development Kit (JDK) 5.0-7 or beyong. The libffi build requires at least the MACRO-64 assembler with the following image identification: Image Identification Information image name: "MACRO-64" image file identification: "MACRO64V1.2-108" image file build identification: "" link date/time: 20-JAN-1998 17:29:45.22 linker identification: "A11-20" http://h71000.www7.hp.com/openvms/freeware/v4_00freeware_abstract.txt states you may find the MACRO-64 assembler on the freeware CD V4. However, the author makes yet no provision on a successful JRuby/Alpha build. This has not yet been successfully demonstrated.
DOWNLOADS for ITANIUM SERVERS: - If you wish to use a pre-built ready to use JRuby 1.6.3 kit for OpenVMS Itanium Servers, visit the URL link at: http://vmsfree.ouvaton.org/freen/index.php?s=jruby - The following section is for VMS users willing to rebuild JRuby 1.6.3 Download Ant/VMS T1.7 (Ant 1.7.0 based) from http://h71000.www7.hp.com/openvms/products/ips/ant/index.html?jumpid=reg_R1002_USEN Download the OpenVMS/GNV kit from http://gnv.sourceforge.net/readme.html Download the modified Ant V1.7.1 jars from ../zip/ant-1.7.1-jars.tar.gz Download the modified libffi V3.0.9 source code from ../zip/libffi-3.0.9.tar.gz Download the modified jffi V1.0 source code from ../zip/wmeissner-jffi-09018f9.tar.gz Download the modified JRuby 1.6.3 source code from ../zip/jruby-1.6.3.tar.gz Download jnr-posix-1.1.8.jar from ../zip/jnr-posix-1.1.8.jar For OpenVMS Itanium servers, get the OpenVMS port of the Intel Itanium Assembler (IASI64.EXE). If you feel difficulties in getting the OpenVMS port of the Intel Itanium assembler (IASI64.EXE), you may always download a libffi PCSI ready kit from: http://vmsfree.ouvaton.org/freen/index.php?s=libffi Instead of you performing a cut and paste of the hereafter DCL procedure, you may always download ../zip/jruby_vms.com.zip and unzip it on your OpenVMS computer using: $ unzip -aa jruby_vms.com.zip If you neither have MMS nor MMK, download MMK from: http://www.kednos.com/kednos/Open_Source/MMK
JRUBY BUILD PROCEDURE NOTES: The following assumes that the procedure runs on an ODS-5 disk and is executed from an account with the TMPMBX, NETMBX and BYPASS privileges to automatically copy the produced libffi.EXE shareable image to SYS$SHARE. Except the PCSI files, all the .tar.gz files and the procedure below are assumed to reside in the same directory path. The author uses SFTP to transfer the files to the VMS directory path and experiences no problems rebuilding JRuby 1.6.3. Install Ant/VMS T1.7 PCSI kit in SYS$COMMON. Install OpenVMS/GNV PCSI kit. For Itanium servers, if installing HP GNV V2.1-3 on a non SYS$SYSDEVICE disk, refer to another article available in this knowledge database at: ../tima/OpenVMS-GNV-GNV_kit_installation_on_an_alternate_ODS-5_device.html Once GNV installed, perform: $ @sys$startup:gnv$startup $ @gnu:[lib]gnv_setup Your directory should contain: $ dire Directory PHV:[PHV.jruby_vms] ant-1^.7^.1-jars^.tar.gz;1 jnr-posix-1^.1^.8.jar;1 jruby-1^.6^.3^.tar.gz;1 jruby_vms.com;1 libffi-3^.0^.9^.tar.gz;1 wmeissner-jffi-09018f9^.tar.gz;1 Total of 6 files. $ prior to the command $ @JRUBY_VMS.COM
JRUBY BUILD PROCEDURE: $! $! File : JRUBY_VMS.COM $! $ jruby_dir = "jruby-1^.6^.3" $! $! VMS_to_UNIX code borrowed from ANT.COM Copyrighted by HP. $! $ VMS_to_UNIX: subroutine $! $! $! We need the directory as a unix-style spec. $! $! Don't use f$parse, this way we can maintain ODS-5 syntax, including case $! We need to let Java$filename_controls do the correct thing. $! $! unix_filename = "/" + f$parse(vms_filename,,,"device") - ":" $! $! already unix don't convert $! $ vms_filename = "''P1'" $ if f$locate("/",vms_filename) .ne. f$length(vms_filename) $ then $ unix_filename = vms_filename $ return $ endif $! get the device name $ if f$locate(":",vms_filename) .ne. f$length(vms_filename) $ then $ unix_filename = "/" + - F$EXTRACT(0,F$LOCATE(":",vms_filename),vms_filename) $else $! relative path $ unix_filename = "." $ endif $! $!get the directory $! $ dir_start_delim = "[" $ dir_end_delim = "]" $ if f$locate("<",vms_filename) .ne. f$length(vms_filename) $ then $ ! not using [foobar.foo] $ vms_start_delim = "<" $ vms_end_delim = ">" $ endif $ vms_self_dir = f$extract(f$locate("''dir_start_delim'",vms_filename)+1, - f$locate("''dir_end_delim'",vms_filename) - - f$locate("''dir_start_delim'",vms_filename), - vms_filename) - "[" - "]" - "<" - ">" $!show sym vms_self_dir $! $! Did we have a directory? No, got to the end $ if "''vms_self_dir'" .eqs. "" then goto directory_done $! $! vms_self_dir = f$parse(vms_filename,,,"directory") - "[" - "]" - "<" - ">" $ i=0 $uloop: $ e=f$element(i,".",vms_self_dir) $ if e .nes. "." $ then $ unix_filename = unix_filename + "/" + e $ i=i+1 $ goto uloop $ endif $! put multi-dot back in (Oracle addition) $! drobles begin $ real_du = "" $MULTIDOT_LOOP: $ if f$length (unix_filename) .EQ. f$locate("^/", unix_filename) then goto END_MULTIDOT_LOOP $ s = f$extract (0, f$locate ("^/", unix_filename), unix_filename) $ real_du = real_du + s + "." $ unix_filename = unix_filename - s - "^/" $ goto MULTIDOT_LOOP $END_MULTIDOT_LOOP: $ unix_filename = real_du + unix_filename $! drobles end $! $! add trailing "/" for directory $! $ directory_done: $ unix_filename = unix_filename + "/" $! $! finally let's get the filename $! $ get_filename: $! unix_filename = f$edit(unix_filename,"lowercase") $! unix_filename = unix_filename + f$parse(vms_filename,,,"NAME") $ vms_filename_start = f$locate("''dir_end_delim'",vms_filename) $! $! if there wasn't a directory look for a device name $ if vms_filename_start .eq. f$length(vms_filename) then - vms_filename_start = f$locate(":",vms_filename) $! $! if we didn't find a directory or a device, just start from zero $ if vms_filename_start .eq. f$length(vms_filename) $ then vms_filename_start = 0 $ else $ vms_filename_start = vms_filename_start + 1 ! move beyond the delim $ endif $! $ unix_filename = unix_filename + - f$extract(vms_filename_start, - f$length(vms_filename), vms_filename) $ real_du = "" $MULTIDOT_LOOP_FILE: $ if f$length (unix_filename) .EQ. f$locate("^.", unix_filename) then - goto END_MULTIDOT_LOOP_FILE $ s = f$extract (0, f$locate ("^.", unix_filename), unix_filename) $ real_du = real_du + s + "." $ unix_filename = unix_filename - s - "^." $ goto MULTIDOT_LOOP_FILE $END_MULTIDOT_LOOP_FILE: $ unix_filename = real_du + unix_filename $ UNIX_file_spec :== "''unix_filename'" $ return $ endsubroutine $! $! $! Start of Main procedure $! $ IA64= F$GETSYI("ARCH_TYPE") .Eq. 3 $ ALPHA= F$GETSYI("ARCH_TYPE") .Eq. 2 $ if IA64 .eq. 0 .and. ALPHA .eq. 0 $ then $ write sys$output "Unsupported platform. Exiting ..." $ exit $ endif $ if ALPHA $ then $ arch = "alpha-OpenVMS" $ java_version = "1.5.0" $ else $ arch = "ia64-OpenVMS" $ java_version = "6.0" $ endif $ on error then exit $ verify = f$verify(0) $ define/user sys$error sys$scratch:temp.txt $ java -fullversion $ open/read fred sys$scratch:temp.txt $ read fred line $ close fred $ delete/noconfirm sys$scratch:temp.txt; $ if f$locate("''java_version'-",line) .eq. f$length(line) $ then $ chr35="""" $ pos_start_version = f$locate(chr35,line)+1 $ line = f$extract(pos_start_version,f$length(line)-pos_start_version,line) $ line = f$extract(0,f$locate(chr35,line), line) $ write sys$error "Wrong Java version : ''line'" $ write sys$error "Expecting Java version ''java_version'" $ exit $ endif $ if f$search("sys$system:mms.exe") .nes. "" $ then $ make = "mms" $ endif $ if f$type(MMK) .nes. "" $ then $ make = "mmk" $ endif $ if f$type(make) .eqs. "" $ then $ write sys$error "No MMS or MMK" $ exit $ endif $ loop: $ if IA64 .eq. 1 .and. f$type(IASM) .eqs. "" $ then $ inquire path "DCL Path for IASI64.EXE ? []" $ if f$locate("]",path) .eq. f$length(path) .and. - f$locate(":",path) .eq. f$length(path) then path = path + ":" $ if f$search("''path'IASI64.EXE") .eqs. "" then goto loop $ IASM :== "mc ''path'IASI64.EXE" $ endif $ Parse_Style = f$getjpi("", "PARSE_STYLE_PERM") $ set process/parse=extended $ this_proc = f$env("procedure") $ this_dev=f$parse(this_proc,,,"DEVICE") $ this_dir=f$parse(this_proc,,,"DIRECTORY") - "]" $ this_VMS_dir = "''this_dev'''this_dir'" + "]" $ create/directory [.ANT_171] $ create/directory [.ANT_171.BIN] $ create/directory [.ANT_171.LIB] $ copy sys$common:[ANT_17.BIN]ANT.COM 'this_dev''this_dir'.ANT_171.BIN] $ copy ant-1^.7^.1-jars^.tar.gz [.ANT_171] $ call VMS_to_UNIX "''jruby_dir'^.tar.gz" $! Enter GNV $ bash gnutar -zxvf libffi-3.0.9.tar.gz cd ANT_171/ gnutar -zxvf ant-1.7.1-jars.tar.gz cd .. gnutar -zxvf wmeissner-jffi-09018f9.tar.gz export UNIX_file_spec=`/gnu/bin/dcl sho symbol/global UNIX_FILE_SPEC | gawk -F\" '{print $2}'` gnutar -zxvf $UNIX_file_spec exit $ call VMS_to_UNIX 'this_VMS_dir' $ ant :== "@''this_dev'''this_dir'.ANT_171.BIN]ANT.COM" $ define ant$home "''this_dev'''this_dir'.ANT_171]" $ set default [.libffi-3^.0^.9] $ define DECC$EFS_CHARSET ENABLE $ @build $ set default [-] $ copy [.libffi-3^.0^.9]libffi.exe SYS$SHARE: $ define libffi "''this_dev'''this_dir'.libffi-3^.0^.9]libffi.exe" $ set security/protection=(S:RWED,O:RWED,G:RE,W:RE) SYS$SHARE:libffi.exe $ set def [.wmeissner-jffi-09018f9] $ open/write fred build.properties $ write fred "libffi_home=''UNIX_file_spec'libffi-3.0.9" $ write fred "libffi=''this_dev'''this_dir'.libffi-3^.0^.9]libffi.exe" $ write fred "mms=''make'" $ close fred $ ant "clean" $ ant $ copy [.dist]jffi.jar [-.'jruby_dir'.build_lib]jffi-'arch'.jar $ if f$search("[-.'jruby_dir'.lib.native]''arch'.DIR") .eqs. "" $ then $ create/dire [-.'jruby_dir'.lib.native.'arch'] $ endif $ copy [.build.jni]jffi-1^.0.exe [-.'jruby_dir'.lib.native.'arch'] $ set security/protection=(S:RWED,O:RWED,G:RE,W:RE) [-.'jruby_dir'.lib.native.'arch']jffi-1^.0.exe $ set def [-] $ copy jnr-posix-1^.1^.8.jar [.'jruby_dir'.build_lib]jnr-posix.jar $ set def [.'jruby_dir'] $ if f$search("[-.ANT_171.LIB]junit.jar") .eqs. "" $ then $ copy [.build_lib]junit.jar [-.ANT_171.LIB] $ endif $ ant "dist-clean" $ ant $ ant "jar-complete" $ set def [-] $ set verify $ @'this_dev''this_dir'.'jruby_dir'.bin]jruby-setup.com $ write sys$output "Testing with calls to DECC$TXPRINTF" $ create DECC_test.rb require 'ffi' require 'ffi/platform' module Portablelibc extend FFI::Library if FFI::Platform.openvms? libc = "DECC$SHR" else libc = "c" end ffi_lib libc if FFI::Platform.openvms? attach_function :printf, :"decc$txprintf", [:string, :varargs], :int else attach_function :printf, [:string, :varargs], :int end end Portablelibc.printf("Hello, World!\n") if ARGV.length > 1 ARGV.length.times do |i| Portablelibc.printf("Argument %d: %s\n", :int, i, :string, ARGV[i]) end end $ jruby DECC_test.rb foo bar $ create Jirb_test.rb fp = open("[]DECC_test.rb;","r") while (!fp.eof()) line = fp.readline() puts line end $ jirb Jirb_test.rb $ set noverify $ write sys$output "For use on your system, add the following to" $ write sys$output "your SYS$MANAGER:SYLOGIN.COM :" $ write sys$output "$ @''this_dev'''this_dir'.''jruby_dir'.bin]jruby-setup.com" $ set process/parse='Parse_style' $ if verify .eq. 1 then set verify $ exit
REFERENCE(S): JRuby including pure OpenVMS examples available at: ../tima/OpenVMS-Linux-Java-JRuby-JRuby-ported_to_OpenVMS_Itanium-Some_notes.html JRuby problem related URL: https://jira.codehaus.org/browse/JRUBY-5943?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=274311