|
Hi Peter, <snip>How does one start the JVM? Doesn't that happen automagically when calling your first java program?
</snip>The system will start a JVM automatically, or attach you to the currently active JVM, when you first attempt to access a java member (method or variable).
You can start the JVM yourself, using JNI. The advantage of using JNI is the fact that you can set options (version, classpath, memory pool size, etc) when you start the JVM.
Here's an example service program module which allows you to specify a stylesheet file path, IFS file path, and result file path. This then uses the stylesheet to transform the IFS file and place the result in the result file.
Anyway, the poiint of osting the source is that it shows how you can use JNI to create a JVM, attach to the current JVM, destroy the JVM, use putenv to set the classpath, use Qp0zGetEnvNoInit to retrieve the current classpath value, etc...
The JNI copysrc file is in QSYSINC/QRPGLESRC(copied from WDSC so I hope it formats OK - if not cut-n-paste it into NOTEPAD)
H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT) H NOMAIN H THREAD(*SERIALIZE) H BNDDIR('QC2LE')‚‚**********************************************************************
‚* Prototypes‚********************************************************************** €
‚* *Entry parms... /define modulesrc D/copy *LIBL/QRPGLECPY,XML2STM_H ‚* IFS File management definitions... d/Copy *LIBL/QRPGLECPY,IFS_Open d/Copy *LIBL/QRPGLECPY,IFS_Read d/Copy *LIBL/QRPGLECPY,IFS_Write d/Copy *LIBL/QRPGLECPY,IFS_Close‚********************************************************************** €
‚‚* IFS File variables... d fullName s 512a d fileName s 512a d file s 10i 0 ‚‚* IFS File Constants... d ##CCSID c Const(32) d ##Null c Const(X'00') d ##FILE_CCSID s 10i 0 Inz(819)‚*..................................................................... €
‚* Objects and primitives‚*..................................................................... €
‚* Strings... D xmlFilePath s O Class(*JAVA:'java.lang.String') D xsltFilePath s O Class(*JAVA:'java.lang.String') D resultFilePath s O Class(*JAVA:'java.lang.String') ‚* Files... D xmlFile s O Class(*JAVA:'java.io.File') D xsltFile s O Class(*JAVA:'java.io.File') D resultFile s O Class(*JAVA:'java.io.File') ‚* Transform sources... D xmlStreamSource... D s O Class(*JAVA D :'javax.xml.transform- D .stream.StreamSource') D xsltStreamSource... D s O Class(*JAVA D :'javax.xml.transform- D .stream.StreamSource') ‚* Transform result... D xmlStreamResult... D s O Class(*JAVA D :'javax.xml.transform- D .stream.StreamResult') ‚* Transformer Factory... D transFactory s O Class(*JAVA D :'javax.xml.transform- D .TransformerFactory') ‚* Transformer... D transformer s O Class(*JAVA D :'javax.xml.transform- D .Transformer')‚*.....................................................................
‚* JVM/JNI section...‚*.....................................................................
D/define OS400_JVM_12 D/copy qsysinc/qrpglesrc,jni ‚* JNI environment pointer... D env s * D g_jnienv s * inz(*null) ‚* get the JNI environment... D getJniEnv pr * D inputOpts 65535a varying const options(*nopass) ‚* Start the JVM... D startJvm pr * D inputOpts 65535a varying const options(*nopass) D attachJvm pr * D getClasspath pr 65535a varying D cvtToAscii pr 65535a varying D ebcdic 65535a varying const ‚* Free single object... D freeJavaObject PR D env * const D javaObject O CLASS(*JAVA:'java.lang.Object') D value ‚* Begin a group of objects... D beginObjGroup PR D env * const D capacity 10I 0 value ‚* End a group of objects... D endObjGroup PR D env * const ‚* Destroy JVM... D destroyJVM PR 10I 0‚*..................................................................... €
‚* Current state... D currentXML s 255a D currentResult s 255a D currentXSLT s 255a ‚* Program variables... D DB2_rtcd s 20a D CP_rtcd s 10i 0‚*..................................................................... €
d errNo s 5u 0‚*.....................................................................
‚* free Java Object...‚*.....................................................................
p freeJavaObject B D freeJavaObject PI D env * const D javaObject O CLASS(*JAVA:'java.lang.Object') D value‚*.....................................................................
/free JNIENV_P = env; If javaObject = *null or JNIEnv_P = *null; return; endif; DeleteLocalRef (JNIEnv_P:javaObject); /end-free‚*.....................................................................
p freeJavaObject E‚*.....................................................................
‚*.....................................................................
‚* begin object group...‚*.....................................................................
P beginObjGroup B D beginObjGroup PI D env * const D capacity 10I 0 value D rc s 10I 0‚*.....................................................................
/free JNIENV_P = env; rc = pushLocalFrame (JNIENV_P : capacity); /end-free‚*.....................................................................
p beginObjGroup E‚*.....................................................................
‚*.....................................................................
‚* End a group of objects...‚*.....................................................................
p endObjGroup B D endObjGroup PI D env * const D rc s 10I 0 D refobject s O CLASS(*JAVA:'java.lang.Object') D newobject s O CLASS(*JAVA:'java.lang.Object')‚*.....................................................................
/free JNIENV_P = env; refObject = *null; newObject = popLocalFrame (JNIENV_P : refObject); /end-free‚*.....................................................................
p endObjGroup E‚*.....................................................................
‚*.....................................................................
‚* getJniEnv - attach-to or start the JVM ‚* ‚* Parameters: ‚* 1. inputOpts - string of options separated by whatever the ‚* last character in the string is. ‚* For example ‚* -Djava.pool.size=800;-Dcompile=none; ‚* - ignored if the JVM is already started‚* - classpath is taken from the CLASSPATH environment
‚* variable ‚* Sample calls: ‚* env = getJniEnv() // take the defaults ‚* env = getJniEnv('-Djava.poolsize=800;' ‚* + '-Dcompile=none;') // specify 2 options ‚* env = getJniEnv('-Djava.poolsize=800!' ‚* + '-Dcompile=none!') // use ! as separator‚*.....................................................................
P getJniEnv b export‚*.....................................................................
D getJniEnv pi * D inputOpts 65535a varying const options(*nopass) D env s * inz(*null)‚*.....................................................................
/free env = attachJvm(); if (env = *null); if %parms() = 0 or %len(inputOpts) = 0; env = startJvm(); else; env = startJvm(inputOpts); endif; endif; g_jnienv = env; return env; /end-free‚*.....................................................................
P getJniEnv e‚*.....................................................................
‚*.....................................................................
‚* startJvm - try to start the JVM ‚* ‚* Parameters: ‚* 1. inputOpts - string of options separated by whatever the ‚* first character in the string is ‚* - ignored if the JVM is already started‚*.....................................................................
P startJvm b D startJvm pi * D inputOptsP 65535a varying const options(*nopass) D initArgs ds likeds(JavaVMInitArgs) D options ds likeds(JavaVMOption) occurs(10) D jvm s like(JavaVM_p) D env s like(JNIENV_p) inz(*null) D rc s 10I 0 D len s 10I 0 D prefix s 100a varying D pOptions s * inz(%addr(options)) D i s 10I 0 D classpath S 65535a varying ‚* For handling the input options... D splitChar s 1a D pos s 10I 0 D nextPos s 10I 0 D inputOpts s 65535a varying D inputOptsPtr s * D freeThisOccur s n dim(%elem(options)) inz(*off)‚*.....................................................................
/free monitor; initArgs = *allx'00'; JNI_GetDefaultJavaVMInitArgs (%addr(initArgs)); initArgs.version = JNI_VERSION_1_2; //‚Add classpath option... classpath = getClasspath(); //‚If classpath is blank, retrieve default classpath... if classpath = *blanks; setClasspath(getDefaultClasspath()); classpath = getClasspath(); endif; if (%len(classpath) > 0); initArgs.nOptions = initArgs.nOptions + 1; %occur(options) = initArgs.nOptions; freeThisOccur(initArgs.nOptions) = *on; options = *allx'00'; prefix = '-Djava.class.path=:'; len = %len(prefix) + %len(classpath) + 1; options.optionString = %alloc (len); %str(options.optionString : len) = cvtToAscii(prefix) + cvtToAscii(classpath); endif; // add any other options that were passed in... if %parms > 0 and %len(inputOptsP) > 0; inputOpts = cvtToAscii(inputOptsP); inputOptsPtr = %addr(inputOpts) + 2; splitChar = %subst(inputOpts : %len(inputOpts) : 1); pos = 1; dow pos <= %len(inputOpts); nextPos = %scan(splitChar : inputOpts : pos); len = nextPos - pos; %subst(inputOpts : nextPos : 1) = x'00'; initArgs.nOptions = initArgs.nOptions + 1; %occur(options) = initArgs.nOptions; options = *allx'00'; options.optionString = inputOptsPtr + pos - 1; pos = nextPos + 1; enddo; endif; if initArgs.nOptions > 0; initArgs.options = pOptions; endif; rc = JNI_CreateJavaVM (jvm : env : %addr(initArgs)); if (rc <> 0); env = *null; endif; on-error; env = *null; endmon; // free any storage allocated for the options... for i = 1 to initArgs.nOptions; if (freeThisOccur(i)); %occur(options) = i; dealloc(n) options.optionString; endif; endfor; return env; /end-free‚*.....................................................................
P startJvm e‚*.....................................................................
‚*.....................................................................
‚* attachJvm - try to attach to the JVM‚*.....................................................................
P attachJvm b‚*.....................................................................
D attachJvm pi * D attachArgs ds likeds(JavaVMAttachArgs) D jvm s like(JavaVM_p) dim(1) D nVms s like(jsize) D env s * inz(*null) D rc s 10I 0‚*.....................................................................
/free monitor; rc = JNI_GetCreatedJavaVMs(jvm : 1 : nVms); if (rc <> 0); return *null; endif; if (nVms = 0); return *null; endif; JavaVM_P = jvm(1); attachArgs = *allx'00'; attachArgs.version = JNI_VERSION_1_2; rc = AttachCurrentThread (jvm(1) : env : %addr(attachArgs)); if (rc <> 0); env = *null; endif; on-error; env = *null; endmon; g_jnienv = env; return env; /end-free‚*.....................................................................
P attachJvm e‚*.....................................................................
‚*.....................................................................
‚* Destroy the JVM...‚*.....................................................................
P destroyJVM B D destroyJVM PI 10I 0 D rc S LIKE(jint) D rpgRc S N D jvm S * DIM(1) D env S * D bufLen S LIKE(jsize) INZ(%elem(jvm)) D nVMs S LIKE(jsize)‚*.....................................................................
/free // See if there’s a JVM started... rc = JNI_GetCreatedJavaVMs (jvm : bufLen : nVMs); // If JVM is started... if (rc = 0 and nVMs > 0); JavaVM_P = jvm(1); rc = DestroyJavaVM (jvm(1)); endif; return rc; /end-free‚*.....................................................................
P destroyJVM E‚‚*.....................................................................
‚‚*.....................................................................
‚* getClasspath - retreive the CLASSPATH environment variable...‚‚*.....................................................................
P getClasspath B D getClasspath PI 65535A varying * See QSYSINC/H D Qp0zGetEnvNoInit... D PR * extproc('Qp0zGetEnvNoInit') D name * value options(*string) D envVarP S *‚‚*.....................................................................
/free envvarP = Qp0zGetEnvNoInit('CLASSPATH'); if (envvarP = *NULL); return ''; else; return %str(envvarP : 65535); endif; /end-free‚‚*.....................................................................
P getClasspath E‚‚*.....................................................................
‚‚*.....................................................................
‚* cvtToAscii - convert from EBCDIC to ASCII...‚‚*.....................................................................
P cvtToAscii B D cvtToAscii PI 65535A varying D input 65535A const varying D QDCXLATE PR extpgm('QDCXLATE') D len 5P 0 const D cnvData 65535A options(*varsize) D cnvTbl 10A const D cnvLib 10A const D retval S like(input) D retvalRef S 1A based(retvalPtr)‚‚*.....................................................................
/free retval = input; retvalPtr = %addr(retval) + 2; // set ptr after the length part QDCXLATE(%len(retval): retvalRef : 'QASCII': 'QSYS'); return retval; /end-free‚‚*.....................................................................
P cvtToAscii E‚‚*.....................................................................
‚‚*.....................................................................
p setErrorNo b‚‚*.....................................................................
d setErrorNo pi d sentErrorNo 5u 0 value‚*....................................................................
‚* Set the global error number...‚*....................................................................
/free errNo = sentErrorNo; /end-free‚*.....................................................................
p setErrorNo e‚*.....................................................................
p getErrorNo b export d getErrorNo pi 5u 0‚*.....................................................................
‚* Return the global error number...‚*.....................................................................
/free return errNo; /end-free‚*.....................................................................
p getErrorNo e‚‚*.....................................................................
p setXMLSource b export‚‚*.....................................................................
d setXMLSource pi 10i 0 d xmlPath 255a value‚*.....................................................................
/free getJVM(); //‚If StreamSource exists, free it... if xmlStreamSource <> *null; monitor; freeJavaObject(env:xmlStreamSource); on-error; setErrorNo(E_FREESTRSRC); return -1; endmon; endif; //‚Create XML file path string object... monitor; xmlFilePath = new_String(%trim(xmlPath)); on-error; setErrorNo(E_NOFILPTHSTR); return -1; endmon; //‚Create XML file object... monitor; xmlFile = new_File(xmlFilePath); on-error; setErrorNo(E_NOXMLFIL); return -1; endmon; //‚Free XML file path string object... monitor; freeJavaObject(env:xmlFilePath); on-error; setErrorNo(E_FREEFILSTR); return -1; endmon; //‚Create transform stream source XML ... monitor; xmlStreamSource = new_StreamSource(xmlFile); on-error; setErrorNo(E_TRANSSTRSRC); return -1; endmon; //‚Free XML stream file object... monitor; freeJavaObject(env:xmlFile); on-error; setErrorNo(E_FREEXMLFIL); return -1; endmon; currentXML = xmlPath; return 0; /end-free‚*.....................................................................
p setXMLSource e‚*.....................................................................
‚‚*.....................................................................
p getXMLSource b export‚‚*.....................................................................
d getXMLSource pi 255a‚*.....................................................................
/free //‚Return current XML document... return currentXML; /end-free‚*.....................................................................
p getXMLSource e‚*.....................................................................
‚‚*.....................................................................
p setXMLResult b export‚‚*.....................................................................
d setXMLResult pi 10i 0 d resultPath 255a value‚*.....................................................................
/free getJVM(); //‚If StreamResult exists, free it... if xmlStreamResult <> *null; monitor; freeJavaObject(env:xmlStreamResult); on-error; setErrorNo(E_FREESTRRES); return -1; endmon; endif; //‚Create XML result file path string object... monitor; resultFilePath = new_String(%trim(ResultPath)); on-error; setErrorNo(E_NOFILESTR); return -1; endmon; //‚Create result stream file object... monitor; resultFile = new_File(resultFilePath); on-error; setErrorNo(E_NORESFIL); return -1; endmon; //‚Free result file path string object... monitor; freeJavaObject(env:resultFilePath); on-error; setErrorNo(E_FREERESFILSTR); return -1; endmon; //‚Create transform XML result object... monitor; xmlStreamResult = new_StreamResult(resultFile); on-error; setErrorNo(E_TRANSRESFIL); return -1; endmon; //‚Free result stream file object... monitor; freeJavaObject(env:resultFile); on-error; setErrorNo(E_FREEXMLRES); return -1; endmon; currentResult = resultPath; return 0; /end-free‚*.....................................................................
p setXMLResult e‚*.....................................................................
‚‚*.....................................................................
p getXMLResult b export‚‚*.....................................................................
d getXMLResult pi 255a‚*.....................................................................
/free //‚Return current XML result document... return currentResult; /end-free‚*.....................................................................
p getXMLResult e‚*.....................................................................
‚‚*.....................................................................
p setTransformer b export‚‚*.....................................................................
d setTransformer pi 10i 0 d xsltPath 255a value‚*.....................................................................
/free getJVM(); //‚If StreamSource exists, free it... if transformer <> *null; monitor; freeJavaObject(env:transformer); on-error; setErrorNo(E_FREETRANS); return -1; endmon; endif; monitor; //‚Create stylesheet filepath string... xsltFilePath = new_String(%trim(XSLTPath)); on-error; setErrorNo(E_NOXSLTSTR); return -1; endmon; monitor; //‚Create stylesheet file object... xsltFile = new_File(XSLTFilePath); on-error; setErrorNo(E_NOXSLTFIL); return -1; endmon; //‚Free XML stylesheet filepath... monitor; freeJavaObject(env:xsltFilePath); on-error; setErrorNo(E_FREEXSLTPATH); return -1; endmon; monitor; //‚Create transform stylesheet stream source object... xsltStreamSource = new_StreamSource(xsltFile); on-error; setErrorNo(E_NOXSLTSRC); return -1; endmon; //‚Free XML stylesheet file object... monitor; freeJavaObject(env:xsltFile); on-error; setErrorNo(E_FREEXSLTFILE); return -1; endmon; if transFactory = *null; monitor; //‚Create new instance of the transformer factory... transFactory = new_TransformerFactory(); on-error; setErrorNo(E_NOTRANSFACT); return -1; endmon; endif; //‚Create transformer... monitor; transformer = new_Transformer(transFactory: xsltStreamSource); on-error; setErrorNo(E_NOTRANSFRMR); return -1; endmon; //‚Free XML stylesheet file... monitor; freeJavaObject(env:xsltStreamSource); on-error; setErrorNo(E_FREESTRSRC); return -1; endmon; currentXSLT = xsltPath; return 0; /end-free‚*.....................................................................
p setTransformer e‚*.....................................................................
‚‚*.....................................................................
p getTransformer b export‚‚*.....................................................................
d getTransformer pi 255a‚*.....................................................................
/free //‚Return current XSLT document... return currentXSLT; /end-free‚*.....................................................................
p getTransformer e‚*.....................................................................
‚‚*.....................................................................
p transform b export‚‚*.....................................................................
d transform pi 10i 0 d xmlPath 255a options(*nopass) d resultPath 255a options(*nopass) d xsltPath 255a options(*nopass)‚*.....................................................................
/free //‚If XML file passed, set it... if %parms > 0 and xmlPath <> *blanks; if setXMLSource(xmlPath) < 0; return -1; endif; endif; //‚If result file passed, set it... if %parms > 1 and resultPath <> *blanks; if setXMLResult(resultPath) < 0; return -1; endif; endif; //‚If transformer passed, set transformer... if %parms > 2 and xsltPath <> *blanks; if setTransformer(xsltPath) < 0; return -1; endif; endif; //‚Transform... monitor; transform_int(transformer: xmlStreamSource: xmlStreamResult); on-error; setErrorNo(E_TRANSFORM); return -1; endmon; return 0; /end-free‚*.....................................................................
p transform e‚*.....................................................................
‚*.....................................................................
‚* Retrieve error number in 4S, 0 format...‚*.....................................................................
p getErrorNo4S b export d getErrorNo4S pi 4s 0 d errorNo4S s 4s 0‚*.....................................................................
‚* Return the global error number in 4S, 0 format...‚*.....................................................................
/free if errNo >= 9999; errorNo4S = 9999; else; errorNo4S = errNo; endif; return errorNo4S; /end-free‚*.....................................................................
p getErrorNo4S e‚*.....................................................................
‚*.....................................................................
‚* Retrieve the Message ID for the specified error number...‚*.....................................................................
p getMSGID b export d getMSGID pi 7a d sentErrorNo 4s 0 value‚*.....................................................................
‚* Set the global error number...‚*.....................................................................
‚* Set message prefix ... /free return ('JVO' + %editc(sentErrorNo:'X')); /end-free‚*.....................................................................
p getMSGID e‚*..................................................................... ‚*.....................................................................
‚* Retrieve the classpath‚*.....................................................................
p setClasspath b export d setClasspath pi d inputClasspath 65535a varying const /free monitor; //‚Set classpath... CP_rtcd = putenv('CLASSPATH=' + %trim(inputClasspath)); on-error; setErrorNo(E_NOCLASSPATH); endmon; return; /end-free‚*.....................................................................
p setClasspath e‚*.....................................................................
‚*.....................................................................
p getJVM b export d getJVM pi 10i 0‚*.....................................................................
/free monitor; //‚Get the current environment (or start a new JVM)... env = getJniEnv('-Djava.version=1.4;'); on-error; setErrorNo(E_NOJNIJVM); return -1; endmon; return 0; /end-free p getJVM e‚*.....................................................................
‚*.....................................................................
p getDefaultclasspath... p b export d getDefaultclasspath... d pi 65535a‚* Prototype variables... €
d idx s 10i 0 d classpath s 65535a varying d propFile s 255a inz(*blanks) D line s 1024a D lineLen s 10i 0 inz(%size(line)) D dataLen s 10i 0 D equalPos s 10i 0‚*.....................................................................
/free //‚Set properties file name... propFile = '/QIBM/UserData/XML2SQL.properties'; //‚Open the IFS file... fullName = %TrimR(propFile) + ##Null; file = IFS_Open(%addr(fullName):##TextData + ##ReadWrite); //‚If unable to open file, return blanks... if file < 0; return *blanks; endif; dow dataLen >= 0; //‚Read a line from the IFS file... dataLen = readLine(file:%addr(line):lineLen); //‚If EOF or error, leave loop... if dataLen < 0; leave; endif; //‚Ignore comment lines... if %subst(line:1:1) = '#'; iter; endif; //‚Ignore lines that do not have '='... equalPos = %scan('=':line:1); if equalPos = 0; iter; endif;//‚If property is CLASSPATH property, retrieve it and leave loop...
if %subst(line:1:equalPos-1) = 'CLASSPATH'; classpath = %trim(%subst(line:equalPos+1 :lineLen-equalPos)); leave; endif; enddo; //‚Close the file... IFS_Close(file); //‚Return the classpath... return classpath; /end-free‚*.....................................................................
p getDefaultclasspath... p e‚*.....................................................................
‚********************************************************************** €
‚* readLine - Read a line from the file...‚*************************************************************************
p readLine b d readLine pi 10i 0 d file 10i 0 value d line * value d lineLen 10i 0 value‚* Prototype variables... €
d rc s 10i 0 inz(*zero) D ch s 1a inz(*blanks) D tempLineLen s 10i 0 inz(*zero) D tempLine s 32766a based(line) D carriageReturn c const(X'0D') D lineFeed c const(X'25')‚*************************************************************************
‚* Initialise temporary field, based on passed pointer... c eval %subst(tempLine:1:lineLen) = *blanks ‚* Read a line from the IFS file (byte-by-byte)... c do *hival c eval rc = IFS_Read( file: %addr(ch) : 1) ‚* If EOF or an error occurred... c if rc < 1 ‚* If there is data on the line, return line length... c if tempLineLen > 0 c return tempLineLen ‚* If there is no data on the line, return error... c else c return -1 c endif c endif ‚* Once a line-feed has been reached, return line length... c if ch = lineFeed c return tempLineLen c endif ‚* Include all non-carriage return characters in current line... c if ch <> carriageReturn c eval tempLineLen += 1 c eval %subst(tempLine:tempLineLen:1) = ch c endif ‚* If reached length of passed pointer, leave... c if tempLineLen = lineLen c leave c endif c enddo‚* Return qualified job description... €
c return tempLineLen‚*********************************************************************
p readLine e‚*************************************************************************
Cheers Larry Ducie
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.