Beispiel: Java-Aufruf-API
Dieses ILE C-Beispiel (Integrated Language Environment) folgt dem Standardkonzept der Invocation-API.
Sie führt Folgendes aus:
- Erstellt eine Java™ Virtual Machine mithilfe von
JNI_CreateJavaVM(). - Verwendet die Java Virtual Machine, um die auszuführende Klassendatei zu suchen.
- Sucht die methodID für die Hauptmethode der Klasse.
- Ruft die Hauptmethode der Klasse auf.
- Meldet Fehler, wenn eine Ausnahmebedingung auftritt.
Wenn Sie das Programm erstellen, stellt das Serviceprogramm QJVAJNI oder QJVAJNI64 die JNI_CreateJavaVM() -API-Funktion bereit. JNI_CreateJavaVM() erstellt die Java Virtual Machine.
Diese Serviceprogramme befinden sich im Systembinderverzeichnis und müssen nicht explizit in einem CL-Erstellungsbefehl angegeben werden. Beispielsweise würden Sie die zuvor genannten Serviceprogramme nicht explizit angeben, wenn Sie den Befehl CRTPGM (Programm erstellen) oder CRTSRVPGM (Serviceprogramm erstellen) verwenden.
Eine Möglichkeit, dieses Programm auszuführen, ist die Verwendung des folgenden Steuersprachenbefehls:
SBMJOB CMD(CALL PGM(YOURLIB/PGMNAME)) ALWMLTTHD(*YES)Jeder Job, der eine Java Virtual Machine erstellt, muss multithreadfähig sein. Die Ausgabe des Hauptprogramms sowie die Ausgabe des Programms werden in QPRINT-Spooldateien gespeichert. Diese Spool-Dateien sind sichtbar, wenn Sie den CL-Befehl WRKSBMJOB (Mit übergebenen Jobs arbeiten) verwenden und den gestarteten Job mit dem CL-Befehl SBMJOB (Job übergeben) anzeigen.
Beispiel: Java-Aufruf-API in ILE C verwenden
#define OS400_JVM_12
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <jni.h>
/* Specify the pragma that causes all literal strings in the
* source code to be stored in ASCII (which, for the strings
* used, is equivalent to UTF-8)
*/
#pragma convert(819)
/* Procedure: Oops
*
* Description: Helper routine that is called when a JNI function
* returns a zero value, indicating a serious error.
* This routine reports the exception to stderr and
* ends the JVM abruptly with a call to FatalError.
*
* Parameters: env -- JNIEnv* to use for JNI calls
* msg -- char* pointing to error description in UTF-8
*
* Note: Control does not return after the call to FatalError
* and it does not return from this procedure.
*/
void Oops(JNIEnv* env, char *msg) {
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
(*env)->FatalError(env, msg);
}
/* This is the program's "main" routine. */
int main (int argc, char *argv[])
{
JavaVMInitArgs initArgs; /* Virtual Machine (VM) initialization structure, passed by
* reference to JNI_CreateJavaVM(). See jni.h for details
*/
JavaVM* myJVM; /* JavaVM pointer set by call to JNI_CreateJavaVM */
JNIEnv* myEnv; /* JNIEnv pointer set by call to JNI_CreateJavaVM */
char* myClasspath; /* Changeable classpath 'string' */
jclass myClass; /* The class to call, 'NativeHello'. */
jmethodID mainID; /* The method ID of its 'main' routine. */
jclass stringClass; /* Needed to create the String[] arg for main */
jobjectArray args; /* The String[] itself */
JavaVMOption options[1]; /* Options array -- use options to set classpath */
int fd0, fd1, fd2; /* file descriptors for IO */
/* Open the file descriptors so that IO works. */
fd0 = open("/dev/null", O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IROTH);
fd1 = open("/dev/null", O_CREAT|O_TRUNC|O_WRONLY, S_IWUSR|S_IWOTH);
fd2 = open("/dev/null", O_CREAT|O_TRUNC|O_WRONLY, S_IWUSR|S_IWOTH);
/* Set the version field of the initialization arguments for JNI v1.4. */
initArgs.version = 0x00010004;
/* Now, you want to specify the directory for the class to run in the classpath.
* with Java2, classpath is passed in as an option.
* Note: You must specify the directory name in UTF-8 format. So, you wrap
* blocks of code in #pragma convert statements.
*/
options[0].optionString="-Djava.class.path=/CrtJvmExample";
initArgs.options=options; /* Pass in the classpath that has been set up. */
initArgs.nOptions = 1; /* Pass in classpath and version options */
/* Create the JVM -- a nonzero return code indicates there was
* an error. Drop back into EBCDIC and write a message to stderr
* before exiting the program.
* Note: This will run the default JVM and JDK which is 32bit JDK 6.0.
* If you want to run a different JVM and JDK, set the JAVA_HOME environment
* variable to the home directory of the JVM you want to use
* (prior to the CreateJavaVM() call).
*/
if (JNI_CreateJavaVM(&myJVM, (void **)&myEnv, (void *)&initArgs)) {
#pragma convert(0)
fprintf(stderr, "Failed to create the JVM\n");
#pragma convert(819)
exit(1);
}
/* Use the newly created JVM to find the example class,
* called 'NativeHello'.
*/
myClass = (*myEnv)->FindClass(myEnv, "NativeHello");
if (! myClass) {
Oops(myEnv, "Failed to find class 'NativeHello'");
}
/* Now, get the method identifier for the 'main' entry point
* of the class.
* Note: The signature of 'main' is always the same for any
* class called by the following java command:
* "main" , "([Ljava/lang/String;)V"
*/
mainID = (*myEnv)->GetStaticMethodID(myEnv,myClass,"main",
"([Ljava/lang/String;)V");
if (! mainID) {
Oops(myEnv, "Failed to find jmethodID of 'main'");
}
/* Get the jclass for String to create the array
* of String to pass to 'main'.
*/
stringClass = (*myEnv)->FindClass(myEnv, "java/lang/String");
if (! stringClass) {
Oops(myEnv, "Failed to find java/lang/String");
}
/* Now, you need to create an empty array of strings,
* since main requires such an array as a parameter.
*/
args = (*myEnv)->NewObjectArray(myEnv,0,stringClass,0);
if (! args) {
Oops(myEnv, "Failed to create args array");
}
/* Now, you have the methodID of main and the class, so you can
* call the main method.
*/
(*myEnv)->CallStaticVoidMethod(myEnv,myClass,mainID,args);
/* Check for errors. */
if ((*myEnv)->ExceptionOccurred(myEnv)) {
(*myEnv)->ExceptionDescribe(myEnv);
}
/* Finally, destroy the JavaVM that you created. */
(*myJVM)->DestroyJavaVM(myJVM);
/* All done. */
return 0;
}Weitere Informationen finden Sie unter Java Invocation API.