aboutsummaryrefslogtreecommitdiffstats
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/java.c2019
-rw-r--r--launcher/java.h115
-rw-r--r--launcher/java_md.c1786
-rw-r--r--launcher/java_md.h73
-rw-r--r--launcher/jli_util.h36
-rw-r--r--launcher/jni.h1959
-rw-r--r--launcher/jvm.h1501
-rw-r--r--launcher/jvm_md.h77
-rw-r--r--launcher/manifest_info.h156
-rw-r--r--launcher/splashscreen.h31
-rw-r--r--launcher/splashscreen_stubs.c78
-rw-r--r--launcher/version_comp.h37
-rw-r--r--launcher/wildcard.h35
13 files changed, 7903 insertions, 0 deletions
diff --git a/launcher/java.c b/launcher/java.c
new file mode 100644
index 0000000..2a8f41e
--- /dev/null
+++ b/launcher/java.c
@@ -0,0 +1,2019 @@
+/*
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Shared source for 'java' command line tool.
+ *
+ * If JAVA_ARGS is defined, then acts as a launcher for applications. For
+ * instance, the JDK command line tools such as javac and javadoc (see
+ * makefiles for more details) are built with this program. Any arguments
+ * prefixed with '-J' will be passed directly to the 'java' command.
+ */
+
+/*
+ * One job of the launcher is to remove command line options which the
+ * vm does not understand and will not process. These options include
+ * options which select which style of vm is run (e.g. -client and
+ * -server) as well as options which select the data model to use.
+ * Additionally, for tools which invoke an underlying vm "-J-foo"
+ * options are turned into "-foo" options to the vm. This option
+ * filtering is handled in a number of places in the launcher, some of
+ * it in machine-dependent code. In this file, the function
+ * CheckJVMType removes vm style options and TranslateApplicationArgs
+ * removes "-J" prefixes. On unix platforms, the
+ * CreateExecutionEnvironment function from the unix java_md.c file
+ * processes and removes -d<n> options. However, in case
+ * CreateExecutionEnvironment does not need to exec because
+ * LD_LIBRARY_PATH is set acceptably and the data model does not need
+ * to be changed, ParseArguments will screen out the redundant -d<n>
+ * options and prevent them from being passed to the vm; this is done
+ * by using the machine-dependent call
+ * RemovableMachineDependentOption.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <jni.h>
+#include <jvm.h>
+#include "java.h"
+#include "manifest_info.h"
+#include "version_comp.h"
+#include "wildcard.h"
+#include "splashscreen.h"
+
+#ifndef FULL_VERSION
+#define FULL_VERSION JDK_MAJOR_VERSION "." JDK_MINOR_VERSION
+#endif
+
+/*
+ * The following environment variable is used to influence the behavior
+ * of the jre exec'd through the SelectVersion routine. The command line
+ * options which specify the version are not passed to the exec'd version,
+ * because that jre may be an older version which wouldn't recognize them.
+ * This environment variable is known to this (and later) version and serves
+ * to suppress the version selection code. This is not only for efficiency,
+ * but also for correctness, since any command line options have been
+ * removed which would cause any value found in the manifest to be used.
+ * This would be incorrect because the command line options are defined
+ * to take precedence.
+ *
+ * The value associated with this environment variable is the MainClass
+ * name from within the executable jar file (if any). This is strictly a
+ * performance enhancement to avoid re-reading the jar file manifest.
+ *
+ * A NOTE TO DEVELOPERS: For performance reasons it is important that
+ * the program image remain relatively small until after SelectVersion
+ * CreateExecutionEnvironment have finished their possibly recursive
+ * processing. Watch everything, but resist all temptations to use Java
+ * interfaces.
+ */
+#define ENV_ENTRY "_JAVA_VERSION_SET"
+
+#define SPLASH_FILE_ENV_ENTRY "_JAVA_SPLASH_FILE"
+#define SPLASH_JAR_ENV_ENTRY "_JAVA_SPLASH_JAR"
+
+static jboolean printVersion = JNI_FALSE; /* print and exit */
+static jboolean showVersion = JNI_FALSE; /* print but continue */
+static jboolean printUsage = JNI_FALSE; /* print and exit*/
+static jboolean printXUsage = JNI_FALSE; /* print and exit*/
+static char *progname;
+static char *launchername;
+jboolean _launcher_debug = JNI_FALSE;
+
+/*
+ * Entries for splash screen environment variables.
+ * putenv is performed in SelectVersion. We need
+ * them in memory until UnsetEnv, so they are made static
+ * global instead of auto local.
+ */
+static char* splash_file_entry = NULL;
+static char* splash_jar_entry = NULL;
+
+/*
+ * List of VM options to be specified when the VM is created.
+ */
+static JavaVMOption *options;
+static int numOptions, maxOptions;
+
+/*
+ * Prototypes for functions internal to launcher.
+ */
+static void SetClassPath(const char *s);
+static void SelectVersion(int argc, char **argv, char **main_class);
+static jboolean ParseArguments(int *pargc, char ***pargv, char **pjarfile,
+ char **pclassname, int *pret, const char *jvmpath);
+static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
+ InvocationFunctions *ifn);
+static jstring NewPlatformString(JNIEnv *env, char *s);
+static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc);
+static jclass LoadClass(JNIEnv *env, char *name);
+static jstring GetMainClassName(JNIEnv *env, char *jarname);
+static void SetJavaCommandLineProp(char* classname, char* jarfile, int argc, char** argv);
+static void SetJavaLauncherProp(void);
+
+#ifdef JAVA_ARGS
+static void TranslateApplicationArgs(int *pargc, char ***pargv);
+static jboolean AddApplicationOptions(void);
+#endif
+
+static void PrintJavaVersion(JNIEnv *env);
+static void PrintUsage(JNIEnv* env, jboolean doXUsage);
+
+static void SetPaths(int argc, char **argv);
+
+
+/* Maximum supported entries from jvm.cfg. */
+#define INIT_MAX_KNOWN_VMS 10
+/* Values for vmdesc.flag */
+#define VM_UNKNOWN -1
+#define VM_KNOWN 0
+#define VM_ALIASED_TO 1
+#define VM_WARN 2
+#define VM_ERROR 3
+#define VM_IF_SERVER_CLASS 4
+#define VM_IGNORE 5
+struct vmdesc {
+ char *name;
+ int flag;
+ char *alias;
+ char *server_class;
+};
+static struct vmdesc *knownVMs = NULL;
+static int knownVMsCount = 0;
+static int knownVMsLimit = 0;
+
+static void GrowKnownVMs();
+static int KnownVMIndex(const char* name);
+static void FreeKnownVMs();
+static void ShowSplashScreen();
+
+jboolean ServerClassMachine();
+
+/* flag which if set suppresses error messages from the launcher */
+static int noExitErrorMessage = 0;
+
+/*
+ * Running Java code in primordial thread caused many problems. We will
+ * create a new thread to invoke JVM. See 6316197 for more information.
+ */
+static jlong threadStackSize = 0; /* stack size of the new thread */
+
+int JNICALL JavaMain(void * args); /* entry point */
+
+struct JavaMainArgs {
+ int argc;
+ char ** argv;
+ char * jarfile;
+ char * classname;
+ InvocationFunctions ifn;
+};
+
+/*
+ * Entry point.
+ */
+int
+main(int argc, char ** argv)
+{
+ char *jarfile = 0;
+ char *classname = 0;
+ char *s = 0;
+ char *main_class = NULL;
+ int ret;
+ InvocationFunctions ifn;
+ jlong start, end;
+ char jrepath[MAXPATHLEN], jvmpath[MAXPATHLEN];
+ char ** original_argv = argv;
+
+ if (getenv("_JAVA_LAUNCHER_DEBUG") != 0) {
+ int i;
+ _launcher_debug = JNI_TRUE;
+ printf("----_JAVA_LAUNCHER_DEBUG----\n");
+ printf("Command line Args:\n");
+ for(i = 0; i < argc+1; i++) {
+ if (argv[i] != NULL){
+ printf("\targv[%d] = '%s'\n",i,argv[i]);
+ }
+ }
+ }
+
+
+
+ /*
+ * Make sure the specified version of the JRE is running.
+ *
+ * There are three things to note about the SelectVersion() routine:
+ * 1) If the version running isn't correct, this routine doesn't
+ * return (either the correct version has been exec'd or an error
+ * was issued).
+ * 2) Argc and Argv in this scope are *not* altered by this routine.
+ * It is the responsibility of subsequent code to ignore the
+ * arguments handled by this routine.
+ * 3) As a side-effect, the variable "main_class" is guaranteed to
+ * be set (if it should ever be set). This isn't exactly the
+ * poster child for structured programming, but it is a small
+ * price to pay for not processing a jar file operand twice.
+ * (Note: This side effect has been disabled. See comment on
+ * bugid 5030265 below.)
+ */
+ SelectVersion(argc, argv, &main_class);
+
+ /* copy original argv */
+ {
+ int i;
+ original_argv = (char**)JLI_MemAlloc(sizeof(char*)*(argc+1));
+ for(i = 0; i < argc+1; i++) {
+ original_argv[i] = argv[i];
+ }
+ }
+
+ CreateExecutionEnvironment(&argc, &argv,
+ jrepath, sizeof(jrepath),
+ jvmpath, sizeof(jvmpath),
+ original_argv);
+
+ ifn.CreateJavaVM = 0;
+ ifn.GetDefaultJavaVMInitArgs = 0;
+
+ if (_launcher_debug)
+ start = CounterGet();
+ if (!LoadJavaVM(jvmpath, &ifn)) {
+ exit(6);
+ }
+ if (_launcher_debug) {
+ end = CounterGet();
+ printf("%ld micro seconds to LoadJavaVM\n",
+ (long)(jint)Counter2Micros(end-start));
+ }
+
+#ifdef JAVA_ARGS /* javac, jar and friends. */
+ progname = "java";
+#else /* java, oldjava, javaw and friends */
+#ifdef PROGNAME
+ progname = PROGNAME;
+#else
+ progname = *argv;
+ if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) {
+ progname = s + 1;
+ }
+#endif /* PROGNAME */
+#endif /* JAVA_ARGS */
+
+#ifdef LAUNCHER_NAME
+ launchername = LAUNCHER_NAME;
+#else
+ launchername = progname;
+#endif /* LAUNCHER_NAME */
+
+ ++argv;
+ --argc;
+
+#ifdef JAVA_ARGS
+ /* Preprocess wrapper arguments */
+ TranslateApplicationArgs(&argc, &argv);
+ if (!AddApplicationOptions()) {
+ exit(1);
+ }
+#endif
+
+ /* Set default CLASSPATH */
+ if ((s = getenv("CLASSPATH")) == 0) {
+ s = ".";
+ }
+#ifndef JAVA_ARGS
+ SetClassPath(s);
+#endif
+
+ /*
+ * Parse command line options; if the return value of
+ * ParseArguments is false, the program should exit.
+ */
+ if (!ParseArguments(&argc, &argv, &jarfile, &classname, &ret, jvmpath)) {
+ exit(ret);
+ }
+
+ /* Override class path if -jar flag was specified */
+ if (jarfile != 0) {
+ SetClassPath(jarfile);
+ }
+
+ /* set the -Dsun.java.command pseudo property */
+ SetJavaCommandLineProp(classname, jarfile, argc, argv);
+
+ /* Set the -Dsun.java.launcher pseudo property */
+ SetJavaLauncherProp();
+
+ /* set the -Dsun.java.launcher.* platform properties */
+ SetJavaLauncherPlatformProps();
+
+ /* Show the splash screen if needed */
+ ShowSplashScreen();
+
+ /*
+ * Done with all command line processing and potential re-execs so
+ * clean up the environment.
+ */
+ (void)UnsetEnv(ENV_ENTRY);
+ (void)UnsetEnv(SPLASH_FILE_ENV_ENTRY);
+ (void)UnsetEnv(SPLASH_JAR_ENV_ENTRY);
+
+ JLI_MemFree(splash_jar_entry);
+ JLI_MemFree(splash_file_entry);
+
+ /*
+ * If user doesn't specify stack size, check if VM has a preference.
+ * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will
+ * return its default stack size through the init args structure.
+ */
+ if (threadStackSize == 0) {
+ struct JDK1_1InitArgs args1_1;
+ memset((void*)&args1_1, 0, sizeof(args1_1));
+ args1_1.version = JNI_VERSION_1_1;
+ ifn.GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */
+ if (args1_1.javaStackSize > 0) {
+ threadStackSize = args1_1.javaStackSize;
+ }
+ }
+
+ { /* Create a new thread to create JVM and invoke main method */
+ struct JavaMainArgs args;
+
+ args.argc = argc;
+ args.argv = argv;
+ args.jarfile = jarfile;
+ args.classname = classname;
+ args.ifn = ifn;
+
+ return ContinueInNewThread(JavaMain, threadStackSize, (void*)&args, ret);
+ }
+}
+
+int JNICALL
+JavaMain(void * _args)
+{
+ struct JavaMainArgs *args = (struct JavaMainArgs *)_args;
+ int argc = args->argc;
+ char **argv = args->argv;
+ char *jarfile = args->jarfile;
+ char *classname = args->classname;
+ InvocationFunctions ifn = args->ifn;
+
+ JavaVM *vm = 0;
+ JNIEnv *env = 0;
+ jstring mainClassName;
+ jclass mainClass;
+ jmethodID mainID;
+ jobjectArray mainArgs;
+ int ret = 0;
+ jlong start, end;
+
+ /*
+ * Error message to print or display; by default the message will
+ * only be displayed in a window.
+ */
+ char * message = "Fatal exception occurred. Program will exit.";
+ jboolean messageDest = JNI_FALSE;
+
+ /* Initialize the virtual machine */
+
+ if (_launcher_debug)
+ start = CounterGet();
+ if (!InitializeJVM(&vm, &env, &ifn)) {
+ ReportErrorMessage("Could not create the Java virtual machine.",
+ JNI_TRUE);
+ exit(1);
+ }
+
+ if (printVersion || showVersion) {
+ PrintJavaVersion(env);
+ if ((*env)->ExceptionOccurred(env)) {
+ ReportExceptionDescription(env);
+ goto leave;
+ }
+ if (printVersion) {
+ ret = 0;
+ message = NULL;
+ goto leave;
+ }
+ if (showVersion) {
+ fprintf(stderr, "\n");
+ }
+ }
+
+ /* If the user specified neither a class name nor a JAR file */
+ if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
+ PrintUsage(env, printXUsage);
+ if ((*env)->ExceptionOccurred(env)) {
+ ReportExceptionDescription(env);
+ ret=1;
+ }
+ message = NULL;
+ goto leave;
+ }
+
+
+
+ FreeKnownVMs(); /* after last possible PrintUsage() */
+
+ if (_launcher_debug) {
+ end = CounterGet();
+ printf("%ld micro seconds to InitializeJVM\n",
+ (long)(jint)Counter2Micros(end-start));
+ }
+
+ /* At this stage, argc/argv have the applications' arguments */
+ if (_launcher_debug) {
+ int i = 0;
+ printf("Main-Class is '%s'\n", classname ? classname : "");
+ printf("Apps' argc is %d\n", argc);
+ for (; i < argc; i++) {
+ printf(" argv[%2d] = '%s'\n", i, argv[i]);
+ }
+ }
+
+ ret = 1;
+
+ /*
+ * Get the application's main class.
+ *
+ * See bugid 5030265. The Main-Class name has already been parsed
+ * from the manifest, but not parsed properly for UTF-8 support.
+ * Hence the code here ignores the value previously extracted and
+ * uses the pre-existing code to reextract the value. This is
+ * possibly an end of release cycle expedient. However, it has
+ * also been discovered that passing some character sets through
+ * the environment has "strange" behavior on some variants of
+ * Windows. Hence, maybe the manifest parsing code local to the
+ * launcher should never be enhanced.
+ *
+ * Hence, future work should either:
+ * 1) Correct the local parsing code and verify that the
+ * Main-Class attribute gets properly passed through
+ * all environments,
+ * 2) Remove the vestages of maintaining main_class through
+ * the environment (and remove these comments).
+ */
+ if (jarfile != 0) {
+ mainClassName = GetMainClassName(env, jarfile);
+ if ((*env)->ExceptionOccurred(env)) {
+ ReportExceptionDescription(env);
+ goto leave;
+ }
+ if (mainClassName == NULL) {
+ const char * format = "Failed to load Main-Class manifest "
+ "attribute from\n%s";
+ message = (char*)JLI_MemAlloc((strlen(format) + strlen(jarfile)) *
+ sizeof(char));
+ sprintf(message, format, jarfile);
+ messageDest = JNI_TRUE;
+ goto leave;
+ }
+ classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
+ if (classname == NULL) {
+ ReportExceptionDescription(env);
+ goto leave;
+ }
+ mainClass = LoadClass(env, classname);
+ if(mainClass == NULL) { /* exception occured */
+ const char * format = "Could not find the main class: %s. Program will exit.";
+ ReportExceptionDescription(env);
+ message = (char *)JLI_MemAlloc((strlen(format) +
+ strlen(classname)) * sizeof(char));
+ messageDest = JNI_TRUE;
+ sprintf(message, format, classname);
+ goto leave;
+ }
+ (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
+ } else {
+ mainClassName = NewPlatformString(env, classname);
+ if (mainClassName == NULL) {
+ const char * format = "Failed to load Main Class: %s";
+ message = (char *)JLI_MemAlloc((strlen(format) + strlen(classname)) *
+ sizeof(char) );
+ sprintf(message, format, classname);
+ messageDest = JNI_TRUE;
+ goto leave;
+ }
+ classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
+ if (classname == NULL) {
+ ReportExceptionDescription(env);
+ goto leave;
+ }
+ mainClass = LoadClass(env, classname);
+ if(mainClass == NULL) { /* exception occured */
+ const char * format = "Could not find the main class: %s. Program will exit.";
+ ReportExceptionDescription(env);
+ message = (char *)JLI_MemAlloc((strlen(format) +
+ strlen(classname)) * sizeof(char));
+ messageDest = JNI_TRUE;
+ sprintf(message, format, classname);
+ goto leave;
+ }
+ (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
+ }
+
+ /* Get the application's main method */
+ mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
+ "([Ljava/lang/String;)V");
+ if (mainID == NULL) {
+ if ((*env)->ExceptionOccurred(env)) {
+ ReportExceptionDescription(env);
+ } else {
+ message = "No main method found in specified class.";
+ messageDest = JNI_TRUE;
+ }
+ goto leave;
+ }
+
+ { /* Make sure the main method is public */
+ jint mods;
+ jmethodID mid;
+ jobject obj = (*env)->ToReflectedMethod(env, mainClass,
+ mainID, JNI_TRUE);
+
+ if( obj == NULL) { /* exception occurred */
+ ReportExceptionDescription(env);
+ goto leave;
+ }
+
+ mid =
+ (*env)->GetMethodID(env,
+ (*env)->GetObjectClass(env, obj),
+ "getModifiers", "()I");
+ if ((*env)->ExceptionOccurred(env)) {
+ ReportExceptionDescription(env);
+ goto leave;
+ }
+
+ mods = (*env)->CallIntMethod(env, obj, mid);
+ if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */
+ message = "Main method not public.";
+ messageDest = JNI_TRUE;
+ goto leave;
+ }
+ }
+
+ /* Build argument array */
+ mainArgs = NewPlatformStringArray(env, argv, argc);
+ if (mainArgs == NULL) {
+ ReportExceptionDescription(env);
+ goto leave;
+ }
+
+ /* Invoke main method. */
+ (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
+
+ /*
+ * The launcher's exit code (in the absence of calls to
+ * System.exit) will be non-zero if main threw an exception.
+ */
+ ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
+
+ /*
+ * Detach the main thread so that it appears to have ended when
+ * the application's main method exits. This will invoke the
+ * uncaught exception handler machinery if main threw an
+ * exception. An uncaught exception handler cannot change the
+ * launcher's return code except by calling System.exit.
+ */
+ if ((*vm)->DetachCurrentThread(vm) != 0) {
+ message = "Could not detach main thread.";
+ messageDest = JNI_TRUE;
+ ret = 1;
+ goto leave;
+ }
+
+ message = NULL;
+
+ leave:
+ /*
+ * Wait for all non-daemon threads to end, then destroy the VM.
+ * This will actually create a trivial new Java waiter thread
+ * named "DestroyJavaVM", but this will be seen as a different
+ * thread from the one that executed main, even though they are
+ * the same C thread. This allows mainThread.join() and
+ * mainThread.isAlive() to work as expected.
+ */
+ (*vm)->DestroyJavaVM(vm);
+
+ if(message != NULL && !noExitErrorMessage)
+ ReportErrorMessage(message, messageDest);
+ return ret;
+}
+
+
+/*
+ * Checks the command line options to find which JVM type was
+ * specified. If no command line option was given for the JVM type,
+ * the default type is used. The environment variable
+ * JDK_ALTERNATE_VM and the command line option -XXaltjvm= are also
+ * checked as ways of specifying which JVM type to invoke.
+ */
+char *
+CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
+ int i, argi;
+ int argc;
+ char **newArgv;
+ int newArgvIdx = 0;
+ int isVMType;
+ int jvmidx = -1;
+ char *jvmtype = getenv("JDK_ALTERNATE_VM");
+
+ argc = *pargc;
+
+ /* To make things simpler we always copy the argv array */
+ newArgv = JLI_MemAlloc((argc + 1) * sizeof(char *));
+
+ /* The program name is always present */
+ newArgv[newArgvIdx++] = (*argv)[0];
+
+ for (argi = 1; argi < argc; argi++) {
+ char *arg = (*argv)[argi];
+ isVMType = 0;
+
+#ifdef JAVA_ARGS
+ if (arg[0] != '-') {
+ newArgv[newArgvIdx++] = arg;
+ continue;
+ }
+#else
+ if (strcmp(arg, "-classpath") == 0 ||
+ strcmp(arg, "-cp") == 0) {
+ newArgv[newArgvIdx++] = arg;
+ argi++;
+ if (argi < argc) {
+ newArgv[newArgvIdx++] = (*argv)[argi];
+ }
+ continue;
+ }
+ if (arg[0] != '-') break;
+#endif
+
+ /* Did the user pass an explicit VM type? */
+ i = KnownVMIndex(arg);
+ if (i >= 0) {
+ jvmtype = knownVMs[jvmidx = i].name + 1; /* skip the - */
+ isVMType = 1;
+ *pargc = *pargc - 1;
+ }
+
+ /* Did the user specify an "alternate" VM? */
+ else if (strncmp(arg, "-XXaltjvm=", 10) == 0 || strncmp(arg, "-J-XXaltjvm=", 12) == 0) {
+ isVMType = 1;
+ jvmtype = arg+((arg[1]=='X')? 10 : 12);
+ jvmidx = -1;
+ }
+
+ if (!isVMType) {
+ newArgv[newArgvIdx++] = arg;
+ }
+ }
+
+ /*
+ * Finish copying the arguments if we aborted the above loop.
+ * NOTE that if we aborted via "break" then we did NOT copy the
+ * last argument above, and in addition argi will be less than
+ * argc.
+ */
+ while (argi < argc) {
+ newArgv[newArgvIdx++] = (*argv)[argi];
+ argi++;
+ }
+
+ /* argv is null-terminated */
+ newArgv[newArgvIdx] = 0;
+
+ /* Copy back argv */
+ *argv = newArgv;
+ *pargc = newArgvIdx;
+
+ /* use the default VM type if not specified (no alias processing) */
+ if (jvmtype == NULL) {
+ char* result = knownVMs[0].name+1;
+ /* Use a different VM type if we are on a server class machine? */
+ if ((knownVMs[0].flag == VM_IF_SERVER_CLASS) &&
+ (ServerClassMachine() == JNI_TRUE)) {
+ result = knownVMs[0].server_class+1;
+ }
+ if (_launcher_debug) {
+ printf("Default VM: %s\n", result);
+ }
+ return result;
+ }
+
+ /* if using an alternate VM, no alias processing */
+ if (jvmidx < 0)
+ return jvmtype;
+
+ /* Resolve aliases first */
+ {
+ int loopCount = 0;
+ while (knownVMs[jvmidx].flag == VM_ALIASED_TO) {
+ int nextIdx = KnownVMIndex(knownVMs[jvmidx].alias);
+
+ if (loopCount > knownVMsCount) {
+ if (!speculative) {
+ ReportErrorMessage("Error: Corrupt jvm.cfg file; cycle in alias list.",
+ JNI_TRUE);
+ exit(1);
+ } else {
+ return "ERROR";
+ /* break; */
+ }
+ }
+
+ if (nextIdx < 0) {
+ if (!speculative) {
+ ReportErrorMessage2("Error: Unable to resolve VM alias %s",
+ knownVMs[jvmidx].alias, JNI_TRUE);
+ exit(1);
+ } else {
+ return "ERROR";
+ }
+ }
+ jvmidx = nextIdx;
+ jvmtype = knownVMs[jvmidx].name+1;
+ loopCount++;
+ }
+ }
+
+ switch (knownVMs[jvmidx].flag) {
+ case VM_WARN:
+ if (!speculative) {
+ fprintf(stderr, "Warning: %s VM not supported; %s VM will be used\n",
+ jvmtype, knownVMs[0].name + 1);
+ }
+ /* fall through */
+ case VM_IGNORE:
+ jvmtype = knownVMs[jvmidx=0].name + 1;
+ /* fall through */
+ case VM_KNOWN:
+ break;
+ case VM_ERROR:
+ if (!speculative) {
+ ReportErrorMessage2("Error: %s VM not supported", jvmtype, JNI_TRUE);
+ exit(1);
+ } else {
+ return "ERROR";
+ }
+ }
+
+ return jvmtype;
+}
+
+# define KB (1024UL)
+# define MB (1024UL * KB)
+# define GB (1024UL * MB)
+
+/* copied from HotSpot function "atomll()" */
+static int
+parse_stack_size(const char *s, jlong *result) {
+ jlong n = 0;
+ int args_read = sscanf(s, jlong_format_specifier(), &n);
+ if (args_read != 1) {
+ return 0;
+ }
+ while (*s != '\0' && *s >= '0' && *s <= '9') {
+ s++;
+ }
+ // 4705540: illegal if more characters are found after the first non-digit
+ if (strlen(s) > 1) {
+ return 0;
+ }
+ switch (*s) {
+ case 'T': case 't':
+ *result = n * GB * KB;
+ return 1;
+ case 'G': case 'g':
+ *result = n * GB;
+ return 1;
+ case 'M': case 'm':
+ *result = n * MB;
+ return 1;
+ case 'K': case 'k':
+ *result = n * KB;
+ return 1;
+ case '\0':
+ *result = n;
+ return 1;
+ default:
+ /* Create JVM with default stack and let VM handle malformed -Xss string*/
+ return 0;
+ }
+}
+
+/*
+ * Adds a new VM option with the given given name and value.
+ */
+void
+AddOption(char *str, void *info)
+{
+ /*
+ * Expand options array if needed to accommodate at least one more
+ * VM option.
+ */
+ if (numOptions >= maxOptions) {
+ if (options == 0) {
+ maxOptions = 4;
+ options = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption));
+ } else {
+ JavaVMOption *tmp;
+ maxOptions *= 2;
+ tmp = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption));
+ memcpy(tmp, options, numOptions * sizeof(JavaVMOption));
+ JLI_MemFree(options);
+ options = tmp;
+ }
+ }
+ options[numOptions].optionString = str;
+ options[numOptions++].extraInfo = info;
+
+ if (strncmp(str, "-Xss", 4) == 0) {
+ jlong tmp;
+ if (parse_stack_size(str + 4, &tmp)) {
+ threadStackSize = tmp;
+ }
+ }
+}
+
+static void
+SetClassPath(const char *s)
+{
+ char *def;
+ s = JLI_WildcardExpandClasspath(s);
+ def = JLI_MemAlloc(strlen(s) + 40);
+ sprintf(def, "-Djava.class.path=%s", s);
+ AddOption(def, NULL);
+}
+
+/*
+ * The SelectVersion() routine ensures that an appropriate version of
+ * the JRE is running. The specification for the appropriate version
+ * is obtained from either the manifest of a jar file (preferred) or
+ * from command line options.
+ * The routine also parses splash screen command line options and
+ * passes on their values in private environment variables.
+ */
+static void
+SelectVersion(int argc, char **argv, char **main_class)
+{
+ char *arg;
+ char **new_argv;
+ char **new_argp;
+ char *operand;
+ char *version = NULL;
+ char *jre = NULL;
+ int jarflag = 0;
+ int headlessflag = 0;
+ int restrict_search = -1; /* -1 implies not known */
+ manifest_info info;
+ char env_entry[MAXNAMELEN + 24] = ENV_ENTRY "=";
+ char *splash_file_name = NULL;
+ char *splash_jar_name = NULL;
+ char *env_in;
+ int res;
+
+ /*
+ * If the version has already been selected, set *main_class
+ * with the value passed through the environment (if any) and
+ * simply return.
+ */
+ if ((env_in = getenv(ENV_ENTRY)) != NULL) {
+ if (*env_in != '\0')
+ *main_class = JLI_StringDup(env_in);
+ return;
+ }
+
+ /*
+ * Scan through the arguments for options relevant to multiple JRE
+ * support. For reference, the command line syntax is defined as:
+ *
+ * SYNOPSIS
+ * java [options] class [argument...]
+ *
+ * java [options] -jar file.jar [argument...]
+ *
+ * As the scan is performed, make a copy of the argument list with
+ * the version specification options (new to 1.5) removed, so that
+ * a version less than 1.5 can be exec'd.
+ *
+ * Note that due to the syntax of the native Windows interface
+ * CreateProcess(), processing similar to the following exists in
+ * the Windows platform specific routine ExecJRE (in java_md.c).
+ * Changes here should be reproduced there.
+ */
+ new_argv = JLI_MemAlloc((argc + 1) * sizeof(char*));
+ new_argv[0] = argv[0];
+ new_argp = &new_argv[1];
+ argc--;
+ argv++;
+ while ((arg = *argv) != 0 && *arg == '-') {
+ if (strncmp(arg, "-version:", 9) == 0) {
+ version = arg + 9;
+ } else if (strcmp(arg, "-jre-restrict-search") == 0) {
+ restrict_search = 1;
+ } else if (strcmp(arg, "-no-jre-restrict-search") == 0) {
+ restrict_search = 0;
+ } else {
+ if (strcmp(arg, "-jar") == 0)
+ jarflag = 1;
+ /* deal with "unfortunate" classpath syntax */
+ if ((strcmp(arg, "-classpath") == 0 || strcmp(arg, "-cp") == 0) &&
+ (argc >= 2)) {
+ *new_argp++ = arg;
+ argc--;
+ argv++;
+ arg = *argv;
+ }
+
+ /*
+ * Checking for headless toolkit option in the some way as AWT does:
+ * "true" means true and any other value means false
+ */
+ if (strcmp(arg, "-Djava.awt.headless=true") == 0) {
+ headlessflag = 1;
+ } else if (strncmp(arg, "-Djava.awt.headless=", 20) == 0) {
+ headlessflag = 0;
+ } else if (strncmp(arg, "-splash:", 8) == 0) {
+ splash_file_name = arg+8;
+ }
+ *new_argp++ = arg;
+ }
+ argc--;
+ argv++;
+ }
+ if (argc <= 0) { /* No operand? Possibly legit with -[full]version */
+ operand = NULL;
+ } else {
+ argc--;
+ *new_argp++ = operand = *argv++;
+ }
+ while (argc-- > 0) /* Copy over [argument...] */
+ *new_argp++ = *argv++;
+ *new_argp = NULL;
+
+ /*
+ * If there is a jar file, read the manifest. If the jarfile can't be
+ * read, the manifest can't be read from the jar file, or the manifest
+ * is corrupt, issue the appropriate error messages and exit.
+ *
+ * Even if there isn't a jar file, construct a manifest_info structure
+ * containing the command line information. It's a convenient way to carry
+ * this data around.
+ */
+ if (jarflag && operand) {
+ if ((res = JLI_ParseManifest(operand, &info)) != 0) {
+ if (res == -1)
+ ReportErrorMessage2("Unable to access jarfile %s",
+ operand, JNI_TRUE);
+ else
+ ReportErrorMessage2("Invalid or corrupt jarfile %s",
+ operand, JNI_TRUE);
+ exit(1);
+ }
+
+ /*
+ * Command line splash screen option should have precedence
+ * over the manifest, so the manifest data is used only if
+ * splash_file_name has not been initialized above during command
+ * line parsing
+ */
+ if (!headlessflag && !splash_file_name && info.splashscreen_image_file_name) {
+ splash_file_name = info.splashscreen_image_file_name;
+ splash_jar_name = operand;
+ }
+ } else {
+ info.manifest_version = NULL;
+ info.main_class = NULL;
+ info.jre_version = NULL;
+ info.jre_restrict_search = 0;
+ }
+
+ /*
+ * Passing on splash screen info in environment variables
+ */
+ if (splash_file_name && !headlessflag) {
+ char* splash_file_entry = JLI_MemAlloc(strlen(SPLASH_FILE_ENV_ENTRY "=")+strlen(splash_file_name)+1);
+ strcpy(splash_file_entry, SPLASH_FILE_ENV_ENTRY "=");
+ strcat(splash_file_entry, splash_file_name);
+ putenv(splash_file_entry);
+ }
+ if (splash_jar_name && !headlessflag) {
+ char* splash_jar_entry = JLI_MemAlloc(strlen(SPLASH_JAR_ENV_ENTRY "=")+strlen(splash_jar_name)+1);
+ strcpy(splash_jar_entry, SPLASH_JAR_ENV_ENTRY "=");
+ strcat(splash_jar_entry, splash_jar_name);
+ putenv(splash_jar_entry);
+ }
+
+ /*
+ * The JRE-Version and JRE-Restrict-Search values (if any) from the
+ * manifest are overwritten by any specified on the command line.
+ */
+ if (version != NULL)
+ info.jre_version = version;
+ if (restrict_search != -1)
+ info.jre_restrict_search = restrict_search;
+
+ /*
+ * "Valid" returns (other than unrecoverable errors) follow. Set
+ * main_class as a side-effect of this routine.
+ */
+ if (info.main_class != NULL)
+ *main_class = JLI_StringDup(info.main_class);
+
+ /*
+ * If no version selection information is found either on the command
+ * line or in the manifest, simply return.
+ */
+ if (info.jre_version == NULL) {
+ JLI_FreeManifest();
+ JLI_MemFree(new_argv);
+ return;
+ }
+
+ /*
+ * Check for correct syntax of the version specification (JSR 56).
+ */
+ if (!JLI_ValidVersionString(info.jre_version)) {
+ ReportErrorMessage2("Syntax error in version specification \"%s\"",
+ info.jre_version, JNI_TRUE);
+ exit(1);
+ }
+
+ /*
+ * Find the appropriate JVM on the system. Just to be as forgiving as
+ * possible, if the standard algorithms don't locate an appropriate
+ * jre, check to see if the one running will satisfy the requirements.
+ * This can happen on systems which haven't been set-up for multiple
+ * JRE support.
+ */
+ jre = LocateJRE(&info);
+ if (_launcher_debug)
+ printf("JRE-Version = %s, JRE-Restrict-Search = %s Selected = %s\n",
+ (info.jre_version?info.jre_version:"null"),
+ (info.jre_restrict_search?"true":"false"), (jre?jre:"null"));
+ if (jre == NULL) {
+ if (JLI_AcceptableRelease(FULL_VERSION, info.jre_version)) {
+ JLI_FreeManifest();
+ JLI_MemFree(new_argv);
+ return;
+ } else {
+ ReportErrorMessage2(
+ "Unable to locate JRE meeting specification \"%s\"",
+ info.jre_version, JNI_TRUE);
+ exit(1);
+ }
+ }
+
+ /*
+ * If I'm not the chosen one, exec the chosen one. Returning from
+ * ExecJRE indicates that I am indeed the chosen one.
+ *
+ * The private environment variable _JAVA_VERSION_SET is used to
+ * prevent the chosen one from re-reading the manifest file and
+ * using the values found within to override the (potential) command
+ * line flags stripped from argv (because the target may not
+ * understand them). Passing the MainClass value is an optimization
+ * to avoid locating, expanding and parsing the manifest extra
+ * times.
+ */
+ if (info.main_class != NULL) {
+ if (strlen(info.main_class) <= MAXNAMELEN) {
+ (void)strcat(env_entry, info.main_class);
+ } else {
+ ReportErrorMessage("Error: main-class: attribute exceeds system limits\n", JNI_TRUE);
+ exit(1);
+ }
+ }
+ (void)putenv(env_entry);
+ ExecJRE(jre, new_argv);
+ JLI_FreeManifest();
+ JLI_MemFree(new_argv);
+ return;
+}
+
+/*
+ * Parses command line arguments. Returns JNI_FALSE if launcher
+ * should exit without starting vm, returns JNI_TRUE if vm needs
+ * to be started to process given options. *pret (the launcher
+ * process return value) is set to 0 for a normal exit.
+ */
+static jboolean
+ParseArguments(int *pargc, char ***pargv, char **pjarfile,
+ char **pclassname, int *pret, const char *jvmpath)
+{
+ int argc = *pargc;
+ char **argv = *pargv;
+ jboolean jarflag = JNI_FALSE;
+ char *arg;
+
+ *pret = 0;
+
+ while ((arg = *argv) != 0 && *arg == '-') {
+ argv++; --argc;
+ if (strcmp(arg, "-classpath") == 0 || strcmp(arg, "-cp") == 0) {
+ if (argc < 1) {
+ ReportErrorMessage2("%s requires class path specification",
+ arg, JNI_TRUE);
+ printUsage = JNI_TRUE;
+ *pret = 1;
+ return JNI_TRUE;
+ }
+ SetClassPath(*argv);
+ argv++; --argc;
+ } else if (strcmp(arg, "-jar") == 0) {
+ jarflag = JNI_TRUE;
+ } else if (strcmp(arg, "-help") == 0 ||
+ strcmp(arg, "-h") == 0 ||
+ strcmp(arg, "-?") == 0) {
+ printUsage = JNI_TRUE;
+ return JNI_TRUE;
+ } else if (strcmp(arg, "-version") == 0) {
+ printVersion = JNI_TRUE;
+ return JNI_TRUE;
+ } else if (strcmp(arg, "-showversion") == 0) {
+ showVersion = JNI_TRUE;
+ } else if (strcmp(arg, "-X") == 0) {
+ printXUsage = JNI_TRUE;
+ return JNI_TRUE;
+/*
+ * The following case provide backward compatibility with old-style
+ * command line options.
+ */
+ } else if (strcmp(arg, "-fullversion") == 0) {
+ fprintf(stderr, "%s full version \"%s\"\n", launchername,
+ FULL_VERSION);
+ return JNI_FALSE;
+ } else if (strcmp(arg, "-verbosegc") == 0) {
+ AddOption("-verbose:gc", NULL);
+ } else if (strcmp(arg, "-t") == 0) {
+ AddOption("-Xt", NULL);
+ } else if (strcmp(arg, "-tm") == 0) {
+ AddOption("-Xtm", NULL);
+ } else if (strcmp(arg, "-debug") == 0) {
+ AddOption("-Xdebug", NULL);
+ } else if (strcmp(arg, "-noclassgc") == 0) {
+ AddOption("-Xnoclassgc", NULL);
+ } else if (strcmp(arg, "-Xfuture") == 0) {
+ AddOption("-Xverify:all", NULL);
+ } else if (strcmp(arg, "-verify") == 0) {
+ AddOption("-Xverify:all", NULL);
+ } else if (strcmp(arg, "-verifyremote") == 0) {
+ AddOption("-Xverify:remote", NULL);
+ } else if (strcmp(arg, "-noverify") == 0) {
+ AddOption("-Xverify:none", NULL);
+ } else if (strcmp(arg, "-XXsuppressExitMessage") == 0) {
+ noExitErrorMessage = 1;
+ } else if (strncmp(arg, "-prof", 5) == 0) {
+ char *p = arg + 5;
+ char *tmp = JLI_MemAlloc(strlen(arg) + 50);
+ if (*p) {
+ sprintf(tmp, "-Xrunhprof:cpu=old,file=%s", p + 1);
+ } else {
+ sprintf(tmp, "-Xrunhprof:cpu=old,file=java.prof");
+ }
+ AddOption(tmp, NULL);
+ } else if (strncmp(arg, "-ss", 3) == 0 ||
+ strncmp(arg, "-oss", 4) == 0 ||
+ strncmp(arg, "-ms", 3) == 0 ||
+ strncmp(arg, "-mx", 3) == 0) {
+ char *tmp = JLI_MemAlloc(strlen(arg) + 6);
+ sprintf(tmp, "-X%s", arg + 1); /* skip '-' */
+ AddOption(tmp, NULL);
+ } else if (strcmp(arg, "-checksource") == 0 ||
+ strcmp(arg, "-cs") == 0 ||
+ strcmp(arg, "-noasyncgc") == 0) {
+ /* No longer supported */
+ fprintf(stderr,
+ "Warning: %s option is no longer supported.\n",
+ arg);
+ } else if (strncmp(arg, "-version:", 9) == 0 ||
+ strcmp(arg, "-no-jre-restrict-search") == 0 ||
+ strcmp(arg, "-jre-restrict-search") == 0 ||
+ strncmp(arg, "-splash:", 8) == 0) {
+ ; /* Ignore machine independent options already handled */
+ } else if (RemovableMachineDependentOption(arg) ) {
+ ; /* Do not pass option to vm. */
+ }
+ else {
+ AddOption(arg, NULL);
+ }
+ }
+
+ if (--argc >= 0) {
+ if (jarflag) {
+ *pjarfile = *argv++;
+ *pclassname = 0;
+ } else {
+ *pjarfile = 0;
+ *pclassname = *argv++;
+ }
+ *pargc = argc;
+ *pargv = argv;
+ }
+
+ return JNI_TRUE;
+}
+
+/*
+ * Initializes the Java Virtual Machine. Also frees options array when
+ * finished.
+ */
+static jboolean
+InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn)
+{
+ JavaVMInitArgs args;
+ jint r;
+
+ memset(&args, 0, sizeof(args));
+ args.version = JNI_VERSION_1_2;
+ args.nOptions = numOptions;
+ args.options = options;
+ args.ignoreUnrecognized = JNI_FALSE;
+
+ if (_launcher_debug) {
+ int i = 0;
+ printf("JavaVM args:\n ");
+ printf("version 0x%08lx, ", (long)args.version);
+ printf("ignoreUnrecognized is %s, ",
+ args.ignoreUnrecognized ? "JNI_TRUE" : "JNI_FALSE");
+ printf("nOptions is %ld\n", (long)args.nOptions);
+ for (i = 0; i < numOptions; i++)
+ printf(" option[%2d] = '%s'\n",
+ i, args.options[i].optionString);
+ }
+
+ r = ifn->CreateJavaVM(pvm, (void **)penv, &args);
+ JLI_MemFree(options);
+ return r == JNI_OK;
+}
+
+#define JNI_ERROR "Error: A JNI error has occurred, please check your installation and try again"
+
+#define NULL_CHECK0(e) if ((e) == 0) { \
+ ReportErrorMessage(JNI_ERROR, JNI_TRUE); \
+ return 0; \
+ }
+
+#define NULL_CHECK(e) if ((e) == 0) { \
+ ReportErrorMessage(JNI_ERROR, JNI_TRUE); \
+ return; \
+ }
+
+static jstring platformEncoding = NULL;
+static jstring getPlatformEncoding(JNIEnv *env) {
+ if (platformEncoding == NULL) {
+ jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
+ if (propname) {
+ jclass cls;
+ jmethodID mid;
+ NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
+ NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
+ env, cls,
+ "getProperty",
+ "(Ljava/lang/String;)Ljava/lang/String;"));
+ platformEncoding = (*env)->CallStaticObjectMethod (
+ env, cls, mid, propname);
+ }
+ }
+ return platformEncoding;
+}
+
+static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
+ jclass cls;
+ jmethodID mid;
+ NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
+ NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
+ env, cls,
+ "isSupported",
+ "(Ljava/lang/String;)Z"));
+ return (*env)->CallStaticBooleanMethod(env, cls, mid, enc);
+}
+
+/*
+ * Returns a new Java string object for the specified platform string.
+ */
+static jstring
+NewPlatformString(JNIEnv *env, char *s)
+{
+ int len = (int)strlen(s);
+ jclass cls;
+ jmethodID mid;
+ jbyteArray ary;
+ jstring enc;
+
+ if (s == NULL)
+ return 0;
+ enc = getPlatformEncoding(env);
+
+ ary = (*env)->NewByteArray(env, len);
+ if (ary != 0) {
+ jstring str = 0;
+ (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
+ if (!(*env)->ExceptionOccurred(env)) {
+ if (isEncodingSupported(env, enc) == JNI_TRUE) {
+ NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
+ NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
+ "([BLjava/lang/String;)V"));
+ str = (*env)->NewObject(env, cls, mid, ary, enc);
+ } else {
+ /*If the encoding specified in sun.jnu.encoding is not
+ endorsed by "Charset.isSupported" we have to fall back
+ to use String(byte[]) explicitly here without specifying
+ the encoding name, in which the StringCoding class will
+ pickup the iso-8859-1 as the fallback converter for us.
+ */
+ NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
+ NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
+ "([B)V"));
+ str = (*env)->NewObject(env, cls, mid, ary);
+ }
+ (*env)->DeleteLocalRef(env, ary);
+ return str;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Returns a new array of Java string objects for the specified
+ * array of platform strings.
+ */
+static jobjectArray
+NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
+{
+ jarray cls;
+ jarray ary;
+ int i;
+
+ NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
+ NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
+ for (i = 0; i < strc; i++) {
+ jstring str = NewPlatformString(env, *strv++);
+ NULL_CHECK0(str);
+ (*env)->SetObjectArrayElement(env, ary, i, str);
+ (*env)->DeleteLocalRef(env, str);
+ }
+ return ary;
+}
+
+/*
+ * Loads a class, convert the '.' to '/'.
+ */
+static jclass
+LoadClass(JNIEnv *env, char *name)
+{
+ char *buf = JLI_MemAlloc(strlen(name) + 1);
+ char *s = buf, *t = name, c;
+ jclass cls;
+ jlong start, end;
+
+ if (_launcher_debug)
+ start = CounterGet();
+
+ do {
+ c = *t++;
+ *s++ = (c == '.') ? '/' : c;
+ } while (c != '\0');
+ cls = (*env)->FindClass(env, buf);
+ JLI_MemFree(buf);
+
+ if (_launcher_debug) {
+ end = CounterGet();
+ printf("%ld micro seconds to load main class\n",
+ (long)(jint)Counter2Micros(end-start));
+ printf("----_JAVA_LAUNCHER_DEBUG----\n");
+ }
+
+ return cls;
+}
+
+
+/*
+ * Returns the main class name for the specified jar file.
+ */
+static jstring
+GetMainClassName(JNIEnv *env, char *jarname)
+{
+#define MAIN_CLASS "Main-Class"
+ jclass cls;
+ jmethodID mid;
+ jobject jar, man, attr;
+ jstring str, result = 0;
+
+ NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
+ NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
+ "(Ljava/lang/String;)V"));
+ NULL_CHECK0(str = NewPlatformString(env, jarname));
+ NULL_CHECK0(jar = (*env)->NewObject(env, cls, mid, str));
+ NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "getManifest",
+ "()Ljava/util/jar/Manifest;"));
+ man = (*env)->CallObjectMethod(env, jar, mid);
+ if (man != 0) {
+ NULL_CHECK0(mid = (*env)->GetMethodID(env,
+ (*env)->GetObjectClass(env, man),
+ "getMainAttributes",
+ "()Ljava/util/jar/Attributes;"));
+ attr = (*env)->CallObjectMethod(env, man, mid);
+ if (attr != 0) {
+ NULL_CHECK0(mid = (*env)->GetMethodID(env,
+ (*env)->GetObjectClass(env, attr),
+ "getValue",
+ "(Ljava/lang/String;)Ljava/lang/String;"));
+ NULL_CHECK0(str = NewPlatformString(env, MAIN_CLASS));
+ result = (*env)->CallObjectMethod(env, attr, mid, str);
+ }
+ }
+ return result;
+}
+
+#ifdef JAVA_ARGS
+static char *java_args[] = JAVA_ARGS;
+static char *app_classpath[] = APP_CLASSPATH;
+
+/*
+ * For tools, convert command line args thus:
+ * javac -cp foo:foo/"*" -J-ms32m ...
+ * java -ms32m -cp JLI_WildcardExpandClasspath(foo:foo/"*") ...
+ */
+static void
+TranslateApplicationArgs(int *pargc, char ***pargv)
+{
+ const int NUM_ARGS = (sizeof(java_args) / sizeof(char *));
+ int argc = *pargc;
+ char **argv = *pargv;
+ int nargc = argc + NUM_ARGS;
+ char **nargv = JLI_MemAlloc((nargc + 1) * sizeof(char *));
+ int i;
+
+ *pargc = nargc;
+ *pargv = nargv;
+
+ /* Copy the VM arguments (i.e. prefixed with -J) */
+ for (i = 0; i < NUM_ARGS; i++) {
+ char *arg = java_args[i];
+ if (arg[0] == '-' && arg[1] == 'J') {
+ *nargv++ = arg + 2;
+ }
+ }
+
+ for (i = 0; i < argc; i++) {
+ char *arg = argv[i];
+ if (arg[0] == '-' && arg[1] == 'J') {
+ if (arg[2] == '\0') {
+ ReportErrorMessage("Error: the -J option should not be "
+ "followed by a space.", JNI_TRUE);
+ exit(1);
+ }
+ *nargv++ = arg + 2;
+ }
+ }
+
+ /* Copy the rest of the arguments */
+ for (i = 0; i < NUM_ARGS; i++) {
+ char *arg = java_args[i];
+ if (arg[0] != '-' || arg[1] != 'J') {
+ *nargv++ = arg;
+ }
+ }
+ for (i = 0; i < argc; i++) {
+ char *arg = argv[i];
+ if (arg[0] == '-') {
+ if (arg[1] == 'J')
+ continue;
+#ifdef EXPAND_CLASSPATH_WILDCARDS
+ if (arg[1] == 'c'
+ && (strcmp(arg, "-cp") == 0 ||
+ strcmp(arg, "-classpath") == 0)
+ && i < argc - 1) {
+ *nargv++ = arg;
+ *nargv++ = (char *) JLI_WildcardExpandClasspath(argv[i+1]);
+ i++;
+ continue;
+ }
+#endif
+ }
+ *nargv++ = arg;
+ }
+ *nargv = 0;
+}
+
+/*
+ * For our tools, we try to add 3 VM options:
+ * -Denv.class.path=<envcp>
+ * -Dapplication.home=<apphome>
+ * -Djava.class.path=<appcp>
+ * <envcp> is the user's setting of CLASSPATH -- for instance the user
+ * tells javac where to find binary classes through this environment
+ * variable. Notice that users will be able to compile against our
+ * tools classes (sun.tools.javac.Main) only if they explicitly add
+ * tools.jar to CLASSPATH.
+ * <apphome> is the directory where the application is installed.
+ * <appcp> is the classpath to where our apps' classfiles are.
+ */
+static jboolean
+AddApplicationOptions()
+{
+ const int NUM_APP_CLASSPATH = (sizeof(app_classpath) / sizeof(char *));
+ char *envcp, *appcp, *apphome;
+ char home[MAXPATHLEN]; /* application home */
+ char separator[] = { PATH_SEPARATOR, '\0' };
+ int size, i;
+ int strlenHome;
+
+ {
+ const char *s = getenv("CLASSPATH");
+ if (s) {
+ s = (char *) JLI_WildcardExpandClasspath(s);
+ /* 40 for -Denv.class.path= */
+ envcp = (char *)JLI_MemAlloc(strlen(s) + 40);
+ sprintf(envcp, "-Denv.class.path=%s", s);
+ AddOption(envcp, NULL);
+ }
+ }
+
+ if (!GetApplicationHome(home, sizeof(home))) {
+ ReportErrorMessage("Can't determine application home", JNI_TRUE);
+ return JNI_FALSE;
+ }
+
+ /* 40 for '-Dapplication.home=' */
+ apphome = (char *)JLI_MemAlloc(strlen(home) + 40);
+ sprintf(apphome, "-Dapplication.home=%s", home);
+ AddOption(apphome, NULL);
+
+ /* How big is the application's classpath? */
+ size = 40; /* 40: "-Djava.class.path=" */
+ strlenHome = (int)strlen(home);
+ for (i = 0; i < NUM_APP_CLASSPATH; i++) {
+ size += strlenHome + (int)strlen(app_classpath[i]) + 1; /* 1: separator */
+ }
+ appcp = (char *)JLI_MemAlloc(size + 1);
+ strcpy(appcp, "-Djava.class.path=");
+ for (i = 0; i < NUM_APP_CLASSPATH; i++) {
+ strcat(appcp, home); /* c:\program files\myapp */
+ strcat(appcp, app_classpath[i]); /* \lib\myapp.jar */
+ strcat(appcp, separator); /* ; */
+ }
+ appcp[strlen(appcp)-1] = '\0'; /* remove trailing path separator */
+ AddOption(appcp, NULL);
+ return JNI_TRUE;
+}
+#endif /* JAVA_ARGS */
+
+/*
+ * inject the -Dsun.java.command pseudo property into the args structure
+ * this pseudo property is used in the HotSpot VM to expose the
+ * Java class name and arguments to the main method to the VM. The
+ * HotSpot VM uses this pseudo property to store the Java class name
+ * (or jar file name) and the arguments to the class's main method
+ * to the instrumentation memory region. The sun.java.command pseudo
+ * property is not exported by HotSpot to the Java layer.
+ */
+void
+SetJavaCommandLineProp(char *classname, char *jarfile,
+ int argc, char **argv)
+{
+
+ int i = 0;
+ size_t len = 0;
+ char* javaCommand = NULL;
+ char* dashDstr = "-Dsun.java.command=";
+
+ if (classname == NULL && jarfile == NULL) {
+ /* unexpected, one of these should be set. just return without
+ * setting the property
+ */
+ return;
+ }
+
+ /* if the class name is not set, then use the jarfile name */
+ if (classname == NULL) {
+ classname = jarfile;
+ }
+
+ /* determine the amount of memory to allocate assuming
+ * the individual components will be space separated
+ */
+ len = strlen(classname);
+ for (i = 0; i < argc; i++) {
+ len += strlen(argv[i]) + 1;
+ }
+
+ /* allocate the memory */
+ javaCommand = (char*) JLI_MemAlloc(len + strlen(dashDstr) + 1);
+
+ /* build the -D string */
+ *javaCommand = '\0';
+ strcat(javaCommand, dashDstr);
+ strcat(javaCommand, classname);
+
+ for (i = 0; i < argc; i++) {
+ /* the components of the string are space separated. In
+ * the case of embedded white space, the relationship of
+ * the white space separated components to their true
+ * positional arguments will be ambiguous. This issue may
+ * be addressed in a future release.
+ */
+ strcat(javaCommand, " ");
+ strcat(javaCommand, argv[i]);
+ }
+
+ AddOption(javaCommand, NULL);
+}
+
+/*
+ * JVM would like to know if it's created by a standard Sun launcher, or by
+ * user native application, the following property indicates the former.
+ */
+void SetJavaLauncherProp() {
+ AddOption("-Dsun.java.launcher=SUN_STANDARD", NULL);
+}
+
+/*
+ * Prints the version information from the java.version and other properties.
+ */
+static void
+PrintJavaVersion(JNIEnv *env)
+{
+ jclass ver;
+ jmethodID print;
+
+ NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
+ NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
+
+ (*env)->CallStaticVoidMethod(env, ver, print);
+}
+
+/*
+ * Prints default usage or the Xusage message, see sun.launcher.LauncherHelp.java
+ */
+static void
+PrintUsage(JNIEnv* env, jboolean doXUsage)
+{
+ jclass cls;
+ jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage;
+ jstring jprogname, vm1, vm2;
+ int i;
+
+ NULL_CHECK(cls = (*env)->FindClass(env, "sun/launcher/LauncherHelp"));
+
+
+ if (doXUsage) {
+ NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls,
+ "printXUsageMessage", "(Z)V"));
+ (*env)->CallStaticVoidMethod(env, cls, printXUsageMessage, JNI_TRUE);
+ } else {
+ NULL_CHECK(initHelp = (*env)->GetStaticMethodID(env, cls,
+ "initHelpMessage", "(Ljava/lang/String;)V"));
+
+ NULL_CHECK(vmSelect = (*env)->GetStaticMethodID(env, cls, "appendVmSelectMessage",
+ "(Ljava/lang/String;Ljava/lang/String;)V"));
+
+ NULL_CHECK(vmSynonym = (*env)->GetStaticMethodID(env, cls,
+ "appendVmSynonymMessage",
+ "(Ljava/lang/String;Ljava/lang/String;)V"));
+ NULL_CHECK(vmErgo = (*env)->GetStaticMethodID(env, cls,
+ "appendVmErgoMessage", "(ZLjava/lang/String;)V"));
+
+ NULL_CHECK(printHelp = (*env)->GetStaticMethodID(env, cls,
+ "printHelpMessage", "(Z)V"));
+
+ jprogname = (*env)->NewStringUTF(env, progname);
+
+ /* Initialize the usage message with the usual preamble */
+ (*env)->CallStaticVoidMethod(env, cls, initHelp, jprogname);
+
+
+ /* Assemble the other variant part of the usage */
+ if ((knownVMs[0].flag == VM_KNOWN) ||
+ (knownVMs[0].flag == VM_IF_SERVER_CLASS)) {
+ vm1 = (*env)->NewStringUTF(env, knownVMs[0].name);
+ vm2 = (*env)->NewStringUTF(env, knownVMs[0].name+1);
+ (*env)->CallStaticVoidMethod(env, cls, vmSelect, vm1, vm2);
+ }
+ for (i=1; i<knownVMsCount; i++) {
+ if (knownVMs[i].flag == VM_KNOWN) {
+ vm1 = (*env)->NewStringUTF(env, knownVMs[i].name);
+ vm2 = (*env)->NewStringUTF(env, knownVMs[i].name+1);
+ (*env)->CallStaticVoidMethod(env, cls, vmSelect, vm1, vm2);
+ }
+ }
+ for (i=1; i<knownVMsCount; i++) {
+ if (knownVMs[i].flag == VM_ALIASED_TO) {
+ vm1 = (*env)->NewStringUTF(env, knownVMs[i].name);
+ vm2 = (*env)->NewStringUTF(env, knownVMs[i].alias+1);
+ (*env)->CallStaticVoidMethod(env, cls, vmSynonym, vm1, vm2);
+ }
+ }
+
+ /* The first known VM is the default */
+ {
+ jboolean isServerClassMachine = ServerClassMachine();
+
+ const char* defaultVM = knownVMs[0].name+1;
+ if ((knownVMs[0].flag == VM_IF_SERVER_CLASS) && isServerClassMachine) {
+ defaultVM = knownVMs[0].server_class+1;
+ }
+
+ vm1 = (*env)->NewStringUTF(env, defaultVM);
+ (*env)->CallStaticVoidMethod(env, cls, vmErgo, isServerClassMachine, vm1);
+ }
+
+ /* Complete the usage message and print to stderr*/
+ (*env)->CallStaticVoidMethod(env, cls, printHelp, JNI_TRUE);
+ }
+ return;
+}
+
+/*
+ * Read the jvm.cfg file and fill the knownJVMs[] array.
+ *
+ * The functionality of the jvm.cfg file is subject to change without
+ * notice and the mechanism will be removed in the future.
+ *
+ * The lexical structure of the jvm.cfg file is as follows:
+ *
+ * jvmcfg := { vmLine }
+ * vmLine := knownLine
+ * | aliasLine
+ * | warnLine
+ * | ignoreLine
+ * | errorLine
+ * | predicateLine
+ * | commentLine
+ * knownLine := flag "KNOWN" EOL
+ * warnLine := flag "WARN" EOL
+ * ignoreLine := flag "IGNORE" EOL
+ * errorLine := flag "ERROR" EOL
+ * aliasLine := flag "ALIASED_TO" flag EOL
+ * predicateLine := flag "IF_SERVER_CLASS" flag EOL
+ * commentLine := "#" text EOL
+ * flag := "-" identifier
+ *
+ * The semantics are that when someone specifies a flag on the command line:
+ * - if the flag appears on a knownLine, then the identifier is used as
+ * the name of the directory holding the JVM library (the name of the JVM).
+ * - if the flag appears as the first flag on an aliasLine, the identifier
+ * of the second flag is used as the name of the JVM.
+ * - if the flag appears on a warnLine, the identifier is used as the
+ * name of the JVM, but a warning is generated.
+ * - if the flag appears on an ignoreLine, the identifier is recognized as the
+ * name of a JVM, but the identifier is ignored and the default vm used
+ * - if the flag appears on an errorLine, an error is generated.
+ * - if the flag appears as the first flag on a predicateLine, and
+ * the machine on which you are running passes the predicate indicated,
+ * then the identifier of the second flag is used as the name of the JVM,
+ * otherwise the identifier of the first flag is used as the name of the JVM.
+ * If no flag is given on the command line, the first vmLine of the jvm.cfg
+ * file determines the name of the JVM.
+ * PredicateLines are only interpreted on first vmLine of a jvm.cfg file,
+ * since they only make sense if someone hasn't specified the name of the
+ * JVM on the command line.
+ *
+ * The intent of the jvm.cfg file is to allow several JVM libraries to
+ * be installed in different subdirectories of a single JRE installation,
+ * for space-savings and convenience in testing.
+ * The intent is explicitly not to provide a full aliasing or predicate
+ * mechanism.
+ */
+jint
+ReadKnownVMs(const char *jrepath, char * arch, jboolean speculative)
+{
+ FILE *jvmCfg;
+ char jvmCfgName[MAXPATHLEN+20];
+ char line[MAXPATHLEN+20];
+ int cnt = 0;
+ int lineno = 0;
+ jlong start, end;
+ int vmType;
+ char *tmpPtr;
+ char *altVMName = NULL;
+ char *serverClassVMName = NULL;
+ static char *whiteSpace = " \t";
+ if (_launcher_debug) {
+ start = CounterGet();
+ }
+
+ strcpy(jvmCfgName, jrepath);
+ strcat(jvmCfgName, FILESEP "lib" FILESEP);
+ strcat(jvmCfgName, arch);
+ strcat(jvmCfgName, FILESEP "jvm.cfg");
+
+ jvmCfg = fopen(jvmCfgName, "r");
+ if (jvmCfg == NULL) {
+ if (!speculative) {
+ ReportErrorMessage2("Error: could not open `%s'", jvmCfgName,
+ JNI_TRUE);
+ exit(1);
+ } else {
+ return -1;
+ }
+ }
+ while (fgets(line, sizeof(line), jvmCfg) != NULL) {
+ vmType = VM_UNKNOWN;
+ lineno++;
+ if (line[0] == '#')
+ continue;
+ if (line[0] != '-') {
+ fprintf(stderr, "Warning: no leading - on line %d of `%s'\n",
+ lineno, jvmCfgName);
+ }
+ if (cnt >= knownVMsLimit) {
+ GrowKnownVMs(cnt);
+ }
+ line[strlen(line)-1] = '\0'; /* remove trailing newline */
+ tmpPtr = line + strcspn(line, whiteSpace);
+ if (*tmpPtr == 0) {
+ fprintf(stderr, "Warning: missing VM type on line %d of `%s'\n",
+ lineno, jvmCfgName);
+ } else {
+ /* Null-terminate this string for JLI_StringDup below */
+ *tmpPtr++ = 0;
+ tmpPtr += strspn(tmpPtr, whiteSpace);
+ if (*tmpPtr == 0) {
+ fprintf(stderr, "Warning: missing VM type on line %d of `%s'\n",
+ lineno, jvmCfgName);
+ } else {
+ if (!strncmp(tmpPtr, "KNOWN", strlen("KNOWN"))) {
+ vmType = VM_KNOWN;
+ } else if (!strncmp(tmpPtr, "ALIASED_TO", strlen("ALIASED_TO"))) {
+ tmpPtr += strcspn(tmpPtr, whiteSpace);
+ if (*tmpPtr != 0) {
+ tmpPtr += strspn(tmpPtr, whiteSpace);
+ }
+ if (*tmpPtr == 0) {
+ fprintf(stderr, "Warning: missing VM alias on line %d of `%s'\n",
+ lineno, jvmCfgName);
+ } else {
+ /* Null terminate altVMName */
+ altVMName = tmpPtr;
+ tmpPtr += strcspn(tmpPtr, whiteSpace);
+ *tmpPtr = 0;
+ vmType = VM_ALIASED_TO;
+ }
+ } else if (!strncmp(tmpPtr, "WARN", strlen("WARN"))) {
+ vmType = VM_WARN;
+ } else if (!strncmp(tmpPtr, "IGNORE", strlen("IGNORE"))) {
+ vmType = VM_IGNORE;
+ } else if (!strncmp(tmpPtr, "ERROR", strlen("ERROR"))) {
+ vmType = VM_ERROR;
+ } else if (!strncmp(tmpPtr,
+ "IF_SERVER_CLASS",
+ strlen("IF_SERVER_CLASS"))) {
+ tmpPtr += strcspn(tmpPtr, whiteSpace);
+ if (*tmpPtr != 0) {
+ tmpPtr += strspn(tmpPtr, whiteSpace);
+ }
+ if (*tmpPtr == 0) {
+ fprintf(stderr, "Warning: missing server class VM on line %d of `%s'\n",
+ lineno, jvmCfgName);
+ } else {
+ /* Null terminate server class VM name */
+ serverClassVMName = tmpPtr;
+ tmpPtr += strcspn(tmpPtr, whiteSpace);
+ *tmpPtr = 0;
+ vmType = VM_IF_SERVER_CLASS;
+ }
+ } else {
+ fprintf(stderr, "Warning: unknown VM type on line %d of `%s'\n",
+ lineno, &jvmCfgName[0]);
+ vmType = VM_KNOWN;
+ }
+ }
+ }
+
+ if (_launcher_debug)
+ printf("jvm.cfg[%d] = ->%s<-\n", cnt, line);
+ if (vmType != VM_UNKNOWN) {
+ knownVMs[cnt].name = JLI_StringDup(line);
+ knownVMs[cnt].flag = vmType;
+ switch (vmType) {
+ default:
+ break;
+ case VM_ALIASED_TO:
+ knownVMs[cnt].alias = JLI_StringDup(altVMName);
+ if (_launcher_debug) {
+ printf(" name: %s vmType: %s alias: %s\n",
+ knownVMs[cnt].name, "VM_ALIASED_TO", knownVMs[cnt].alias);
+ }
+ break;
+ case VM_IF_SERVER_CLASS:
+ knownVMs[cnt].server_class = JLI_StringDup(serverClassVMName);
+ if (_launcher_debug) {
+ printf(" name: %s vmType: %s server_class: %s\n",
+ knownVMs[cnt].name, "VM_IF_SERVER_CLASS", knownVMs[cnt].server_class);
+ }
+ break;
+ }
+ cnt++;
+ }
+ }
+ fclose(jvmCfg);
+ knownVMsCount = cnt;
+
+ if (_launcher_debug) {
+ end = CounterGet();
+ printf("%ld micro seconds to parse jvm.cfg\n",
+ (long)(jint)Counter2Micros(end-start));
+ }
+
+ return cnt;
+}
+
+
+static void
+GrowKnownVMs(int minimum)
+{
+ struct vmdesc* newKnownVMs;
+ int newMax;
+
+ newMax = (knownVMsLimit == 0 ? INIT_MAX_KNOWN_VMS : (2 * knownVMsLimit));
+ if (newMax <= minimum) {
+ newMax = minimum;
+ }
+ newKnownVMs = (struct vmdesc*) JLI_MemAlloc(newMax * sizeof(struct vmdesc));
+ if (knownVMs != NULL) {
+ memcpy(newKnownVMs, knownVMs, knownVMsLimit * sizeof(struct vmdesc));
+ }
+ JLI_MemFree(knownVMs);
+ knownVMs = newKnownVMs;
+ knownVMsLimit = newMax;
+}
+
+
+/* Returns index of VM or -1 if not found */
+static int
+KnownVMIndex(const char* name)
+{
+ int i;
+ if (strncmp(name, "-J", 2) == 0) name += 2;
+ for (i = 0; i < knownVMsCount; i++) {
+ if (!strcmp(name, knownVMs[i].name)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static void
+FreeKnownVMs()
+{
+ int i;
+ for (i = 0; i < knownVMsCount; i++) {
+ JLI_MemFree(knownVMs[i].name);
+ knownVMs[i].name = NULL;
+ }
+ JLI_MemFree(knownVMs);
+}
+
+
+/*
+ * Displays the splash screen according to the jar file name
+ * and image file names stored in environment variables
+ */
+static void
+ShowSplashScreen()
+{
+ const char *jar_name = getenv(SPLASH_JAR_ENV_ENTRY);
+ const char *file_name = getenv(SPLASH_FILE_ENV_ENTRY);
+ int data_size;
+ void *image_data;
+ if (jar_name) {
+ image_data = JLI_JarUnpackFile(jar_name, file_name, &data_size);
+ if (image_data) {
+ DoSplashInit();
+ DoSplashLoadMemory(image_data, data_size);
+ JLI_MemFree(image_data);
+ }
+ } else if (file_name) {
+ DoSplashInit();
+ DoSplashLoadFile(file_name);
+ } else {
+ return;
+ }
+ DoSplashSetFileJarName(file_name, jar_name);
+}
diff --git a/launcher/java.h b/launcher/java.h
new file mode 100644
index 0000000..49e62f7
--- /dev/null
+++ b/launcher/java.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JAVA_H_
+#define _JAVA_H_
+
+/*
+ * Get system specific defines.
+ */
+#include "jni.h"
+#include "java_md.h"
+#include "jli_util.h"
+
+#include <limits.h>
+
+#define CURRENT_DATA_MODEL (CHAR_BIT * sizeof(void*))
+
+/*
+ * Pointers to the needed JNI invocation API, initialized by LoadJavaVM.
+ */
+typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);
+typedef jint (JNICALL *GetDefaultJavaVMInitArgs_t)(void *args);
+
+typedef struct {
+ CreateJavaVM_t CreateJavaVM;
+ GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs;
+} InvocationFunctions;
+
+/*
+ * Prototypes for launcher functions in the system specific java_md.c.
+ */
+
+jboolean
+LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn);
+
+void
+GetXUsagePath(char *buf, jint bufsize);
+
+jboolean
+GetApplicationHome(char *buf, jint bufsize);
+
+const char *
+GetArch();
+
+void CreateExecutionEnvironment(int *_argc,
+ char ***_argv,
+ char jrepath[],
+ jint so_jrepath,
+ char jvmpath[],
+ jint so_jvmpath,
+ char **original_argv);
+
+/*
+ * Report an error message to stderr or a window as appropriate. The
+ * flag always is set to JNI_TRUE if message is to be reported to both
+ * strerr and windows and set to JNI_FALSE if the message should only
+ * be sent to a window.
+ */
+void ReportErrorMessage(char * message, jboolean always);
+void ReportErrorMessage2(char * format, char * string, jboolean always);
+
+/*
+ * Report an exception which terminates the vm to stderr or a window
+ * as appropriate.
+ */
+void ReportExceptionDescription(JNIEnv * env);
+
+jboolean RemovableMachineDependentOption(char * option);
+void PrintMachineDependentOptions();
+
+const char *jlong_format_specifier();
+/*
+ * Block current thread and continue execution in new thread
+ */
+int ContinueInNewThread(int (JNICALL *continuation)(void *),
+ jlong stack_size, void * args, int ret);
+
+/* sun.java.launcher.* platform properties. */
+void SetJavaLauncherPlatformProps(void);
+
+/*
+ * Functions defined in java.c and used in java_md.c.
+ */
+jint ReadKnownVMs(const char *jrepath, char * arch, jboolean speculative);
+char *CheckJvmType(int *argc, char ***argv, jboolean speculative);
+void AddOption(char *str, void *info);
+
+/*
+ * Make launcher spit debug output.
+ */
+extern jboolean _launcher_debug;
+
+#endif /* _JAVA_H_ */
diff --git a/launcher/java_md.c b/launcher/java_md.c
new file mode 100644
index 0000000..e3e5e6f
--- /dev/null
+++ b/launcher/java_md.c
@@ -0,0 +1,1786 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "java.h"
+#include <dirent.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "manifest_info.h"
+#include "version_comp.h"
+
+#ifdef __linux__
+#include <pthread.h>
+#else
+#include <thread.h>
+#endif
+
+#define JVM_DLL "libjvm.so"
+#define JAVA_DLL "libjava.so"
+
+/*
+ * If a processor / os combination has the ability to run binaries of
+ * two data models and cohabitation of jre/jdk bits with both data
+ * models is supported, then DUAL_MODE is defined. When DUAL_MODE is
+ * defined, the architecture names for the narrow and wide version of
+ * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME. Currently
+ * only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE; linux
+ * i586/amd64 could be defined as DUAL_MODE but that is not the
+ * current policy.
+ */
+
+#ifndef LIBARCHNAME
+# error "The macro LIBARCHNAME was not defined on the compile line"
+#endif
+
+#ifdef __sun
+# define DUAL_MODE
+# ifndef LIBARCH32NAME
+# error "The macro LIBARCH32NAME was not defined on the compile line"
+# endif
+# ifndef LIBARCH64NAME
+# error "The macro LIBARCH64NAME was not defined on the compile line"
+# endif
+# include <sys/systeminfo.h>
+# include <sys/elf.h>
+# include <stdio.h>
+#endif
+
+/* pointer to environment */
+extern char **environ;
+
+/*
+ * A collection of useful strings. One should think of these as #define
+ * entries, but actual strings can be more efficient (with many compilers).
+ */
+#ifdef __linux__
+static const char *system_dir = "/usr/java";
+static const char *user_dir = "/java";
+#else /* Solaris */
+static const char *system_dir = "/usr/jdk";
+static const char *user_dir = "/jdk";
+#endif
+
+/*
+ * Flowchart of launcher execs and options processing on unix
+ *
+ * The selection of the proper vm shared library to open depends on
+ * several classes of command line options, including vm "flavor"
+ * options (-client, -server) and the data model options, -d32 and
+ * -d64, as well as a version specification which may have come from
+ * the command line or from the manifest of an executable jar file.
+ * The vm selection options are not passed to the running
+ * virtual machine; they must be screened out by the launcher.
+ *
+ * The version specification (if any) is processed first by the
+ * platform independent routine SelectVersion. This may result in
+ * the exec of the specified launcher version.
+ *
+ * Typically, the launcher execs at least once to ensure a suitable
+ * LD_LIBRARY_PATH is in effect for the process. The first exec
+ * screens out all the data model options; leaving the choice of data
+ * model implicit in the binary selected to run. However, in case no
+ * exec is done, the data model options are screened out before the vm
+ * is invoked.
+ *
+ * incoming argv ------------------------------
+ * | |
+ * \|/ |
+ * CheckJVMType |
+ * (removes -client, -server, etc.) |
+ * \|/
+ * CreateExecutionEnvironment
+ * (removes -d32 and -d64,
+ * determines desired data model,
+ * sets up LD_LIBRARY_PATH,
+ * and exec's)
+ * |
+ * --------------------------------------------
+ * |
+ * \|/
+ * exec child 1 incoming argv -----------------
+ * | |
+ * \|/ |
+ * CheckJVMType |
+ * (removes -client, -server, etc.) |
+ * | \|/
+ * | CreateExecutionEnvironment
+ * | (verifies desired data model
+ * | is running and acceptable
+ * | LD_LIBRARY_PATH;
+ * | no-op in child)
+ * |
+ * \|/
+ * TranslateDashJArgs...
+ * (Prepare to pass args to vm)
+ * |
+ * |
+ * |
+ * \|/
+ * ParseArguments
+ * (ignores -d32 and -d64,
+ * processes version options,
+ * creates argument list for vm,
+ * etc.)
+ *
+ */
+
+static char *SetExecname(char **argv);
+static char * GetExecname();
+static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
+ char *jvmpath, jint jvmpathsize, char * arch);
+static jboolean GetJREPath(char *path, jint pathsize, char * arch, jboolean speculative);
+
+const char *
+GetArch()
+{
+ return LIBARCHNAME;
+}
+
+void
+CreateExecutionEnvironment(int *_argcp,
+ char ***_argvp,
+ char jrepath[],
+ jint so_jrepath,
+ char jvmpath[],
+ jint so_jvmpath,
+ char **original_argv) {
+ /*
+ * First, determine if we are running the desired data model. If we
+ * are running the desired data model, all the error messages
+ * associated with calling GetJREPath, ReadKnownVMs, etc. should be
+ * output. However, if we are not running the desired data model,
+ * some of the errors should be suppressed since it is more
+ * informative to issue an error message based on whether or not the
+ * os/processor combination has dual mode capabilities.
+ */
+
+ char *execname = NULL;
+ int original_argc = *_argcp;
+ jboolean jvmpathExists;
+
+ /* Compute the name of the executable */
+ execname = SetExecname(*_argvp);
+
+ /* Set the LD_LIBRARY_PATH environment variable, check data model
+ flags, and exec process, if needed */
+ {
+ char *arch = (char *)GetArch(); /* like sparc or sparcv9 */
+ char * jvmtype = NULL;
+ int argc = *_argcp;
+ char **argv = original_argv;
+
+ char *runpath = NULL; /* existing effective LD_LIBRARY_PATH
+ setting */
+
+ int running = CURRENT_DATA_MODEL;
+
+ int wanted = running; /* What data mode is being
+ asked for? Current model is
+ fine unless another model
+ is asked for */
+
+ char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
+ char* newpath = NULL; /* path on new LD_LIBRARY_PATH */
+ char* lastslash = NULL;
+
+ char** newenvp = NULL; /* current environment */
+
+ char** newargv = NULL;
+ int newargc = 0;
+#ifdef __sun
+ char* dmpath = NULL; /* data model specific LD_LIBRARY_PATH,
+ Solaris only */
+#endif
+
+ /*
+ * Starting in 1.5, all unix platforms accept the -d32 and -d64
+ * options. On platforms where only one data-model is supported
+ * (e.g. ia-64 Linux), using the flag for the other data model is
+ * an error and will terminate the program.
+ */
+
+ { /* open new scope to declare local variables */
+ int i;
+
+ newargv = (char **)JLI_MemAlloc((argc+1) * sizeof(*newargv));
+ newargv[newargc++] = argv[0];
+
+ /* scan for data model arguments and remove from argument list;
+ last occurrence determines desired data model */
+ for (i=1; i < argc; i++) {
+
+ if (strcmp(argv[i], "-J-d64") == 0 || strcmp(argv[i], "-d64") == 0) {
+ wanted = 64;
+ continue;
+ }
+ if (strcmp(argv[i], "-J-d32") == 0 || strcmp(argv[i], "-d32") == 0) {
+ wanted = 32;
+ continue;
+ }
+ newargv[newargc++] = argv[i];
+
+#ifdef JAVA_ARGS
+ if (argv[i][0] != '-')
+ continue;
+#else
+ if (strcmp(argv[i], "-classpath") == 0 || strcmp(argv[i], "-cp") == 0) {
+ i++;
+ if (i >= argc) break;
+ newargv[newargc++] = argv[i];
+ continue;
+ }
+ if (argv[i][0] != '-') { i++; break; }
+#endif
+ }
+
+ /* copy rest of args [i .. argc) */
+ while (i < argc) {
+ newargv[newargc++] = argv[i++];
+ }
+ newargv[newargc] = NULL;
+
+ /*
+ * newargv has all proper arguments here
+ */
+
+ argc = newargc;
+ argv = newargv;
+ }
+
+ /* If the data model is not changing, it is an error if the
+ jvmpath does not exist */
+ if (wanted == running) {
+ /* Find out where the JRE is that we will be using. */
+ if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
+ fprintf(stderr, "Error: could not find Java 2 Runtime Environment.\n");
+ exit(2);
+ }
+
+ /* Find the specified JVM type */
+ if (ReadKnownVMs(jrepath, arch, JNI_FALSE) < 1) {
+ fprintf(stderr, "Error: no known VMs. (check for corrupt jvm.cfg file)\n");
+ exit(1);
+ }
+
+ jvmpath[0] = '\0';
+ jvmtype = CheckJvmType(_argcp, _argvp, JNI_FALSE);
+
+ if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch )) {
+ fprintf(stderr, "Error: no `%s' JVM at `%s'.\n", jvmtype, jvmpath);
+ exit(4);
+ }
+ } else { /* do the same speculatively or exit */
+#ifdef DUAL_MODE
+ if (running != wanted) {
+ /* Find out where the JRE is that we will be using. */
+ if (!GetJREPath(jrepath, so_jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME), JNI_TRUE)) {
+ goto EndDataModelSpeculate;
+ }
+
+ /*
+ * Read in jvm.cfg for target data model and process vm
+ * selection options.
+ */
+ if (ReadKnownVMs(jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME), JNI_TRUE) < 1) {
+ goto EndDataModelSpeculate;
+ }
+ jvmpath[0] = '\0';
+ jvmtype = CheckJvmType(_argcp, _argvp, JNI_TRUE);
+ /* exec child can do error checking on the existence of the path */
+ jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath,
+ ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME));
+
+ }
+ EndDataModelSpeculate: /* give up and let other code report error message */
+ ;
+#else
+ fprintf(stderr, "This Java instance does not support a %d-bit JVM.\nPlease install the desired version.\n", wanted);
+ exit(1);
+#endif
+ }
+
+ /*
+ * We will set the LD_LIBRARY_PATH as follows:
+ *
+ * o $JVMPATH (directory portion only)
+ * o $JRE/lib/$LIBARCHNAME
+ * o $JRE/../lib/$LIBARCHNAME
+ *
+ * followed by the user's previous effective LD_LIBRARY_PATH, if
+ * any.
+ */
+
+#ifdef __sun
+ /*
+ * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
+ * variables:
+ *
+ * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
+ * data-model specific variables are not set.
+ *
+ * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
+ * for 64-bit binaries.
+ *
+ * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
+ * for 32-bit binaries.
+ *
+ * The vm uses LD_LIBRARY_PATH to set the java.library.path system
+ * property. To shield the vm from the complication of multiple
+ * LD_LIBRARY_PATH variables, if the appropriate data model
+ * specific variable is set, we will act as if LD_LIBRARY_PATH had
+ * the value of the data model specific variant and the data model
+ * specific variant will be unset. Note that the variable for the
+ * *wanted* data model must be used (if it is set), not simply the
+ * current running data model.
+ */
+
+ switch(wanted) {
+ case 0:
+ if(running == 32) {
+ dmpath = getenv("LD_LIBRARY_PATH_32");
+ wanted = 32;
+ }
+ else {
+ dmpath = getenv("LD_LIBRARY_PATH_64");
+ wanted = 64;
+ }
+ break;
+
+ case 32:
+ dmpath = getenv("LD_LIBRARY_PATH_32");
+ break;
+
+ case 64:
+ dmpath = getenv("LD_LIBRARY_PATH_64");
+ break;
+
+ default:
+ fprintf(stderr, "Improper value at line %d.", __LINE__);
+ exit(1); /* unknown value in wanted */
+ break;
+ }
+
+ /*
+ * If dmpath is NULL, the relevant data model specific variable is
+ * not set and normal LD_LIBRARY_PATH should be used.
+ */
+ if( dmpath == NULL) {
+ runpath = getenv("LD_LIBRARY_PATH");
+ }
+ else {
+ runpath = dmpath;
+ }
+#else
+ /*
+ * If not on Solaris, assume only a single LD_LIBRARY_PATH
+ * variable.
+ */
+ runpath = getenv("LD_LIBRARY_PATH");
+#endif /* __sun */
+
+#ifdef __linux
+ /*
+ * On linux, if a binary is running as sgid or suid, glibc sets
+ * LD_LIBRARY_PATH to the empty string for security purposes. (In
+ * contrast, on Solaris the LD_LIBRARY_PATH variable for a
+ * privileged binary does not lose its settings; but the dynamic
+ * linker does apply more scrutiny to the path.) The launcher uses
+ * the value of LD_LIBRARY_PATH to prevent an exec loop.
+ * Therefore, if we are running sgid or suid, this function's
+ * setting of LD_LIBRARY_PATH will be ineffective and we should
+ * return from the function now. Getting the right libraries to
+ * be found must be handled through other mechanisms.
+ */
+ if((getgid() != getegid()) || (getuid() != geteuid()) ) {
+ return;
+ }
+#endif
+
+ /* runpath contains current effective LD_LIBRARY_PATH setting */
+
+ jvmpath = JLI_StringDup(jvmpath);
+ new_runpath = JLI_MemAlloc( ((runpath!=NULL)?strlen(runpath):0) +
+ 2*strlen(jrepath) + 2*strlen(arch) +
+ strlen(jvmpath) + 52);
+ newpath = new_runpath + strlen("LD_LIBRARY_PATH=");
+
+
+ /*
+ * Create desired LD_LIBRARY_PATH value for target data model.
+ */
+ {
+ /* remove the name of the .so from the JVM path */
+ lastslash = strrchr(jvmpath, '/');
+ if (lastslash)
+ *lastslash = '\0';
+
+
+ /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */
+
+ sprintf(new_runpath, "LD_LIBRARY_PATH="
+ "%s:"
+ "%s/lib/%s:"
+ "%s/../lib/%s",
+ jvmpath,
+#ifdef DUAL_MODE
+ jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME),
+ jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME)
+#else
+ jrepath, arch,
+ jrepath, arch
+#endif
+ );
+
+
+ /*
+ * Check to make sure that the prefix of the current path is the
+ * desired environment variable setting.
+ */
+ if (runpath != NULL &&
+ strncmp(newpath, runpath, strlen(newpath))==0 &&
+ (runpath[strlen(newpath)] == 0 || runpath[strlen(newpath)] == ':') &&
+ (running == wanted) /* data model does not have to be changed */
+#ifdef __sun
+ && (dmpath == NULL) /* data model specific variables not set */
+#endif
+ ) {
+
+ return;
+
+ }
+ }
+
+ /*
+ * Place the desired environment setting onto the prefix of
+ * LD_LIBRARY_PATH. Note that this prevents any possible infinite
+ * loop of execv() because we test for the prefix, above.
+ */
+ if (runpath != 0) {
+ strcat(new_runpath, ":");
+ strcat(new_runpath, runpath);
+ }
+
+ if( putenv(new_runpath) != 0) {
+ exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
+ properly */
+ }
+
+ /*
+ * Unix systems document that they look at LD_LIBRARY_PATH only
+ * once at startup, so we have to re-exec the current executable
+ * to get the changed environment variable to have an effect.
+ */
+
+#ifdef __sun
+ /*
+ * If dmpath is not NULL, remove the data model specific string
+ * in the environment for the exec'ed child.
+ */
+
+ if( dmpath != NULL)
+ (void)UnsetEnv((wanted==32)?"LD_LIBRARY_PATH_32":"LD_LIBRARY_PATH_64");
+#endif
+
+ newenvp = environ;
+
+ {
+ char *newexec = execname;
+#ifdef DUAL_MODE
+ /*
+ * If the data model is being changed, the path to the
+ * executable must be updated accordingly; the executable name
+ * and directory the executable resides in are separate. In the
+ * case of 32 => 64, the new bits are assumed to reside in, e.g.
+ * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
+ * the bits are assumed to be in "olddir/../execname". For example,
+ *
+ * olddir/sparcv9/execname
+ * olddir/amd64/execname
+ *
+ * for Solaris SPARC and Linux amd64, respectively.
+ */
+
+ if (running != wanted) {
+ char *oldexec = strcpy(JLI_MemAlloc(strlen(execname) + 1), execname);
+ char *olddir = oldexec;
+ char *oldbase = strrchr(oldexec, '/');
+
+
+ newexec = JLI_MemAlloc(strlen(execname) + 20);
+ *oldbase++ = 0;
+ sprintf(newexec, "%s/%s/%s", olddir,
+ ((wanted==64) ? LIBARCH64NAME : ".."), oldbase);
+ argv[0] = newexec;
+ }
+#endif
+
+ (void)fflush(stdout);
+ (void)fflush(stderr);
+ execve(newexec, argv, newenvp);
+ perror("execve()");
+
+ fprintf(stderr, "Error trying to exec %s.\n", newexec);
+ fprintf(stderr, "Check if file exists and permissions are set correctly.\n");
+
+#ifdef DUAL_MODE
+ if (running != wanted) {
+ fprintf(stderr, "Failed to start a %d-bit JVM process from a %d-bit JVM.\n",
+ wanted, running);
+# ifdef __sun
+
+# ifdef __sparc
+ fprintf(stderr, "Verify all necessary J2SE components have been installed.\n" );
+ fprintf(stderr,
+ "(Solaris SPARC 64-bit components must be installed after 32-bit components.)\n" );
+# else
+ fprintf(stderr, "Either 64-bit processes are not supported by this platform\n");
+ fprintf(stderr, "or the 64-bit components have not been installed.\n");
+# endif
+ }
+# endif
+#endif
+
+ }
+
+ exit(1);
+ }
+
+}
+
+
+/*
+ * On Solaris VM choosing is done by the launcher (java.c).
+ */
+static jboolean
+GetJVMPath(const char *jrepath, const char *jvmtype,
+ char *jvmpath, jint jvmpathsize, char * arch)
+{
+ struct stat s;
+
+ if (strchr(jvmtype, '/')) {
+ sprintf(jvmpath, "%s/" JVM_DLL, jvmtype);
+ } else {
+ sprintf(jvmpath, "%s/lib/%s/%s/" JVM_DLL, jrepath, arch, jvmtype);
+ }
+ if (_launcher_debug)
+ printf("Does `%s' exist ... ", jvmpath);
+
+ if (stat(jvmpath, &s) == 0) {
+ if (_launcher_debug)
+ printf("yes.\n");
+ return JNI_TRUE;
+ } else {
+ if (_launcher_debug)
+ printf("no.\n");
+ return JNI_FALSE;
+ }
+}
+
+/*
+ * Find path to JRE based on .exe's location or registry settings.
+ */
+static jboolean
+GetJREPath(char *path, jint pathsize, char * arch, jboolean speculative)
+{
+ char libjava[MAXPATHLEN];
+
+ if (GetApplicationHome(path, pathsize)) {
+ /* Is JRE co-located with the application? */
+ sprintf(libjava, "%s/lib/%s/" JAVA_DLL, path, arch);
+ if (access(libjava, F_OK) == 0) {
+ goto found;
+ }
+
+ /* Does the app ship a private JRE in <apphome>/jre directory? */
+ sprintf(libjava, "%s/jre/lib/%s/" JAVA_DLL, path, arch);
+ if (access(libjava, F_OK) == 0) {
+ strcat(path, "/jre");
+ goto found;
+ }
+ }
+
+ if (!speculative)
+ fprintf(stderr, "Error: could not find " JAVA_DLL "\n");
+ return JNI_FALSE;
+
+ found:
+ if (_launcher_debug)
+ printf("JRE path is %s\n", path);
+ return JNI_TRUE;
+}
+
+jboolean
+LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
+{
+ Dl_info dlinfo;
+ void *libjvm;
+
+ if (_launcher_debug) {
+ printf("JVM path is %s\n", jvmpath);
+ }
+
+ libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL);
+ if (libjvm == NULL) {
+#if defined(__solaris__) && defined(__sparc) && !defined(_LP64) /* i.e. 32-bit sparc */
+ FILE * fp;
+ Elf32_Ehdr elf_head;
+ int count;
+ int location;
+
+ fp = fopen(jvmpath, "r");
+ if(fp == NULL)
+ goto error;
+
+ /* read in elf header */
+ count = fread((void*)(&elf_head), sizeof(Elf32_Ehdr), 1, fp);
+ fclose(fp);
+ if(count < 1)
+ goto error;
+
+ /*
+ * Check for running a server vm (compiled with -xarch=v8plus)
+ * on a stock v8 processor. In this case, the machine type in
+ * the elf header would not be included the architecture list
+ * provided by the isalist command, which is turn is gotten from
+ * sysinfo. This case cannot occur on 64-bit hardware and thus
+ * does not have to be checked for in binaries with an LP64 data
+ * model.
+ */
+ if(elf_head.e_machine == EM_SPARC32PLUS) {
+ char buf[257]; /* recommended buffer size from sysinfo man
+ page */
+ long length;
+ char* location;
+
+ length = sysinfo(SI_ISALIST, buf, 257);
+ if(length > 0) {
+ location = strstr(buf, "sparcv8plus ");
+ if(location == NULL) {
+ fprintf(stderr, "SPARC V8 processor detected; Server compiler requires V9 or better.\n");
+ fprintf(stderr, "Use Client compiler on V8 processors.\n");
+ fprintf(stderr, "Could not create the Java virtual machine.\n");
+ return JNI_FALSE;
+ }
+ }
+ }
+#endif
+ fprintf(stderr, "dl failure on line %d", __LINE__);
+ goto error;
+ }
+
+ ifn->CreateJavaVM = (CreateJavaVM_t)
+ dlsym(libjvm, "JNI_CreateJavaVM");
+ if (ifn->CreateJavaVM == NULL)
+ goto error;
+
+ ifn->GetDefaultJavaVMInitArgs = (GetDefaultJavaVMInitArgs_t)
+ dlsym(libjvm, "JNI_GetDefaultJavaVMInitArgs");
+ if (ifn->GetDefaultJavaVMInitArgs == NULL)
+ goto error;
+
+ return JNI_TRUE;
+
+error:
+ fprintf(stderr, "Error: failed %s, because %s\n", jvmpath, dlerror());
+ return JNI_FALSE;
+}
+
+/*
+ * If app is "/foo/bin/javac", or "/foo/bin/sparcv9/javac" then put
+ * "/foo" into buf.
+ */
+jboolean
+GetApplicationHome(char *buf, jint bufsize)
+{
+#ifdef __linux__
+ char *execname = GetExecname();
+ if (execname) {
+ strncpy(buf, execname, bufsize-1);
+ buf[bufsize-1] = '\0';
+ } else {
+ return JNI_FALSE;
+ }
+#else
+ Dl_info dlinfo;
+
+ dladdr((void *)GetApplicationHome, &dlinfo);
+ if (realpath(dlinfo.dli_fname, buf) == NULL) {
+ fprintf(stderr, "Error: realpath(`%s') failed.\n", dlinfo.dli_fname);
+ return JNI_FALSE;
+ }
+#endif
+
+ if (strrchr(buf, '/') == 0) {
+ buf[0] = '\0';
+ return JNI_FALSE;
+ }
+ *(strrchr(buf, '/')) = '\0'; /* executable file */
+ if (strlen(buf) < 4 || strrchr(buf, '/') == 0) {
+ buf[0] = '\0';
+ return JNI_FALSE;
+ }
+ if (strcmp("/bin", buf + strlen(buf) - 4) != 0)
+ *(strrchr(buf, '/')) = '\0'; /* sparcv9 or amd64 */
+ if (strlen(buf) < 4 || strcmp("/bin", buf + strlen(buf) - 4) != 0) {
+ buf[0] = '\0';
+ return JNI_FALSE;
+ }
+ *(strrchr(buf, '/')) = '\0'; /* bin */
+
+ return JNI_TRUE;
+}
+
+
+/*
+ * Return true if the named program exists
+ */
+static int
+ProgramExists(char *name)
+{
+ struct stat sb;
+ if (stat(name, &sb) != 0) return 0;
+ if (S_ISDIR(sb.st_mode)) return 0;
+ return (sb.st_mode & S_IEXEC) != 0;
+}
+
+
+/*
+ * Find a command in a directory, returning the path.
+ */
+static char *
+Resolve(char *indir, char *cmd)
+{
+ char name[PATH_MAX + 2], *real;
+
+ if ((strlen(indir) + strlen(cmd) + 1) > PATH_MAX) return 0;
+ sprintf(name, "%s%c%s", indir, FILE_SEPARATOR, cmd);
+ if (!ProgramExists(name)) return 0;
+ real = JLI_MemAlloc(PATH_MAX + 2);
+ if (!realpath(name, real))
+ strcpy(real, name);
+ return real;
+}
+
+
+/*
+ * Find a path for the executable
+ */
+static char *
+FindExecName(char *program)
+{
+ char cwdbuf[PATH_MAX+2];
+ char *path;
+ char *tmp_path;
+ char *f;
+ char *result = NULL;
+
+ /* absolute path? */
+ if (*program == FILE_SEPARATOR ||
+ (FILE_SEPARATOR=='\\' && strrchr(program, ':')))
+ return Resolve("", program+1);
+
+ /* relative path? */
+ if (strrchr(program, FILE_SEPARATOR) != 0) {
+ char buf[PATH_MAX+2];
+ return Resolve(getcwd(cwdbuf, sizeof(cwdbuf)), program);
+ }
+
+ /* from search path? */
+ path = getenv("PATH");
+ if (!path || !*path) path = ".";
+ tmp_path = JLI_MemAlloc(strlen(path) + 2);
+ strcpy(tmp_path, path);
+
+ for (f=tmp_path; *f && result==0; ) {
+ char *s = f;
+ while (*f && (*f != PATH_SEPARATOR)) ++f;
+ if (*f) *f++ = 0;
+ if (*s == FILE_SEPARATOR)
+ result = Resolve(s, program);
+ else {
+ /* relative path element */
+ char dir[2*PATH_MAX];
+ sprintf(dir, "%s%c%s", getcwd(cwdbuf, sizeof(cwdbuf)),
+ FILE_SEPARATOR, s);
+ result = Resolve(dir, program);
+ }
+ if (result != 0) break;
+ }
+
+ JLI_MemFree(tmp_path);
+ return result;
+}
+
+
+/* Store the name of the executable once computed */
+static char *execname = NULL;
+
+/*
+ * Compute the name of the executable
+ *
+ * In order to re-exec securely we need the absolute path of the
+ * executable. On Solaris getexecname(3c) may not return an absolute
+ * path so we use dladdr to get the filename of the executable and
+ * then use realpath to derive an absolute path. From Solaris 9
+ * onwards the filename returned in DL_info structure from dladdr is
+ * an absolute pathname so technically realpath isn't required.
+ * On Linux we read the executable name from /proc/self/exe.
+ * As a fallback, and for platforms other than Solaris and Linux,
+ * we use FindExecName to compute the executable name.
+ */
+static char *
+SetExecname(char **argv)
+{
+ char* exec_path = NULL;
+
+ if (execname != NULL) /* Already determined */
+ return (execname);
+
+#if defined(__sun)
+ {
+ Dl_info dlinfo;
+ if (dladdr((void*)&SetExecname, &dlinfo)) {
+ char *resolved = (char*)JLI_MemAlloc(PATH_MAX+1);
+ if (resolved != NULL) {
+ exec_path = realpath(dlinfo.dli_fname, resolved);
+ if (exec_path == NULL) {
+ JLI_MemFree(resolved);
+ }
+ }
+ }
+ }
+#elif defined(__linux__)
+ {
+ const char* self = "/proc/self/exe";
+ char buf[PATH_MAX+1];
+ int len = readlink(self, buf, PATH_MAX);
+ if (len >= 0) {
+ buf[len] = '\0'; /* readlink doesn't nul terminate */
+ exec_path = JLI_StringDup(buf);
+ }
+ }
+#else /* !__sun && !__linux */
+ {
+ /* Not implemented */
+ }
+#endif
+
+ if (exec_path == NULL) {
+ exec_path = FindExecName(argv[0]);
+ }
+ execname = exec_path;
+ return exec_path;
+}
+
+/*
+ * Return the name of the executable. Used in java_md.c to find the JRE area.
+ */
+static char *
+GetExecname() {
+ return execname;
+}
+
+void ReportErrorMessage(char * message, jboolean always) {
+ if (always) {
+ fprintf(stderr, "%s\n", message);
+ }
+}
+
+void ReportErrorMessage2(char * format, char * string, jboolean always) {
+ if (always) {
+ fprintf(stderr, format, string);
+ fprintf(stderr, "\n");
+ }
+}
+
+void ReportExceptionDescription(JNIEnv * env) {
+ (*env)->ExceptionDescribe(env);
+}
+
+/*
+ * Return JNI_TRUE for an option string that has no effect but should
+ * _not_ be passed on to the vm; return JNI_FALSE otherwise. On
+ * Solaris SPARC, this screening needs to be done if:
+ * 1) LD_LIBRARY_PATH does _not_ need to be reset and
+ * 2) -d32 or -d64 is passed to a binary with a matching data model
+ * (the exec in SetLibraryPath removes -d<n> options and points the
+ * exec to the proper binary). When this exec is not done, these options
+ * would end up getting passed onto the vm.
+ */
+jboolean RemovableMachineDependentOption(char * option) {
+ /*
+ * Unconditionally remove both -d32 and -d64 options since only
+ * the last such options has an effect; e.g.
+ * java -d32 -d64 -d32 -version
+ * is equivalent to
+ * java -d32 -version
+ */
+
+ if( (strcmp(option, "-d32") == 0 ) ||
+ (strcmp(option, "-d64") == 0 ) )
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
+}
+
+/*
+ * The following methods (down to ServerClassMachine()) answer
+ * the question about whether a machine is a "server-class"
+ * machine. A server-class machine is loosely defined as one
+ * with 2 or more processors and 2 gigabytes or more physical
+ * memory. The definition of a processor is a physical package,
+ * not a hyperthreaded chip masquerading as a multi-processor.
+ * The definition of memory is also somewhat fuzzy, since x86
+ * machines seem not to report all the memory in their DIMMs, we
+ * think because of memory mapping of graphics cards, etc.
+ *
+ * This code is somewhat more confused with #ifdef's than we'd
+ * like because this file is used by both Solaris and Linux
+ * platforms, and so needs to be parameterized for SPARC and
+ * i586 hardware. The other Linux platforms (amd64 and ia64)
+ * don't even ask this question, because they only come with
+ * server JVMs. */
+
+# define KB (1024UL)
+# define MB (1024UL * KB)
+# define GB (1024UL * MB)
+
+/* Compute physical memory by asking the OS */
+uint64_t
+physical_memory(void) {
+ const uint64_t pages = (uint64_t) sysconf(_SC_PHYS_PAGES);
+ const uint64_t page_size = (uint64_t) sysconf(_SC_PAGESIZE);
+ const uint64_t result = pages * page_size;
+# define UINT64_FORMAT "%" PRIu64
+
+ if (_launcher_debug) {
+ printf("pages: " UINT64_FORMAT
+ " page_size: " UINT64_FORMAT
+ " physical memory: " UINT64_FORMAT " (%.3fGB)\n",
+ pages, page_size, result, result / (double) GB);
+ }
+ return result;
+}
+
+#if defined(__sparc)
+
+/* Methods for solaris-sparc and linux-sparc: these are easy. */
+
+/* Ask the OS how many processors there are. */
+unsigned long
+physical_processors(void) {
+ const unsigned long sys_processors = sysconf(_SC_NPROCESSORS_CONF);
+
+ if (_launcher_debug) {
+ printf("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors);
+ }
+ return sys_processors;
+}
+
+/* The sparc version of the "server-class" predicate. */
+jboolean
+unix_sparc_ServerClassMachine(void) {
+ jboolean result = JNI_FALSE;
+ /* How big is a server class machine? */
+ const unsigned long server_processors = 2UL;
+ const uint64_t server_memory = 2UL * GB;
+ const uint64_t actual_memory = physical_memory();
+
+ /* Is this a server class machine? */
+ if (actual_memory >= server_memory) {
+ const unsigned long actual_processors = physical_processors();
+ if (actual_processors >= server_processors) {
+ result = JNI_TRUE;
+ }
+ }
+ if (_launcher_debug) {
+ printf("unix_" LIBARCHNAME "_ServerClassMachine: %s\n",
+ (result == JNI_TRUE ? "JNI_TRUE" : "JNI_FALSE"));
+ }
+ return result;
+}
+
+#endif /* __sparc */
+
+#if defined(__sun) && defined(i586)
+
+/*
+ * A utility method for asking the CPU about itself.
+ * There's a corresponding version of linux-i586
+ * because the compilers are different.
+ */
+void
+get_cpuid(uint32_t arg,
+ uint32_t* eaxp,
+ uint32_t* ebxp,
+ uint32_t* ecxp,
+ uint32_t* edxp) {
+#ifdef _LP64
+ asm(
+ /* rbx is a callee-saved register */
+ " movq %rbx, %r11 \n"
+ /* rdx and rcx are 3rd and 4th argument registers */
+ " movq %rdx, %r10 \n"
+ " movq %rcx, %r9 \n"
+ " movl %edi, %eax \n"
+ " cpuid \n"
+ " movl %eax, (%rsi)\n"
+ " movl %ebx, (%r10)\n"
+ " movl %ecx, (%r9) \n"
+ " movl %edx, (%r8) \n"
+ /* Restore rbx */
+ " movq %r11, %rbx");
+#else
+ /* EBX is a callee-saved register */
+ asm(" pushl %ebx");
+ /* Need ESI for storing through arguments */
+ asm(" pushl %esi");
+ asm(" movl 8(%ebp), %eax \n"
+ " cpuid \n"
+ " movl 12(%ebp), %esi \n"
+ " movl %eax, (%esi) \n"
+ " movl 16(%ebp), %esi \n"
+ " movl %ebx, (%esi) \n"
+ " movl 20(%ebp), %esi \n"
+ " movl %ecx, (%esi) \n"
+ " movl 24(%ebp), %esi \n"
+ " movl %edx, (%esi) ");
+ /* Restore ESI and EBX */
+ asm(" popl %esi");
+ /* Restore EBX */
+ asm(" popl %ebx");
+#endif
+}
+
+#endif /* __sun && i586 */
+
+#if defined(__linux__) && defined(i586)
+
+/*
+ * A utility method for asking the CPU about itself.
+ * There's a corresponding version of solaris-i586
+ * because the compilers are different.
+ */
+void
+get_cpuid(uint32_t arg,
+ uint32_t* eaxp,
+ uint32_t* ebxp,
+ uint32_t* ecxp,
+ uint32_t* edxp) {
+#ifdef _LP64
+ __asm__ volatile (/* Instructions */
+ " movl %4, %%eax \n"
+ " cpuid \n"
+ " movl %%eax, (%0)\n"
+ " movl %%ebx, (%1)\n"
+ " movl %%ecx, (%2)\n"
+ " movl %%edx, (%3)\n"
+ : /* Outputs */
+ : /* Inputs */
+ "r" (eaxp),
+ "r" (ebxp),
+ "r" (ecxp),
+ "r" (edxp),
+ "r" (arg)
+ : /* Clobbers */
+ "%rax", "%rbx", "%rcx", "%rdx", "memory"
+ );
+#else
+ uint32_t value_of_eax = 0;
+ uint32_t value_of_ebx = 0;
+ uint32_t value_of_ecx = 0;
+ uint32_t value_of_edx = 0;
+ __asm__ volatile (/* Instructions */
+ /* ebx is callee-save, so push it */
+ " pushl %%ebx \n"
+ " movl %4, %%eax \n"
+ " cpuid \n"
+ " movl %%eax, %0 \n"
+ " movl %%ebx, %1 \n"
+ " movl %%ecx, %2 \n"
+ " movl %%edx, %3 \n"
+ /* restore ebx */
+ " popl %%ebx \n"
+
+ : /* Outputs */
+ "=m" (value_of_eax),
+ "=m" (value_of_ebx),
+ "=m" (value_of_ecx),
+ "=m" (value_of_edx)
+ : /* Inputs */
+ "m" (arg)
+ : /* Clobbers */
+ "%eax", "%ecx", "%edx"
+ );
+ *eaxp = value_of_eax;
+ *ebxp = value_of_ebx;
+ *ecxp = value_of_ecx;
+ *edxp = value_of_edx;
+#endif
+}
+
+#endif /* __linux__ && i586 */
+
+#ifdef i586
+/*
+ * Routines shared by solaris-i586 and linux-i586.
+ */
+
+enum HyperThreadingSupport_enum {
+ hts_supported = 1,
+ hts_too_soon_to_tell = 0,
+ hts_not_supported = -1,
+ hts_not_pentium4 = -2,
+ hts_not_intel = -3
+};
+typedef enum HyperThreadingSupport_enum HyperThreadingSupport;
+
+/* Determine if hyperthreading is supported */
+HyperThreadingSupport
+hyperthreading_support(void) {
+ HyperThreadingSupport result = hts_too_soon_to_tell;
+ /* Bits 11 through 8 is family processor id */
+# define FAMILY_ID_SHIFT 8
+# define FAMILY_ID_MASK 0xf
+ /* Bits 23 through 20 is extended family processor id */
+# define EXT_FAMILY_ID_SHIFT 20
+# define EXT_FAMILY_ID_MASK 0xf
+ /* Pentium 4 family processor id */
+# define PENTIUM4_FAMILY_ID 0xf
+ /* Bit 28 indicates Hyper-Threading Technology support */
+# define HT_BIT_SHIFT 28
+# define HT_BIT_MASK 1
+ uint32_t vendor_id[3] = { 0U, 0U, 0U };
+ uint32_t value_of_eax = 0U;
+ uint32_t value_of_edx = 0U;
+ uint32_t dummy = 0U;
+
+ /* Yes, this is supposed to be [0], [2], [1] */
+ get_cpuid(0, &dummy, &vendor_id[0], &vendor_id[2], &vendor_id[1]);
+ if (_launcher_debug) {
+ printf("vendor: %c %c %c %c %c %c %c %c %c %c %c %c \n",
+ ((vendor_id[0] >> 0) & 0xff),
+ ((vendor_id[0] >> 8) & 0xff),
+ ((vendor_id[0] >> 16) & 0xff),
+ ((vendor_id[0] >> 24) & 0xff),
+ ((vendor_id[1] >> 0) & 0xff),
+ ((vendor_id[1] >> 8) & 0xff),
+ ((vendor_id[1] >> 16) & 0xff),
+ ((vendor_id[1] >> 24) & 0xff),
+ ((vendor_id[2] >> 0) & 0xff),
+ ((vendor_id[2] >> 8) & 0xff),
+ ((vendor_id[2] >> 16) & 0xff),
+ ((vendor_id[2] >> 24) & 0xff));
+ }
+ get_cpuid(1, &value_of_eax, &dummy, &dummy, &value_of_edx);
+ if (_launcher_debug) {
+ printf("value_of_eax: 0x%x value_of_edx: 0x%x\n",
+ value_of_eax, value_of_edx);
+ }
+ if ((((value_of_eax >> FAMILY_ID_SHIFT) & FAMILY_ID_MASK) == PENTIUM4_FAMILY_ID) ||
+ (((value_of_eax >> EXT_FAMILY_ID_SHIFT) & EXT_FAMILY_ID_MASK) != 0)) {
+ if ((((vendor_id[0] >> 0) & 0xff) == 'G') &&
+ (((vendor_id[0] >> 8) & 0xff) == 'e') &&
+ (((vendor_id[0] >> 16) & 0xff) == 'n') &&
+ (((vendor_id[0] >> 24) & 0xff) == 'u') &&
+ (((vendor_id[1] >> 0) & 0xff) == 'i') &&
+ (((vendor_id[1] >> 8) & 0xff) == 'n') &&
+ (((vendor_id[1] >> 16) & 0xff) == 'e') &&
+ (((vendor_id[1] >> 24) & 0xff) == 'I') &&
+ (((vendor_id[2] >> 0) & 0xff) == 'n') &&
+ (((vendor_id[2] >> 8) & 0xff) == 't') &&
+ (((vendor_id[2] >> 16) & 0xff) == 'e') &&
+ (((vendor_id[2] >> 24) & 0xff) == 'l')) {
+ if (((value_of_edx >> HT_BIT_SHIFT) & HT_BIT_MASK) == HT_BIT_MASK) {
+ if (_launcher_debug) {
+ printf("Hyperthreading supported\n");
+ }
+ result = hts_supported;
+ } else {
+ if (_launcher_debug) {
+ printf("Hyperthreading not supported\n");
+ }
+ result = hts_not_supported;
+ }
+ } else {
+ if (_launcher_debug) {
+ printf("Not GenuineIntel\n");
+ }
+ result = hts_not_intel;
+ }
+ } else {
+ if (_launcher_debug) {
+ printf("not Pentium 4 or extended\n");
+ }
+ result = hts_not_pentium4;
+ }
+ return result;
+}
+
+/* Determine how many logical processors there are per CPU */
+unsigned int
+logical_processors_per_package(void) {
+ /*
+ * After CPUID with EAX==1, register EBX bits 23 through 16
+ * indicate the number of logical processors per package
+ */
+# define NUM_LOGICAL_SHIFT 16
+# define NUM_LOGICAL_MASK 0xff
+ unsigned int result = 1U;
+ const HyperThreadingSupport hyperthreading = hyperthreading_support();
+
+ if (hyperthreading == hts_supported) {
+ uint32_t value_of_ebx = 0U;
+ uint32_t dummy = 0U;
+
+ get_cpuid(1, &dummy, &value_of_ebx, &dummy, &dummy);
+ result = (value_of_ebx >> NUM_LOGICAL_SHIFT) & NUM_LOGICAL_MASK;
+ if (_launcher_debug) {
+ printf("logical processors per package: %u\n", result);
+ }
+ }
+ return result;
+}
+
+/* Compute the number of physical processors, not logical processors */
+unsigned long
+physical_processors(void) {
+ const long sys_processors = sysconf(_SC_NPROCESSORS_CONF);
+ unsigned long result = sys_processors;
+
+ if (_launcher_debug) {
+ printf("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors);
+ }
+ if (sys_processors > 1) {
+ unsigned int logical_processors = logical_processors_per_package();
+ if (logical_processors > 1) {
+ result = (unsigned long) sys_processors / logical_processors;
+ }
+ }
+ if (_launcher_debug) {
+ printf("physical processors: %lu\n", result);
+ }
+ return result;
+}
+
+#endif /* i586 */
+
+#if defined(__sun) && defined(i586)
+
+/* The definition of a server-class machine for solaris-i586/amd64 */
+jboolean
+solaris_i586_ServerClassMachine(void) {
+ jboolean result = JNI_FALSE;
+ /* How big is a server class machine? */
+ const unsigned long server_processors = 2UL;
+ const uint64_t server_memory = 2UL * GB;
+ /*
+ * We seem not to get our full complement of memory.
+ * We allow some part (1/8?) of the memory to be "missing",
+ * based on the sizes of DIMMs, and maybe graphics cards.
+ */
+ const uint64_t missing_memory = 256UL * MB;
+ const uint64_t actual_memory = physical_memory();
+
+ /* Is this a server class machine? */
+ if (actual_memory >= (server_memory - missing_memory)) {
+ const unsigned long actual_processors = physical_processors();
+ if (actual_processors >= server_processors) {
+ result = JNI_TRUE;
+ }
+ }
+ if (_launcher_debug) {
+ printf("solaris_" LIBARCHNAME "_ServerClassMachine: %s\n",
+ (result == JNI_TRUE ? "true" : "false"));
+ }
+ return result;
+}
+
+#endif /* __sun && i586 */
+
+#if defined(__linux__) && defined(i586)
+
+/* The definition of a server-class machine for linux-i586 */
+jboolean
+linux_i586_ServerClassMachine(void) {
+ jboolean result = JNI_FALSE;
+ /* How big is a server class machine? */
+ const unsigned long server_processors = 2UL;
+ const uint64_t server_memory = 2UL * GB;
+ /*
+ * We seem not to get our full complement of memory.
+ * We allow some part (1/8?) of the memory to be "missing",
+ * based on the sizes of DIMMs, and maybe graphics cards.
+ */
+ const uint64_t missing_memory = 256UL * MB;
+ const uint64_t actual_memory = physical_memory();
+
+ /* Is this a server class machine? */
+ if (actual_memory >= (server_memory - missing_memory)) {
+ const unsigned long actual_processors = physical_processors();
+ if (actual_processors >= server_processors) {
+ result = JNI_TRUE;
+ }
+ }
+ if (_launcher_debug) {
+ printf("linux_" LIBARCHNAME "_ServerClassMachine: %s\n",
+ (result == JNI_TRUE ? "true" : "false"));
+ }
+ return result;
+}
+
+#endif /* __linux__ && i586 */
+
+/* Dispatch to the platform-specific definition of "server-class" */
+jboolean
+ServerClassMachine(void) {
+ jboolean result = JNI_FALSE;
+#if defined(NEVER_ACT_AS_SERVER_CLASS_MACHINE)
+ result = JNI_FALSE;
+#elif defined(ALWAYS_ACT_AS_SERVER_CLASS_MACHINE)
+ result = JNI_TRUE;
+#elif defined(__sun) && defined(__sparc)
+ result = unix_sparc_ServerClassMachine();
+#elif defined(__sun) && defined(i586)
+ result = solaris_i586_ServerClassMachine();
+#elif defined(__linux__) && defined(i586)
+ result = linux_i586_ServerClassMachine();
+#else
+ if (_launcher_debug) {
+ printf("ServerClassMachine: returns default value of %s\n",
+ (result == JNI_TRUE ? "true" : "false"));
+ }
+#endif
+ return result;
+}
+
+/*
+ * Since using the file system as a registry is a bit risky, perform
+ * additional sanity checks on the identified directory to validate
+ * it as a valid jre/sdk.
+ *
+ * Return 0 if the tests fail; otherwise return non-zero (true).
+ *
+ * Note that checking for anything more than the existence of an
+ * executable object at bin/java relative to the path being checked
+ * will break the regression tests.
+ */
+static int
+CheckSanity(char *path, char *dir)
+{
+ char buffer[PATH_MAX];
+
+ if (strlen(path) + strlen(dir) + 11 > PATH_MAX)
+ return (0); /* Silently reject "impossibly" long paths */
+
+ (void)strcat(strcat(strcat(strcpy(buffer, path), "/"), dir), "/bin/java");
+ return ((access(buffer, X_OK) == 0) ? 1 : 0);
+}
+
+/*
+ * Determine if there is an acceptable JRE in the directory dirname.
+ * Upon locating the "best" one, return a fully qualified path to
+ * it. "Best" is defined as the most advanced JRE meeting the
+ * constraints contained in the manifest_info. If no JRE in this
+ * directory meets the constraints, return NULL.
+ *
+ * Note that we don't check for errors in reading the directory
+ * (which would be done by checking errno). This is because it
+ * doesn't matter if we get an error reading the directory, or
+ * we just don't find anything interesting in the directory. We
+ * just return NULL in either case.
+ *
+ * The historical names of j2sdk and j2re were changed to jdk and
+ * jre respecively as part of the 1.5 rebranding effort. Since the
+ * former names are legacy on Linux, they must be recognized for
+ * all time. Fortunately, this is a minor cost.
+ */
+static char
+*ProcessDir(manifest_info *info, char *dirname)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ char *best = NULL;
+ int offset;
+ int best_offset = 0;
+ char *ret_str = NULL;
+ char buffer[PATH_MAX];
+
+ if ((dirp = opendir(dirname)) == NULL)
+ return (NULL);
+
+ do {
+ if ((dp = readdir(dirp)) != NULL) {
+ offset = 0;
+ if ((strncmp(dp->d_name, "jre", 3) == 0) ||
+ (strncmp(dp->d_name, "jdk", 3) == 0))
+ offset = 3;
+ else if (strncmp(dp->d_name, "j2re", 4) == 0)
+ offset = 4;
+ else if (strncmp(dp->d_name, "j2sdk", 5) == 0)
+ offset = 5;
+ if (offset > 0) {
+ if ((JLI_AcceptableRelease(dp->d_name + offset,
+ info->jre_version)) && CheckSanity(dirname, dp->d_name))
+ if ((best == NULL) || (JLI_ExactVersionId(
+ dp->d_name + offset, best + best_offset) > 0)) {
+ if (best != NULL)
+ JLI_MemFree(best);
+ best = JLI_StringDup(dp->d_name);
+ best_offset = offset;
+ }
+ }
+ }
+ } while (dp != NULL);
+ (void) closedir(dirp);
+ if (best == NULL)
+ return (NULL);
+ else {
+ ret_str = JLI_MemAlloc(strlen(dirname) + strlen(best) + 2);
+ ret_str = strcat(strcat(strcpy(ret_str, dirname), "/"), best);
+ JLI_MemFree(best);
+ return (ret_str);
+ }
+}
+
+/*
+ * This is the global entry point. It examines the host for the optimal
+ * JRE to be used by scanning a set of directories. The set of directories
+ * is platform dependent and can be overridden by the environment
+ * variable JAVA_VERSION_PATH.
+ *
+ * This routine itself simply determines the set of appropriate
+ * directories before passing control onto ProcessDir().
+ */
+char*
+LocateJRE(manifest_info* info)
+{
+ char *path;
+ char *home;
+ char *target = NULL;
+ char *dp;
+ char *cp;
+
+ /*
+ * Start by getting JAVA_VERSION_PATH
+ */
+ if (info->jre_restrict_search)
+ path = JLI_StringDup(system_dir);
+ else if ((path = getenv("JAVA_VERSION_PATH")) != NULL)
+ path = JLI_StringDup(path);
+ else
+ if ((home = getenv("HOME")) != NULL) {
+ path = (char *)JLI_MemAlloc(strlen(home) + strlen(system_dir) +
+ strlen(user_dir) + 2);
+ path = strcat(strcat(strcat(strcpy(path, home),
+ user_dir), ":"), system_dir);
+ } else
+ path = JLI_StringDup(system_dir);
+
+ /*
+ * Step through each directory on the path. Terminate the scan with
+ * the first directory with an acceptable JRE.
+ */
+ cp = dp = path;
+ while (dp != NULL) {
+ cp = strchr(dp, (int)':');
+ if (cp != NULL)
+ *cp = (char)NULL;
+ if ((target = ProcessDir(info, dp)) != NULL)
+ break;
+ dp = cp;
+ if (dp != NULL)
+ dp++;
+ }
+ JLI_MemFree(path);
+ return (target);
+}
+
+/*
+ * Given a path to a jre to execute, this routine checks if this process
+ * is indeed that jre. If not, it exec's that jre.
+ *
+ * We want to actually check the paths rather than just the version string
+ * built into the executable, so that given version specification (and
+ * JAVA_VERSION_PATH) will yield the exact same Java environment, regardless
+ * of the version of the arbitrary launcher we start with.
+ */
+void
+ExecJRE(char *jre, char **argv)
+{
+ char wanted[PATH_MAX];
+ char *execname;
+ char *progname;
+
+ /*
+ * Resolve the real path to the directory containing the selected JRE.
+ */
+ if (realpath(jre, wanted) == NULL) {
+ fprintf(stderr, "Unable to resolve %s\n", jre);
+ exit(1);
+ }
+
+ /*
+ * Resolve the real path to the currently running launcher.
+ */
+ execname = SetExecname(argv);
+ if (execname == NULL) {
+ fprintf(stderr, "Unable to resolve current executable\n");
+ exit(1);
+ }
+
+ /*
+ * If the path to the selected JRE directory is a match to the initial
+ * portion of the path to the currently executing JRE, we have a winner!
+ * If so, just return.
+ */
+ if (strncmp(wanted, execname, strlen(wanted)) == 0)
+ return; /* I am the droid you were looking for */
+
+ /*
+ * If this isn't the selected version, exec the selected version.
+ */
+#ifdef JAVA_ARGS /* javac, jar and friends. */
+ progname = "java";
+#else /* java, oldjava, javaw and friends */
+#ifdef PROGNAME
+ progname = PROGNAME;
+#else
+ progname = *argv;
+ if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) {
+ progname = s + 1;
+ }
+#endif /* PROGNAME */
+#endif /* JAVA_ARGS */
+
+ /*
+ * This should never happen (because of the selection code in SelectJRE),
+ * but check for "impossibly" long path names just because buffer overruns
+ * can be so deadly.
+ */
+ if (strlen(wanted) + strlen(progname) + 6 > PATH_MAX) {
+ fprintf(stderr, "Path length exceeds maximum length (PATH_MAX)\n");
+ exit(1);
+ }
+
+ /*
+ * Construct the path and exec it.
+ */
+ (void)strcat(strcat(wanted, "/bin/"), progname);
+ argv[0] = progname;
+ if (_launcher_debug) {
+ int i;
+ printf("ReExec Command: %s (%s)\n", wanted, argv[0]);
+ printf("ReExec Args:");
+ for (i = 1; argv[i] != NULL; i++)
+ printf(" %s", argv[i]);
+ printf("\n");
+ }
+ (void)fflush(stdout);
+ (void)fflush(stderr);
+ execv(wanted, argv);
+ perror("execv()");
+ fprintf(stderr, "Exec of %s failed\n", wanted);
+ exit(1);
+}
+
+/*
+ * "Borrowed" from Solaris 10 where the unsetenv() function is being added
+ * to libc thanks to SUSv3 (Standard Unix Specification, version 3). As
+ * such, in the fullness of time this will appear in libc on all relevant
+ * Solaris/Linux platforms and maybe even the Windows platform. At that
+ * time, this stub can be removed.
+ *
+ * This implementation removes the environment locking for multithreaded
+ * applications. (We don't have access to these mutexes within libc and
+ * the launcher isn't multithreaded.) Note that what remains is platform
+ * independent, because it only relies on attributes that a POSIX environment
+ * defines.
+ *
+ * Returns 0 on success, -1 on failure.
+ *
+ * Also removed was the setting of errno. The only value of errno set
+ * was EINVAL ("Invalid Argument").
+ */
+
+/*
+ * s1(environ) is name=value
+ * s2(name) is name(not the form of name=value).
+ * if names match, return value of 1, else return 0
+ */
+static int
+match_noeq(const char *s1, const char *s2)
+{
+ while (*s1 == *s2++) {
+ if (*s1++ == '=')
+ return (1);
+ }
+ if (*s1 == '=' && s2[-1] == '\0')
+ return (1);
+ return (0);
+}
+
+/*
+ * added for SUSv3 standard
+ *
+ * Delete entry from environ.
+ * Do not free() memory! Other threads may be using it.
+ * Keep it around forever.
+ */
+static int
+borrowed_unsetenv(const char *name)
+{
+ long idx; /* index into environ */
+
+ if (name == NULL || *name == '\0' ||
+ strchr(name, '=') != NULL) {
+ return (-1);
+ }
+
+ for (idx = 0; environ[idx] != NULL; idx++) {
+ if (match_noeq(environ[idx], name))
+ break;
+ }
+ if (environ[idx] == NULL) {
+ /* name not found but still a success */
+ return (0);
+ }
+ /* squeeze up one entry */
+ do {
+ environ[idx] = environ[idx+1];
+ } while (environ[++idx] != NULL);
+
+ return (0);
+}
+/* --- End of "borrowed" code --- */
+
+/*
+ * Wrapper for unsetenv() function.
+ */
+int
+UnsetEnv(char *name)
+{
+ return(borrowed_unsetenv(name));
+}
+
+/* --- Splash Screen shared library support --- */
+
+static const char* SPLASHSCREEN_SO = "libsplashscreen.so";
+
+static void* hSplashLib = NULL;
+
+void* SplashProcAddress(const char* name) {
+ if (!hSplashLib) {
+ hSplashLib = dlopen(SPLASHSCREEN_SO, RTLD_LAZY | RTLD_GLOBAL);
+ }
+ if (hSplashLib) {
+ void* sym = dlsym(hSplashLib, name);
+ return sym;
+ } else {
+ return NULL;
+ }
+}
+
+void SplashFreeLibrary() {
+ if (hSplashLib) {
+ dlclose(hSplashLib);
+ hSplashLib = NULL;
+ }
+}
+
+const char *
+jlong_format_specifier() {
+ return "%lld";
+}
+
+/*
+ * Block current thread and continue execution in a new thread
+ */
+int
+ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void * args, int ret) {
+ int rslt;
+#ifdef __linux__
+ pthread_t tid;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ if (stack_size > 0) {
+ pthread_attr_setstacksize(&attr, stack_size);
+ }
+
+ if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
+ void * tmp;
+ pthread_join(tid, &tmp);
+ rslt = (int)tmp;
+ } else {
+ /*
+ * Continue execution in current thread if for some reason (e.g. out of
+ * memory/LWP) a new thread can't be created. This will likely fail
+ * later in continuation as JNI_CreateJavaVM needs to create quite a
+ * few new threads, anyway, just give it a try..
+ */
+ rslt = continuation(args);
+ }
+
+ pthread_attr_destroy(&attr);
+#else
+ thread_t tid;
+ long flags = 0;
+ if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
+ void * tmp;
+ thr_join(tid, NULL, &tmp);
+ rslt = (int)tmp;
+ } else {
+ /* See above. Continue in current thread if thr_create() failed */
+ rslt = continuation(args);
+ }
+#endif
+ /* If the caller has deemed there is an error we
+ * simply return that, otherwise we return the value of
+ * the callee
+ */
+ return (ret != 0) ? ret : rslt;
+}
+
+/* Coarse estimation of number of digits assuming the worst case is a 64-bit pid. */
+#define MAX_PID_STR_SZ 20
+
+void SetJavaLauncherPlatformProps() {
+ /* Linux only */
+#ifdef __linux__
+ const char *substr = "-Dsun.java.launcher.pid=";
+ char *pid_prop_str = (char *)JLI_MemAlloc(strlen(substr) + MAX_PID_STR_SZ + 1);
+ sprintf(pid_prop_str, "%s%d", substr, getpid());
+ AddOption(pid_prop_str, NULL);
+#endif
+}
diff --git a/launcher/java_md.h b/launcher/java_md.h
new file mode 100644
index 0000000..21ac500
--- /dev/null
+++ b/launcher/java_md.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef JAVA_MD_H
+#define JAVA_MD_H
+
+#include <limits.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include "manifest_info.h"
+#include "jli_util.h"
+
+#define PATH_SEPARATOR ':'
+#define FILESEP "/"
+#define FILE_SEPARATOR '/'
+#define IS_FILE_SEPARATOR(c) ((c) == '/')
+#ifndef MAXNAMELEN
+#define MAXNAMELEN PATH_MAX
+#endif
+
+#ifdef JAVA_ARGS
+/*
+ * ApplicationHome is prepended to each of these entries; the resulting
+ * strings are concatenated (separated by PATH_SEPARATOR) and used as the
+ * value of -cp option to the launcher.
+ */
+#ifndef APP_CLASSPATH
+#define APP_CLASSPATH { "/lib/tools.jar", "/classes" }
+#endif
+#endif
+
+#ifdef HAVE_GETHRTIME
+/*
+ * Support for doing cheap, accurate interval timing.
+ */
+#include <sys/time.h>
+#define CounterGet() (gethrtime()/1000)
+#define Counter2Micros(counts) (counts)
+#else
+#define CounterGet() (0)
+#define Counter2Micros(counts) (1)
+#endif /* HAVE_GETHRTIME */
+
+/*
+ * Function prototypes.
+ */
+char *LocateJRE(manifest_info *info);
+void ExecJRE(char *jre, char **argv);
+int UnsetEnv(char *name);
+
+#endif
diff --git a/launcher/jli_util.h b/launcher/jli_util.h
new file mode 100644
index 0000000..d50d5c1
--- /dev/null
+++ b/launcher/jli_util.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JLI_UTIL_H
+#define _JLI_UTIL_H
+
+#include <stdlib.h>
+
+void *JLI_MemAlloc(size_t size);
+void *JLI_MemRealloc(void *ptr, size_t size);
+char *JLI_StringDup(const char *s1);
+void JLI_MemFree(void *ptr);
+
+#endif /* _JLI_UTIL_H */
diff --git a/launcher/jni.h b/launcher/jni.h
new file mode 100644
index 0000000..dc2c8f6
--- /dev/null
+++ b/launcher/jni.h
@@ -0,0 +1,1959 @@
+/*
+ * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * We used part of Netscape's Java Runtime Interface (JRI) as the starting
+ * point of our design and implementation.
+ */
+
+/******************************************************************************
+ * Java Runtime Interface
+ * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved.
+ *****************************************************************************/
+
+#ifndef _JAVASOFT_JNI_H_
+#define _JAVASOFT_JNI_H_
+
+#include <stdio.h>
+#include <stdarg.h>
+
+/* jni_md.h contains the machine-dependent typedefs for jbyte, jint
+ and jlong */
+
+#include "jni_md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * JNI Types
+ */
+
+#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H
+
+typedef unsigned char jboolean;
+typedef unsigned short jchar;
+typedef short jshort;
+typedef float jfloat;
+typedef double jdouble;
+
+typedef jint jsize;
+
+#ifdef __cplusplus
+
+class _jobject {};
+class _jclass : public _jobject {};
+class _jthrowable : public _jobject {};
+class _jstring : public _jobject {};
+class _jarray : public _jobject {};
+class _jbooleanArray : public _jarray {};
+class _jbyteArray : public _jarray {};
+class _jcharArray : public _jarray {};
+class _jshortArray : public _jarray {};
+class _jintArray : public _jarray {};
+class _jlongArray : public _jarray {};
+class _jfloatArray : public _jarray {};
+class _jdoubleArray : public _jarray {};
+class _jobjectArray : public _jarray {};
+
+typedef _jobject *jobject;
+typedef _jclass *jclass;
+typedef _jthrowable *jthrowable;
+typedef _jstring *jstring;
+typedef _jarray *jarray;
+typedef _jbooleanArray *jbooleanArray;
+typedef _jbyteArray *jbyteArray;
+typedef _jcharArray *jcharArray;
+typedef _jshortArray *jshortArray;
+typedef _jintArray *jintArray;
+typedef _jlongArray *jlongArray;
+typedef _jfloatArray *jfloatArray;
+typedef _jdoubleArray *jdoubleArray;
+typedef _jobjectArray *jobjectArray;
+
+#else
+
+struct _jobject;
+
+typedef struct _jobject *jobject;
+typedef jobject jclass;
+typedef jobject jthrowable;
+typedef jobject jstring;
+typedef jobject jarray;
+typedef jarray jbooleanArray;
+typedef jarray jbyteArray;
+typedef jarray jcharArray;
+typedef jarray jshortArray;
+typedef jarray jintArray;
+typedef jarray jlongArray;
+typedef jarray jfloatArray;
+typedef jarray jdoubleArray;
+typedef jarray jobjectArray;
+
+#endif
+
+typedef jobject jweak;
+
+typedef union jvalue {
+ jboolean z;
+ jbyte b;
+ jchar c;
+ jshort s;
+ jint i;
+ jlong j;
+ jfloat f;
+ jdouble d;
+ jobject l;
+} jvalue;
+
+struct _jfieldID;
+typedef struct _jfieldID *jfieldID;
+
+struct _jmethodID;
+typedef struct _jmethodID *jmethodID;
+
+/* Return values from jobjectRefType */
+typedef enum _jobjectType {
+ JNIInvalidRefType = 0,
+ JNILocalRefType = 1,
+ JNIGlobalRefType = 2,
+ JNIWeakGlobalRefType = 3
+} jobjectRefType;
+
+
+#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */
+
+/*
+ * jboolean constants
+ */
+
+#define JNI_FALSE 0
+#define JNI_TRUE 1
+
+/*
+ * possible return values for JNI functions.
+ */
+
+#define JNI_OK 0 /* success */
+#define JNI_ERR (-1) /* unknown error */
+#define JNI_EDETACHED (-2) /* thread detached from the VM */
+#define JNI_EVERSION (-3) /* JNI version error */
+#define JNI_ENOMEM (-4) /* not enough memory */
+#define JNI_EEXIST (-5) /* VM already created */
+#define JNI_EINVAL (-6) /* invalid arguments */
+
+/*
+ * used in ReleaseScalarArrayElements
+ */
+
+#define JNI_COMMIT 1
+#define JNI_ABORT 2
+
+/*
+ * used in RegisterNatives to describe native method name, signature,
+ * and function pointer.
+ */
+
+typedef struct {
+ char *name;
+ char *signature;
+ void *fnPtr;
+} JNINativeMethod;
+
+/*
+ * JNI Native Method Interface.
+ */
+
+struct JNINativeInterface_;
+
+struct JNIEnv_;
+
+#ifdef __cplusplus
+typedef JNIEnv_ JNIEnv;
+#else
+typedef const struct JNINativeInterface_ *JNIEnv;
+#endif
+
+/*
+ * JNI Invocation Interface.
+ */
+
+struct JNIInvokeInterface_;
+
+struct JavaVM_;
+
+#ifdef __cplusplus
+typedef JavaVM_ JavaVM;
+#else
+typedef const struct JNIInvokeInterface_ *JavaVM;
+#endif
+
+struct JNINativeInterface_ {
+ void *reserved0;
+ void *reserved1;
+ void *reserved2;
+
+ void *reserved3;
+ jint (JNICALL *GetVersion)(JNIEnv *env);
+
+ jclass (JNICALL *DefineClass)
+ (JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
+ jsize len);
+ jclass (JNICALL *FindClass)
+ (JNIEnv *env, const char *name);
+
+ jmethodID (JNICALL *FromReflectedMethod)
+ (JNIEnv *env, jobject method);
+ jfieldID (JNICALL *FromReflectedField)
+ (JNIEnv *env, jobject field);
+
+ jobject (JNICALL *ToReflectedMethod)
+ (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic);
+
+ jclass (JNICALL *GetSuperclass)
+ (JNIEnv *env, jclass sub);
+ jboolean (JNICALL *IsAssignableFrom)
+ (JNIEnv *env, jclass sub, jclass sup);
+
+ jobject (JNICALL *ToReflectedField)
+ (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic);
+
+ jint (JNICALL *Throw)
+ (JNIEnv *env, jthrowable obj);
+ jint (JNICALL *ThrowNew)
+ (JNIEnv *env, jclass clazz, const char *msg);
+ jthrowable (JNICALL *ExceptionOccurred)
+ (JNIEnv *env);
+ void (JNICALL *ExceptionDescribe)
+ (JNIEnv *env);
+ void (JNICALL *ExceptionClear)
+ (JNIEnv *env);
+ void (JNICALL *FatalError)
+ (JNIEnv *env, const char *msg);
+
+ jint (JNICALL *PushLocalFrame)
+ (JNIEnv *env, jint capacity);
+ jobject (JNICALL *PopLocalFrame)
+ (JNIEnv *env, jobject result);
+
+ jobject (JNICALL *NewGlobalRef)
+ (JNIEnv *env, jobject lobj);
+ void (JNICALL *DeleteGlobalRef)
+ (JNIEnv *env, jobject gref);
+ void (JNICALL *DeleteLocalRef)
+ (JNIEnv *env, jobject obj);
+ jboolean (JNICALL *IsSameObject)
+ (JNIEnv *env, jobject obj1, jobject obj2);
+ jobject (JNICALL *NewLocalRef)
+ (JNIEnv *env, jobject ref);
+ jint (JNICALL *EnsureLocalCapacity)
+ (JNIEnv *env, jint capacity);
+
+ jobject (JNICALL *AllocObject)
+ (JNIEnv *env, jclass clazz);
+ jobject (JNICALL *NewObject)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *NewObjectV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jobject (JNICALL *NewObjectA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jclass (JNICALL *GetObjectClass)
+ (JNIEnv *env, jobject obj);
+ jboolean (JNICALL *IsInstanceOf)
+ (JNIEnv *env, jobject obj, jclass clazz);
+
+ jmethodID (JNICALL *GetMethodID)
+ (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *CallObjectMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jobject (JNICALL *CallObjectMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jobject (JNICALL *CallObjectMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
+
+ jboolean (JNICALL *CallBooleanMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jboolean (JNICALL *CallBooleanMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jboolean (JNICALL *CallBooleanMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
+
+ jbyte (JNICALL *CallByteMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jbyte (JNICALL *CallByteMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jbyte (JNICALL *CallByteMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+ jchar (JNICALL *CallCharMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jchar (JNICALL *CallCharMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jchar (JNICALL *CallCharMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+ jshort (JNICALL *CallShortMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jshort (JNICALL *CallShortMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jshort (JNICALL *CallShortMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+ jint (JNICALL *CallIntMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jint (JNICALL *CallIntMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jint (JNICALL *CallIntMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+ jlong (JNICALL *CallLongMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jlong (JNICALL *CallLongMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jlong (JNICALL *CallLongMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+ jfloat (JNICALL *CallFloatMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jfloat (JNICALL *CallFloatMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jfloat (JNICALL *CallFloatMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+ jdouble (JNICALL *CallDoubleMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jdouble (JNICALL *CallDoubleMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jdouble (JNICALL *CallDoubleMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+ void (JNICALL *CallVoidMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ void (JNICALL *CallVoidMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ void (JNICALL *CallVoidMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
+
+ jobject (JNICALL *CallNonvirtualObjectMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *CallNonvirtualObjectMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jobject (JNICALL *CallNonvirtualObjectMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue * args);
+
+ jboolean (JNICALL *CallNonvirtualBooleanMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jboolean (JNICALL *CallNonvirtualBooleanMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jboolean (JNICALL *CallNonvirtualBooleanMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue * args);
+
+ jbyte (JNICALL *CallNonvirtualByteMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jbyte (JNICALL *CallNonvirtualByteMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jbyte (JNICALL *CallNonvirtualByteMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue *args);
+
+ jchar (JNICALL *CallNonvirtualCharMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jchar (JNICALL *CallNonvirtualCharMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jchar (JNICALL *CallNonvirtualCharMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue *args);
+
+ jshort (JNICALL *CallNonvirtualShortMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jshort (JNICALL *CallNonvirtualShortMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jshort (JNICALL *CallNonvirtualShortMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue *args);
+
+ jint (JNICALL *CallNonvirtualIntMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jint (JNICALL *CallNonvirtualIntMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jint (JNICALL *CallNonvirtualIntMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue *args);
+
+ jlong (JNICALL *CallNonvirtualLongMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jlong (JNICALL *CallNonvirtualLongMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jlong (JNICALL *CallNonvirtualLongMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue *args);
+
+ jfloat (JNICALL *CallNonvirtualFloatMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jfloat (JNICALL *CallNonvirtualFloatMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jfloat (JNICALL *CallNonvirtualFloatMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue *args);
+
+ jdouble (JNICALL *CallNonvirtualDoubleMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jdouble (JNICALL *CallNonvirtualDoubleMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jdouble (JNICALL *CallNonvirtualDoubleMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue *args);
+
+ void (JNICALL *CallNonvirtualVoidMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ void (JNICALL *CallNonvirtualVoidMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ void (JNICALL *CallNonvirtualVoidMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ const jvalue * args);
+
+ jfieldID (JNICALL *GetFieldID)
+ (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *GetObjectField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jboolean (JNICALL *GetBooleanField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jbyte (JNICALL *GetByteField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jchar (JNICALL *GetCharField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jshort (JNICALL *GetShortField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jint (JNICALL *GetIntField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jlong (JNICALL *GetLongField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jfloat (JNICALL *GetFloatField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jdouble (JNICALL *GetDoubleField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+
+ void (JNICALL *SetObjectField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val);
+ void (JNICALL *SetBooleanField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val);
+ void (JNICALL *SetByteField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val);
+ void (JNICALL *SetCharField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val);
+ void (JNICALL *SetShortField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val);
+ void (JNICALL *SetIntField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jint val);
+ void (JNICALL *SetLongField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val);
+ void (JNICALL *SetFloatField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val);
+ void (JNICALL *SetDoubleField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val);
+
+ jmethodID (JNICALL *GetStaticMethodID)
+ (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *CallStaticObjectMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *CallStaticObjectMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jobject (JNICALL *CallStaticObjectMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jboolean (JNICALL *CallStaticBooleanMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jboolean (JNICALL *CallStaticBooleanMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jboolean (JNICALL *CallStaticBooleanMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jbyte (JNICALL *CallStaticByteMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jbyte (JNICALL *CallStaticByteMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jbyte (JNICALL *CallStaticByteMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jchar (JNICALL *CallStaticCharMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jchar (JNICALL *CallStaticCharMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jchar (JNICALL *CallStaticCharMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jshort (JNICALL *CallStaticShortMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jshort (JNICALL *CallStaticShortMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jshort (JNICALL *CallStaticShortMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jint (JNICALL *CallStaticIntMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jint (JNICALL *CallStaticIntMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jint (JNICALL *CallStaticIntMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jlong (JNICALL *CallStaticLongMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jlong (JNICALL *CallStaticLongMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jlong (JNICALL *CallStaticLongMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jfloat (JNICALL *CallStaticFloatMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jfloat (JNICALL *CallStaticFloatMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jfloat (JNICALL *CallStaticFloatMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ jdouble (JNICALL *CallStaticDoubleMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jdouble (JNICALL *CallStaticDoubleMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jdouble (JNICALL *CallStaticDoubleMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+ void (JNICALL *CallStaticVoidMethod)
+ (JNIEnv *env, jclass cls, jmethodID methodID, ...);
+ void (JNICALL *CallStaticVoidMethodV)
+ (JNIEnv *env, jclass cls, jmethodID methodID, va_list args);
+ void (JNICALL *CallStaticVoidMethodA)
+ (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args);
+
+ jfieldID (JNICALL *GetStaticFieldID)
+ (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+ jobject (JNICALL *GetStaticObjectField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jboolean (JNICALL *GetStaticBooleanField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jbyte (JNICALL *GetStaticByteField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jchar (JNICALL *GetStaticCharField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jshort (JNICALL *GetStaticShortField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jint (JNICALL *GetStaticIntField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jlong (JNICALL *GetStaticLongField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jfloat (JNICALL *GetStaticFloatField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jdouble (JNICALL *GetStaticDoubleField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+
+ void (JNICALL *SetStaticObjectField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value);
+ void (JNICALL *SetStaticBooleanField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value);
+ void (JNICALL *SetStaticByteField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value);
+ void (JNICALL *SetStaticCharField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value);
+ void (JNICALL *SetStaticShortField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value);
+ void (JNICALL *SetStaticIntField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value);
+ void (JNICALL *SetStaticLongField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value);
+ void (JNICALL *SetStaticFloatField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value);
+ void (JNICALL *SetStaticDoubleField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value);
+
+ jstring (JNICALL *NewString)
+ (JNIEnv *env, const jchar *unicode, jsize len);
+ jsize (JNICALL *GetStringLength)
+ (JNIEnv *env, jstring str);
+ const jchar *(JNICALL *GetStringChars)
+ (JNIEnv *env, jstring str, jboolean *isCopy);
+ void (JNICALL *ReleaseStringChars)
+ (JNIEnv *env, jstring str, const jchar *chars);
+
+ jstring (JNICALL *NewStringUTF)
+ (JNIEnv *env, const char *utf);
+ jsize (JNICALL *GetStringUTFLength)
+ (JNIEnv *env, jstring str);
+ const char* (JNICALL *GetStringUTFChars)
+ (JNIEnv *env, jstring str, jboolean *isCopy);
+ void (JNICALL *ReleaseStringUTFChars)
+ (JNIEnv *env, jstring str, const char* chars);
+
+
+ jsize (JNICALL *GetArrayLength)
+ (JNIEnv *env, jarray array);
+
+ jobjectArray (JNICALL *NewObjectArray)
+ (JNIEnv *env, jsize len, jclass clazz, jobject init);
+ jobject (JNICALL *GetObjectArrayElement)
+ (JNIEnv *env, jobjectArray array, jsize index);
+ void (JNICALL *SetObjectArrayElement)
+ (JNIEnv *env, jobjectArray array, jsize index, jobject val);
+
+ jbooleanArray (JNICALL *NewBooleanArray)
+ (JNIEnv *env, jsize len);
+ jbyteArray (JNICALL *NewByteArray)
+ (JNIEnv *env, jsize len);
+ jcharArray (JNICALL *NewCharArray)
+ (JNIEnv *env, jsize len);
+ jshortArray (JNICALL *NewShortArray)
+ (JNIEnv *env, jsize len);
+ jintArray (JNICALL *NewIntArray)
+ (JNIEnv *env, jsize len);
+ jlongArray (JNICALL *NewLongArray)
+ (JNIEnv *env, jsize len);
+ jfloatArray (JNICALL *NewFloatArray)
+ (JNIEnv *env, jsize len);
+ jdoubleArray (JNICALL *NewDoubleArray)
+ (JNIEnv *env, jsize len);
+
+ jboolean * (JNICALL *GetBooleanArrayElements)
+ (JNIEnv *env, jbooleanArray array, jboolean *isCopy);
+ jbyte * (JNICALL *GetByteArrayElements)
+ (JNIEnv *env, jbyteArray array, jboolean *isCopy);
+ jchar * (JNICALL *GetCharArrayElements)
+ (JNIEnv *env, jcharArray array, jboolean *isCopy);
+ jshort * (JNICALL *GetShortArrayElements)
+ (JNIEnv *env, jshortArray array, jboolean *isCopy);
+ jint * (JNICALL *GetIntArrayElements)
+ (JNIEnv *env, jintArray array, jboolean *isCopy);
+ jlong * (JNICALL *GetLongArrayElements)
+ (JNIEnv *env, jlongArray array, jboolean *isCopy);
+ jfloat * (JNICALL *GetFloatArrayElements)
+ (JNIEnv *env, jfloatArray array, jboolean *isCopy);
+ jdouble * (JNICALL *GetDoubleArrayElements)
+ (JNIEnv *env, jdoubleArray array, jboolean *isCopy);
+
+ void (JNICALL *ReleaseBooleanArrayElements)
+ (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode);
+ void (JNICALL *ReleaseByteArrayElements)
+ (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode);
+ void (JNICALL *ReleaseCharArrayElements)
+ (JNIEnv *env, jcharArray array, jchar *elems, jint mode);
+ void (JNICALL *ReleaseShortArrayElements)
+ (JNIEnv *env, jshortArray array, jshort *elems, jint mode);
+ void (JNICALL *ReleaseIntArrayElements)
+ (JNIEnv *env, jintArray array, jint *elems, jint mode);
+ void (JNICALL *ReleaseLongArrayElements)
+ (JNIEnv *env, jlongArray array, jlong *elems, jint mode);
+ void (JNICALL *ReleaseFloatArrayElements)
+ (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode);
+ void (JNICALL *ReleaseDoubleArrayElements)
+ (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode);
+
+ void (JNICALL *GetBooleanArrayRegion)
+ (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ void (JNICALL *GetByteArrayRegion)
+ (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf);
+ void (JNICALL *GetCharArrayRegion)
+ (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf);
+ void (JNICALL *GetShortArrayRegion)
+ (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf);
+ void (JNICALL *GetIntArrayRegion)
+ (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf);
+ void (JNICALL *GetLongArrayRegion)
+ (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf);
+ void (JNICALL *GetFloatArrayRegion)
+ (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf);
+ void (JNICALL *GetDoubleArrayRegion)
+ (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ void (JNICALL *SetBooleanArrayRegion)
+ (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf);
+ void (JNICALL *SetByteArrayRegion)
+ (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf);
+ void (JNICALL *SetCharArrayRegion)
+ (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf);
+ void (JNICALL *SetShortArrayRegion)
+ (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf);
+ void (JNICALL *SetIntArrayRegion)
+ (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf);
+ void (JNICALL *SetLongArrayRegion)
+ (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf);
+ void (JNICALL *SetFloatArrayRegion)
+ (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf);
+ void (JNICALL *SetDoubleArrayRegion)
+ (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf);
+
+ jint (JNICALL *RegisterNatives)
+ (JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
+ jint nMethods);
+ jint (JNICALL *UnregisterNatives)
+ (JNIEnv *env, jclass clazz);
+
+ jint (JNICALL *MonitorEnter)
+ (JNIEnv *env, jobject obj);
+ jint (JNICALL *MonitorExit)
+ (JNIEnv *env, jobject obj);
+
+ jint (JNICALL *GetJavaVM)
+ (JNIEnv *env, JavaVM **vm);
+
+ void (JNICALL *GetStringRegion)
+ (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);
+ void (JNICALL *GetStringUTFRegion)
+ (JNIEnv *env, jstring str, jsize start, jsize len, char *buf);
+
+ void * (JNICALL *GetPrimitiveArrayCritical)
+ (JNIEnv *env, jarray array, jboolean *isCopy);
+ void (JNICALL *ReleasePrimitiveArrayCritical)
+ (JNIEnv *env, jarray array, void *carray, jint mode);
+
+ const jchar * (JNICALL *GetStringCritical)
+ (JNIEnv *env, jstring string, jboolean *isCopy);
+ void (JNICALL *ReleaseStringCritical)
+ (JNIEnv *env, jstring string, const jchar *cstring);
+
+ jweak (JNICALL *NewWeakGlobalRef)
+ (JNIEnv *env, jobject obj);
+ void (JNICALL *DeleteWeakGlobalRef)
+ (JNIEnv *env, jweak ref);
+
+ jboolean (JNICALL *ExceptionCheck)
+ (JNIEnv *env);
+
+ jobject (JNICALL *NewDirectByteBuffer)
+ (JNIEnv* env, void* address, jlong capacity);
+ void* (JNICALL *GetDirectBufferAddress)
+ (JNIEnv* env, jobject buf);
+ jlong (JNICALL *GetDirectBufferCapacity)
+ (JNIEnv* env, jobject buf);
+
+ /* New JNI 1.6 Features */
+
+ jobjectRefType (JNICALL *GetObjectRefType)
+ (JNIEnv* env, jobject obj);
+};
+
+/*
+ * We use inlined functions for C++ so that programmers can write:
+ *
+ * env->FindClass("java/lang/String")
+ *
+ * in C++ rather than:
+ *
+ * (*env)->FindClass(env, "java/lang/String")
+ *
+ * in C.
+ */
+
+struct JNIEnv_ {
+ const struct JNINativeInterface_ *functions;
+#ifdef __cplusplus
+
+ jint GetVersion() {
+ return functions->GetVersion(this);
+ }
+ jclass DefineClass(const char *name, jobject loader, const jbyte *buf,
+ jsize len) {
+ return functions->DefineClass(this, name, loader, buf, len);
+ }
+ jclass FindClass(const char *name) {
+ return functions->FindClass(this, name);
+ }
+ jmethodID FromReflectedMethod(jobject method) {
+ return functions->FromReflectedMethod(this,method);
+ }
+ jfieldID FromReflectedField(jobject field) {
+ return functions->FromReflectedField(this,field);
+ }
+
+ jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) {
+ return functions->ToReflectedMethod(this, cls, methodID, isStatic);
+ }
+
+ jclass GetSuperclass(jclass sub) {
+ return functions->GetSuperclass(this, sub);
+ }
+ jboolean IsAssignableFrom(jclass sub, jclass sup) {
+ return functions->IsAssignableFrom(this, sub, sup);
+ }
+
+ jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) {
+ return functions->ToReflectedField(this,cls,fieldID,isStatic);
+ }
+
+ jint Throw(jthrowable obj) {
+ return functions->Throw(this, obj);
+ }
+ jint ThrowNew(jclass clazz, const char *msg) {
+ return functions->ThrowNew(this, clazz, msg);
+ }
+ jthrowable ExceptionOccurred() {
+ return functions->ExceptionOccurred(this);
+ }
+ void ExceptionDescribe() {
+ functions->ExceptionDescribe(this);
+ }
+ void ExceptionClear() {
+ functions->ExceptionClear(this);
+ }
+ void FatalError(const char *msg) {
+ functions->FatalError(this, msg);
+ }
+
+ jint PushLocalFrame(jint capacity) {
+ return functions->PushLocalFrame(this,capacity);
+ }
+ jobject PopLocalFrame(jobject result) {
+ return functions->PopLocalFrame(this,result);
+ }
+
+ jobject NewGlobalRef(jobject lobj) {
+ return functions->NewGlobalRef(this,lobj);
+ }
+ void DeleteGlobalRef(jobject gref) {
+ functions->DeleteGlobalRef(this,gref);
+ }
+ void DeleteLocalRef(jobject obj) {
+ functions->DeleteLocalRef(this, obj);
+ }
+
+ jboolean IsSameObject(jobject obj1, jobject obj2) {
+ return functions->IsSameObject(this,obj1,obj2);
+ }
+
+ jobject NewLocalRef(jobject ref) {
+ return functions->NewLocalRef(this,ref);
+ }
+ jint EnsureLocalCapacity(jint capacity) {
+ return functions->EnsureLocalCapacity(this,capacity);
+ }
+
+ jobject AllocObject(jclass clazz) {
+ return functions->AllocObject(this,clazz);
+ }
+ jobject NewObject(jclass clazz, jmethodID methodID, ...) {
+ va_list args;
+ jobject result;
+ va_start(args, methodID);
+ result = functions->NewObjectV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jobject NewObjectV(jclass clazz, jmethodID methodID,
+ va_list args) {
+ return functions->NewObjectV(this,clazz,methodID,args);
+ }
+ jobject NewObjectA(jclass clazz, jmethodID methodID,
+ const jvalue *args) {
+ return functions->NewObjectA(this,clazz,methodID,args);
+ }
+
+ jclass GetObjectClass(jobject obj) {
+ return functions->GetObjectClass(this,obj);
+ }
+ jboolean IsInstanceOf(jobject obj, jclass clazz) {
+ return functions->IsInstanceOf(this,obj,clazz);
+ }
+
+ jmethodID GetMethodID(jclass clazz, const char *name,
+ const char *sig) {
+ return functions->GetMethodID(this,clazz,name,sig);
+ }
+
+ jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jobject result;
+ va_start(args,methodID);
+ result = functions->CallObjectMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jobject CallObjectMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallObjectMethodV(this,obj,methodID,args);
+ }
+ jobject CallObjectMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallObjectMethodA(this,obj,methodID,args);
+ }
+
+ jboolean CallBooleanMethod(jobject obj,
+ jmethodID methodID, ...) {
+ va_list args;
+ jboolean result;
+ va_start(args,methodID);
+ result = functions->CallBooleanMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jboolean CallBooleanMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallBooleanMethodV(this,obj,methodID,args);
+ }
+ jboolean CallBooleanMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallBooleanMethodA(this,obj,methodID, args);
+ }
+
+ jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jbyte result;
+ va_start(args,methodID);
+ result = functions->CallByteMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jbyte CallByteMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallByteMethodV(this,obj,methodID,args);
+ }
+ jbyte CallByteMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallByteMethodA(this,obj,methodID,args);
+ }
+
+ jchar CallCharMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jchar result;
+ va_start(args,methodID);
+ result = functions->CallCharMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jchar CallCharMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallCharMethodV(this,obj,methodID,args);
+ }
+ jchar CallCharMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallCharMethodA(this,obj,methodID,args);
+ }
+
+ jshort CallShortMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jshort result;
+ va_start(args,methodID);
+ result = functions->CallShortMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jshort CallShortMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallShortMethodV(this,obj,methodID,args);
+ }
+ jshort CallShortMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallShortMethodA(this,obj,methodID,args);
+ }
+
+ jint CallIntMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jint result;
+ va_start(args,methodID);
+ result = functions->CallIntMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jint CallIntMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallIntMethodV(this,obj,methodID,args);
+ }
+ jint CallIntMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallIntMethodA(this,obj,methodID,args);
+ }
+
+ jlong CallLongMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jlong result;
+ va_start(args,methodID);
+ result = functions->CallLongMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jlong CallLongMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallLongMethodV(this,obj,methodID,args);
+ }
+ jlong CallLongMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallLongMethodA(this,obj,methodID,args);
+ }
+
+ jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jfloat result;
+ va_start(args,methodID);
+ result = functions->CallFloatMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jfloat CallFloatMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallFloatMethodV(this,obj,methodID,args);
+ }
+ jfloat CallFloatMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallFloatMethodA(this,obj,methodID,args);
+ }
+
+ jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jdouble result;
+ va_start(args,methodID);
+ result = functions->CallDoubleMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jdouble CallDoubleMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallDoubleMethodV(this,obj,methodID,args);
+ }
+ jdouble CallDoubleMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallDoubleMethodA(this,obj,methodID,args);
+ }
+
+ void CallVoidMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ va_start(args,methodID);
+ functions->CallVoidMethodV(this,obj,methodID,args);
+ va_end(args);
+ }
+ void CallVoidMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ functions->CallVoidMethodV(this,obj,methodID,args);
+ }
+ void CallVoidMethodA(jobject obj, jmethodID methodID,
+ const jvalue * args) {
+ functions->CallVoidMethodA(this,obj,methodID,args);
+ }
+
+ jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jobject result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualObjectMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualObjectMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, const jvalue * args) {
+ return functions->CallNonvirtualObjectMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jboolean result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualBooleanMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, const jvalue * args) {
+ return functions->CallNonvirtualBooleanMethodA(this,obj,clazz,
+ methodID, args);
+ }
+
+ jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jbyte result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualByteMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualByteMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, const jvalue * args) {
+ return functions->CallNonvirtualByteMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jchar CallNonvirtualCharMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jchar result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualCharMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualCharMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, const jvalue * args) {
+ return functions->CallNonvirtualCharMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jshort CallNonvirtualShortMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jshort result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualShortMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualShortMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, const jvalue * args) {
+ return functions->CallNonvirtualShortMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jint CallNonvirtualIntMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jint result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualIntMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jint CallNonvirtualIntMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualIntMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jint CallNonvirtualIntMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, const jvalue * args) {
+ return functions->CallNonvirtualIntMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jlong CallNonvirtualLongMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jlong result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualLongMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualLongMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, const jvalue * args) {
+ return functions->CallNonvirtualLongMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jfloat result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualFloatMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz,
+ jmethodID methodID,
+ va_list args) {
+ return functions->CallNonvirtualFloatMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz,
+ jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallNonvirtualFloatMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jdouble result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz,
+ jmethodID methodID,
+ va_list args) {
+ return functions->CallNonvirtualDoubleMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz,
+ jmethodID methodID,
+ const jvalue * args) {
+ return functions->CallNonvirtualDoubleMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ va_start(args,methodID);
+ functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args);
+ va_end(args);
+ }
+ void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
+ jmethodID methodID,
+ va_list args) {
+ functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args);
+ }
+ void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
+ jmethodID methodID,
+ const jvalue * args) {
+ functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args);
+ }
+
+ jfieldID GetFieldID(jclass clazz, const char *name,
+ const char *sig) {
+ return functions->GetFieldID(this,clazz,name,sig);
+ }
+
+ jobject GetObjectField(jobject obj, jfieldID fieldID) {
+ return functions->GetObjectField(this,obj,fieldID);
+ }
+ jboolean GetBooleanField(jobject obj, jfieldID fieldID) {
+ return functions->GetBooleanField(this,obj,fieldID);
+ }
+ jbyte GetByteField(jobject obj, jfieldID fieldID) {
+ return functions->GetByteField(this,obj,fieldID);
+ }
+ jchar GetCharField(jobject obj, jfieldID fieldID) {
+ return functions->GetCharField(this,obj,fieldID);
+ }
+ jshort GetShortField(jobject obj, jfieldID fieldID) {
+ return functions->GetShortField(this,obj,fieldID);
+ }
+ jint GetIntField(jobject obj, jfieldID fieldID) {
+ return functions->GetIntField(this,obj,fieldID);
+ }
+ jlong GetLongField(jobject obj, jfieldID fieldID) {
+ return functions->GetLongField(this,obj,fieldID);
+ }
+ jfloat GetFloatField(jobject obj, jfieldID fieldID) {
+ return functions->GetFloatField(this,obj,fieldID);
+ }
+ jdouble GetDoubleField(jobject obj, jfieldID fieldID) {
+ return functions->GetDoubleField(this,obj,fieldID);
+ }
+
+ void SetObjectField(jobject obj, jfieldID fieldID, jobject val) {
+ functions->SetObjectField(this,obj,fieldID,val);
+ }
+ void SetBooleanField(jobject obj, jfieldID fieldID,
+ jboolean val) {
+ functions->SetBooleanField(this,obj,fieldID,val);
+ }
+ void SetByteField(jobject obj, jfieldID fieldID,
+ jbyte val) {
+ functions->SetByteField(this,obj,fieldID,val);
+ }
+ void SetCharField(jobject obj, jfieldID fieldID,
+ jchar val) {
+ functions->SetCharField(this,obj,fieldID,val);
+ }
+ void SetShortField(jobject obj, jfieldID fieldID,
+ jshort val) {
+ functions->SetShortField(this,obj,fieldID,val);
+ }
+ void SetIntField(jobject obj, jfieldID fieldID,
+ jint val) {
+ functions->SetIntField(this,obj,fieldID,val);
+ }
+ void SetLongField(jobject obj, jfieldID fieldID,
+ jlong val) {
+ functions->SetLongField(this,obj,fieldID,val);
+ }
+ void SetFloatField(jobject obj, jfieldID fieldID,
+ jfloat val) {
+ functions->SetFloatField(this,obj,fieldID,val);
+ }
+ void SetDoubleField(jobject obj, jfieldID fieldID,
+ jdouble val) {
+ functions->SetDoubleField(this,obj,fieldID,val);
+ }
+
+ jmethodID GetStaticMethodID(jclass clazz, const char *name,
+ const char *sig) {
+ return functions->GetStaticMethodID(this,clazz,name,sig);
+ }
+
+ jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID,
+ ...) {
+ va_list args;
+ jobject result;
+ va_start(args,methodID);
+ result = functions->CallStaticObjectMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID,
+ va_list args) {
+ return functions->CallStaticObjectMethodV(this,clazz,methodID,args);
+ }
+ jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID,
+ const jvalue *args) {
+ return functions->CallStaticObjectMethodA(this,clazz,methodID,args);
+ }
+
+ jboolean CallStaticBooleanMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jboolean result;
+ va_start(args,methodID);
+ result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jboolean CallStaticBooleanMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticBooleanMethodV(this,clazz,methodID,args);
+ }
+ jboolean CallStaticBooleanMethodA(jclass clazz,
+ jmethodID methodID, const jvalue *args) {
+ return functions->CallStaticBooleanMethodA(this,clazz,methodID,args);
+ }
+
+ jbyte CallStaticByteMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jbyte result;
+ va_start(args,methodID);
+ result = functions->CallStaticByteMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jbyte CallStaticByteMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticByteMethodV(this,clazz,methodID,args);
+ }
+ jbyte CallStaticByteMethodA(jclass clazz,
+ jmethodID methodID, const jvalue *args) {
+ return functions->CallStaticByteMethodA(this,clazz,methodID,args);
+ }
+
+ jchar CallStaticCharMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jchar result;
+ va_start(args,methodID);
+ result = functions->CallStaticCharMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jchar CallStaticCharMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticCharMethodV(this,clazz,methodID,args);
+ }
+ jchar CallStaticCharMethodA(jclass clazz,
+ jmethodID methodID, const jvalue *args) {
+ return functions->CallStaticCharMethodA(this,clazz,methodID,args);
+ }
+
+ jshort CallStaticShortMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jshort result;
+ va_start(args,methodID);
+ result = functions->CallStaticShortMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jshort CallStaticShortMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticShortMethodV(this,clazz,methodID,args);
+ }
+ jshort CallStaticShortMethodA(jclass clazz,
+ jmethodID methodID, const jvalue *args) {
+ return functions->CallStaticShortMethodA(this,clazz,methodID,args);
+ }
+
+ jint CallStaticIntMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jint result;
+ va_start(args,methodID);
+ result = functions->CallStaticIntMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jint CallStaticIntMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticIntMethodV(this,clazz,methodID,args);
+ }
+ jint CallStaticIntMethodA(jclass clazz,
+ jmethodID methodID, const jvalue *args) {
+ return functions->CallStaticIntMethodA(this,clazz,methodID,args);
+ }
+
+ jlong CallStaticLongMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jlong result;
+ va_start(args,methodID);
+ result = functions->CallStaticLongMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jlong CallStaticLongMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticLongMethodV(this,clazz,methodID,args);
+ }
+ jlong CallStaticLongMethodA(jclass clazz,
+ jmethodID methodID, const jvalue *args) {
+ return functions->CallStaticLongMethodA(this,clazz,methodID,args);
+ }
+
+ jfloat CallStaticFloatMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jfloat result;
+ va_start(args,methodID);
+ result = functions->CallStaticFloatMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jfloat CallStaticFloatMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticFloatMethodV(this,clazz,methodID,args);
+ }
+ jfloat CallStaticFloatMethodA(jclass clazz,
+ jmethodID methodID, const jvalue *args) {
+ return functions->CallStaticFloatMethodA(this,clazz,methodID,args);
+ }
+
+ jdouble CallStaticDoubleMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jdouble result;
+ va_start(args,methodID);
+ result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jdouble CallStaticDoubleMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticDoubleMethodV(this,clazz,methodID,args);
+ }
+ jdouble CallStaticDoubleMethodA(jclass clazz,
+ jmethodID methodID, const jvalue *args) {
+ return functions->CallStaticDoubleMethodA(this,clazz,methodID,args);
+ }
+
+ void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) {
+ va_list args;
+ va_start(args,methodID);
+ functions->CallStaticVoidMethodV(this,cls,methodID,args);
+ va_end(args);
+ }
+ void CallStaticVoidMethodV(jclass cls, jmethodID methodID,
+ va_list args) {
+ functions->CallStaticVoidMethodV(this,cls,methodID,args);
+ }
+ void CallStaticVoidMethodA(jclass cls, jmethodID methodID,
+ const jvalue * args) {
+ functions->CallStaticVoidMethodA(this,cls,methodID,args);
+ }
+
+ jfieldID GetStaticFieldID(jclass clazz, const char *name,
+ const char *sig) {
+ return functions->GetStaticFieldID(this,clazz,name,sig);
+ }
+ jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticObjectField(this,clazz,fieldID);
+ }
+ jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticBooleanField(this,clazz,fieldID);
+ }
+ jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticByteField(this,clazz,fieldID);
+ }
+ jchar GetStaticCharField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticCharField(this,clazz,fieldID);
+ }
+ jshort GetStaticShortField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticShortField(this,clazz,fieldID);
+ }
+ jint GetStaticIntField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticIntField(this,clazz,fieldID);
+ }
+ jlong GetStaticLongField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticLongField(this,clazz,fieldID);
+ }
+ jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticFloatField(this,clazz,fieldID);
+ }
+ jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticDoubleField(this,clazz,fieldID);
+ }
+
+ void SetStaticObjectField(jclass clazz, jfieldID fieldID,
+ jobject value) {
+ functions->SetStaticObjectField(this,clazz,fieldID,value);
+ }
+ void SetStaticBooleanField(jclass clazz, jfieldID fieldID,
+ jboolean value) {
+ functions->SetStaticBooleanField(this,clazz,fieldID,value);
+ }
+ void SetStaticByteField(jclass clazz, jfieldID fieldID,
+ jbyte value) {
+ functions->SetStaticByteField(this,clazz,fieldID,value);
+ }
+ void SetStaticCharField(jclass clazz, jfieldID fieldID,
+ jchar value) {
+ functions->SetStaticCharField(this,clazz,fieldID,value);
+ }
+ void SetStaticShortField(jclass clazz, jfieldID fieldID,
+ jshort value) {
+ functions->SetStaticShortField(this,clazz,fieldID,value);
+ }
+ void SetStaticIntField(jclass clazz, jfieldID fieldID,
+ jint value) {
+ functions->SetStaticIntField(this,clazz,fieldID,value);
+ }
+ void SetStaticLongField(jclass clazz, jfieldID fieldID,
+ jlong value) {
+ functions->SetStaticLongField(this,clazz,fieldID,value);
+ }
+ void SetStaticFloatField(jclass clazz, jfieldID fieldID,
+ jfloat value) {
+ functions->SetStaticFloatField(this,clazz,fieldID,value);
+ }
+ void SetStaticDoubleField(jclass clazz, jfieldID fieldID,
+ jdouble value) {
+ functions->SetStaticDoubleField(this,clazz,fieldID,value);
+ }
+
+ jstring NewString(const jchar *unicode, jsize len) {
+ return functions->NewString(this,unicode,len);
+ }
+ jsize GetStringLength(jstring str) {
+ return functions->GetStringLength(this,str);
+ }
+ const jchar *GetStringChars(jstring str, jboolean *isCopy) {
+ return functions->GetStringChars(this,str,isCopy);
+ }
+ void ReleaseStringChars(jstring str, const jchar *chars) {
+ functions->ReleaseStringChars(this,str,chars);
+ }
+
+ jstring NewStringUTF(const char *utf) {
+ return functions->NewStringUTF(this,utf);
+ }
+ jsize GetStringUTFLength(jstring str) {
+ return functions->GetStringUTFLength(this,str);
+ }
+ const char* GetStringUTFChars(jstring str, jboolean *isCopy) {
+ return functions->GetStringUTFChars(this,str,isCopy);
+ }
+ void ReleaseStringUTFChars(jstring str, const char* chars) {
+ functions->ReleaseStringUTFChars(this,str,chars);
+ }
+
+ jsize GetArrayLength(jarray array) {
+ return functions->GetArrayLength(this,array);
+ }
+
+ jobjectArray NewObjectArray(jsize len, jclass clazz,
+ jobject init) {
+ return functions->NewObjectArray(this,len,clazz,init);
+ }
+ jobject GetObjectArrayElement(jobjectArray array, jsize index) {
+ return functions->GetObjectArrayElement(this,array,index);
+ }
+ void SetObjectArrayElement(jobjectArray array, jsize index,
+ jobject val) {
+ functions->SetObjectArrayElement(this,array,index,val);
+ }
+
+ jbooleanArray NewBooleanArray(jsize len) {
+ return functions->NewBooleanArray(this,len);
+ }
+ jbyteArray NewByteArray(jsize len) {
+ return functions->NewByteArray(this,len);
+ }
+ jcharArray NewCharArray(jsize len) {
+ return functions->NewCharArray(this,len);
+ }
+ jshortArray NewShortArray(jsize len) {
+ return functions->NewShortArray(this,len);
+ }
+ jintArray NewIntArray(jsize len) {
+ return functions->NewIntArray(this,len);
+ }
+ jlongArray NewLongArray(jsize len) {
+ return functions->NewLongArray(this,len);
+ }
+ jfloatArray NewFloatArray(jsize len) {
+ return functions->NewFloatArray(this,len);
+ }
+ jdoubleArray NewDoubleArray(jsize len) {
+ return functions->NewDoubleArray(this,len);
+ }
+
+ jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) {
+ return functions->GetBooleanArrayElements(this,array,isCopy);
+ }
+ jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) {
+ return functions->GetByteArrayElements(this,array,isCopy);
+ }
+ jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) {
+ return functions->GetCharArrayElements(this,array,isCopy);
+ }
+ jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) {
+ return functions->GetShortArrayElements(this,array,isCopy);
+ }
+ jint * GetIntArrayElements(jintArray array, jboolean *isCopy) {
+ return functions->GetIntArrayElements(this,array,isCopy);
+ }
+ jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) {
+ return functions->GetLongArrayElements(this,array,isCopy);
+ }
+ jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) {
+ return functions->GetFloatArrayElements(this,array,isCopy);
+ }
+ jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) {
+ return functions->GetDoubleArrayElements(this,array,isCopy);
+ }
+
+ void ReleaseBooleanArrayElements(jbooleanArray array,
+ jboolean *elems,
+ jint mode) {
+ functions->ReleaseBooleanArrayElements(this,array,elems,mode);
+ }
+ void ReleaseByteArrayElements(jbyteArray array,
+ jbyte *elems,
+ jint mode) {
+ functions->ReleaseByteArrayElements(this,array,elems,mode);
+ }
+ void ReleaseCharArrayElements(jcharArray array,
+ jchar *elems,
+ jint mode) {
+ functions->ReleaseCharArrayElements(this,array,elems,mode);
+ }
+ void ReleaseShortArrayElements(jshortArray array,
+ jshort *elems,
+ jint mode) {
+ functions->ReleaseShortArrayElements(this,array,elems,mode);
+ }
+ void ReleaseIntArrayElements(jintArray array,
+ jint *elems,
+ jint mode) {
+ functions->ReleaseIntArrayElements(this,array,elems,mode);
+ }
+ void ReleaseLongArrayElements(jlongArray array,
+ jlong *elems,
+ jint mode) {
+ functions->ReleaseLongArrayElements(this,array,elems,mode);
+ }
+ void ReleaseFloatArrayElements(jfloatArray array,
+ jfloat *elems,
+ jint mode) {
+ functions->ReleaseFloatArrayElements(this,array,elems,mode);
+ }
+ void ReleaseDoubleArrayElements(jdoubleArray array,
+ jdouble *elems,
+ jint mode) {
+ functions->ReleaseDoubleArrayElements(this,array,elems,mode);
+ }
+
+ void GetBooleanArrayRegion(jbooleanArray array,
+ jsize start, jsize len, jboolean *buf) {
+ functions->GetBooleanArrayRegion(this,array,start,len,buf);
+ }
+ void GetByteArrayRegion(jbyteArray array,
+ jsize start, jsize len, jbyte *buf) {
+ functions->GetByteArrayRegion(this,array,start,len,buf);
+ }
+ void GetCharArrayRegion(jcharArray array,
+ jsize start, jsize len, jchar *buf) {
+ functions->GetCharArrayRegion(this,array,start,len,buf);
+ }
+ void GetShortArrayRegion(jshortArray array,
+ jsize start, jsize len, jshort *buf) {
+ functions->GetShortArrayRegion(this,array,start,len,buf);
+ }
+ void GetIntArrayRegion(jintArray array,
+ jsize start, jsize len, jint *buf) {
+ functions->GetIntArrayRegion(this,array,start,len,buf);
+ }
+ void GetLongArrayRegion(jlongArray array,
+ jsize start, jsize len, jlong *buf) {
+ functions->GetLongArrayRegion(this,array,start,len,buf);
+ }
+ void GetFloatArrayRegion(jfloatArray array,
+ jsize start, jsize len, jfloat *buf) {
+ functions->GetFloatArrayRegion(this,array,start,len,buf);
+ }
+ void GetDoubleArrayRegion(jdoubleArray array,
+ jsize start, jsize len, jdouble *buf) {
+ functions->GetDoubleArrayRegion(this,array,start,len,buf);
+ }
+
+ void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
+ const jboolean *buf) {
+ functions->SetBooleanArrayRegion(this,array,start,len,buf);
+ }
+ void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
+ const jbyte *buf) {
+ functions->SetByteArrayRegion(this,array,start,len,buf);
+ }
+ void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
+ const jchar *buf) {
+ functions->SetCharArrayRegion(this,array,start,len,buf);
+ }
+ void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
+ const jshort *buf) {
+ functions->SetShortArrayRegion(this,array,start,len,buf);
+ }
+ void SetIntArrayRegion(jintArray array, jsize start, jsize len,
+ const jint *buf) {
+ functions->SetIntArrayRegion(this,array,start,len,buf);
+ }
+ void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
+ const jlong *buf) {
+ functions->SetLongArrayRegion(this,array,start,len,buf);
+ }
+ void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
+ const jfloat *buf) {
+ functions->SetFloatArrayRegion(this,array,start,len,buf);
+ }
+ void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
+ const jdouble *buf) {
+ functions->SetDoubleArrayRegion(this,array,start,len,buf);
+ }
+
+ jint RegisterNatives(jclass clazz, const JNINativeMethod *methods,
+ jint nMethods) {
+ return functions->RegisterNatives(this,clazz,methods,nMethods);
+ }
+ jint UnregisterNatives(jclass clazz) {
+ return functions->UnregisterNatives(this,clazz);
+ }
+
+ jint MonitorEnter(jobject obj) {
+ return functions->MonitorEnter(this,obj);
+ }
+ jint MonitorExit(jobject obj) {
+ return functions->MonitorExit(this,obj);
+ }
+
+ jint GetJavaVM(JavaVM **vm) {
+ return functions->GetJavaVM(this,vm);
+ }
+
+ void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) {
+ functions->GetStringRegion(this,str,start,len,buf);
+ }
+ void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) {
+ functions->GetStringUTFRegion(this,str,start,len,buf);
+ }
+
+ void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) {
+ return functions->GetPrimitiveArrayCritical(this,array,isCopy);
+ }
+ void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) {
+ functions->ReleasePrimitiveArrayCritical(this,array,carray,mode);
+ }
+
+ const jchar * GetStringCritical(jstring string, jboolean *isCopy) {
+ return functions->GetStringCritical(this,string,isCopy);
+ }
+ void ReleaseStringCritical(jstring string, const jchar *cstring) {
+ functions->ReleaseStringCritical(this,string,cstring);
+ }
+
+ jweak NewWeakGlobalRef(jobject obj) {
+ return functions->NewWeakGlobalRef(this,obj);
+ }
+ void DeleteWeakGlobalRef(jweak ref) {
+ functions->DeleteWeakGlobalRef(this,ref);
+ }
+
+ jboolean ExceptionCheck() {
+ return functions->ExceptionCheck(this);
+ }
+
+ jobject NewDirectByteBuffer(void* address, jlong capacity) {
+ return functions->NewDirectByteBuffer(this, address, capacity);
+ }
+ void* GetDirectBufferAddress(jobject buf) {
+ return functions->GetDirectBufferAddress(this, buf);
+ }
+ jlong GetDirectBufferCapacity(jobject buf) {
+ return functions->GetDirectBufferCapacity(this, buf);
+ }
+ jobjectRefType GetObjectRefType(jobject obj) {
+ return functions->GetObjectRefType(this, obj);
+ }
+
+#endif /* __cplusplus */
+};
+
+typedef struct JavaVMOption {
+ char *optionString;
+ void *extraInfo;
+} JavaVMOption;
+
+typedef struct JavaVMInitArgs {
+ jint version;
+
+ jint nOptions;
+ JavaVMOption *options;
+ jboolean ignoreUnrecognized;
+} JavaVMInitArgs;
+
+typedef struct JavaVMAttachArgs {
+ jint version;
+
+ char *name;
+ jobject group;
+} JavaVMAttachArgs;
+
+/* These will be VM-specific. */
+
+#define JDK1_2
+#define JDK1_4
+
+/* End VM-specific. */
+
+struct JNIInvokeInterface_ {
+ void *reserved0;
+ void *reserved1;
+ void *reserved2;
+
+ jint (JNICALL *DestroyJavaVM)(JavaVM *vm);
+
+ jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args);
+
+ jint (JNICALL *DetachCurrentThread)(JavaVM *vm);
+
+ jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version);
+
+ jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args);
+};
+
+struct JavaVM_ {
+ const struct JNIInvokeInterface_ *functions;
+#ifdef __cplusplus
+
+ jint DestroyJavaVM() {
+ return functions->DestroyJavaVM(this);
+ }
+ jint AttachCurrentThread(void **penv, void *args) {
+ return functions->AttachCurrentThread(this, penv, args);
+ }
+ jint DetachCurrentThread() {
+ return functions->DetachCurrentThread(this);
+ }
+
+ jint GetEnv(void **penv, jint version) {
+ return functions->GetEnv(this, penv, version);
+ }
+ jint AttachCurrentThreadAsDaemon(void **penv, void *args) {
+ return functions->AttachCurrentThreadAsDaemon(this, penv, args);
+ }
+#endif
+};
+
+#ifdef _JNI_IMPLEMENTATION_
+#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT
+#else
+#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT
+#endif
+_JNI_IMPORT_OR_EXPORT_ jint JNICALL
+JNI_GetDefaultJavaVMInitArgs(void *args);
+
+_JNI_IMPORT_OR_EXPORT_ jint JNICALL
+JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args);
+
+_JNI_IMPORT_OR_EXPORT_ jint JNICALL
+JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);
+
+/* Defined by native libraries. */
+JNIEXPORT jint JNICALL
+JNI_OnLoad(JavaVM *vm, void *reserved);
+
+JNIEXPORT void JNICALL
+JNI_OnUnload(JavaVM *vm, void *reserved);
+
+#define JNI_VERSION_1_1 0x00010001
+#define JNI_VERSION_1_2 0x00010002
+#define JNI_VERSION_1_4 0x00010004
+#define JNI_VERSION_1_6 0x00010006
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !_JAVASOFT_JNI_H_ */
diff --git a/launcher/jvm.h b/launcher/jvm.h
new file mode 100644
index 0000000..87eaa6d
--- /dev/null
+++ b/launcher/jvm.h
@@ -0,0 +1,1501 @@
+/*
+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JAVASOFT_JVM_H_
+#define _JAVASOFT_JVM_H_
+
+#include <sys/stat.h>
+
+#include "jni.h"
+#include "jvm_md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains additional functions exported from the VM.
+ * These functions are complementary to the standard JNI support.
+ * There are three parts to this file:
+ *
+ * First, this file contains the VM-related functions needed by native
+ * libraries in the standard Java API. For example, the java.lang.Object
+ * class needs VM-level functions that wait for and notify monitors.
+ *
+ * Second, this file contains the functions and constant definitions
+ * needed by the byte code verifier and class file format checker.
+ * These functions allow the verifier and format checker to be written
+ * in a VM-independent way.
+ *
+ * Third, this file contains various I/O and nerwork operations needed
+ * by the standard Java I/O and network APIs.
+ */
+
+/*
+ * Bump the version number when either of the following happens:
+ *
+ * 1. There is a change in JVM_* functions.
+ *
+ * 2. There is a change in the contract between VM and Java classes.
+ * For example, if the VM relies on a new private field in Thread
+ * class.
+ */
+
+#define JVM_INTERFACE_VERSION 4
+
+JNIEXPORT jint JNICALL
+JVM_GetInterfaceVersion(void);
+
+/*************************************************************************
+ PART 1: Functions for Native Libraries
+ ************************************************************************/
+/*
+ * java.lang.Object
+ */
+JNIEXPORT jint JNICALL
+JVM_IHashCode(JNIEnv *env, jobject obj);
+
+JNIEXPORT void JNICALL
+JVM_MonitorWait(JNIEnv *env, jobject obj, jlong ms);
+
+JNIEXPORT void JNICALL
+JVM_MonitorNotify(JNIEnv *env, jobject obj);
+
+JNIEXPORT void JNICALL
+JVM_MonitorNotifyAll(JNIEnv *env, jobject obj);
+
+JNIEXPORT jobject JNICALL
+JVM_Clone(JNIEnv *env, jobject obj);
+
+/*
+ * java.lang.String
+ */
+JNIEXPORT jstring JNICALL
+JVM_InternString(JNIEnv *env, jstring str);
+
+/*
+ * java.lang.System
+ */
+JNIEXPORT jlong JNICALL
+JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored);
+
+JNIEXPORT jlong JNICALL
+JVM_NanoTime(JNIEnv *env, jclass ignored);
+
+JNIEXPORT void JNICALL
+JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
+ jobject dst, jint dst_pos, jint length);
+
+JNIEXPORT jobject JNICALL
+JVM_InitProperties(JNIEnv *env, jobject p);
+
+/*
+ * java.io.File
+ */
+JNIEXPORT void JNICALL
+JVM_OnExit(void (*func)(void));
+
+/*
+ * java.lang.Runtime
+ */
+JNIEXPORT void JNICALL
+JVM_Exit(jint code);
+
+JNIEXPORT void JNICALL
+JVM_Halt(jint code);
+
+JNIEXPORT void JNICALL
+JVM_GC(void);
+
+/* Returns the number of real-time milliseconds that have elapsed since the
+ * least-recently-inspected heap object was last inspected by the garbage
+ * collector.
+ *
+ * For simple stop-the-world collectors this value is just the time
+ * since the most recent collection. For generational collectors it is the
+ * time since the oldest generation was most recently collected. Other
+ * collectors are free to return a pessimistic estimate of the elapsed time, or
+ * simply the time since the last full collection was performed.
+ *
+ * Note that in the presence of reference objects, a given object that is no
+ * longer strongly reachable may have to be inspected multiple times before it
+ * can be reclaimed.
+ */
+JNIEXPORT jlong JNICALL
+JVM_MaxObjectInspectionAge(void);
+
+JNIEXPORT void JNICALL
+JVM_TraceInstructions(jboolean on);
+
+JNIEXPORT void JNICALL
+JVM_TraceMethodCalls(jboolean on);
+
+JNIEXPORT jlong JNICALL
+JVM_TotalMemory(void);
+
+JNIEXPORT jlong JNICALL
+JVM_FreeMemory(void);
+
+JNIEXPORT jlong JNICALL
+JVM_MaxMemory(void);
+
+JNIEXPORT jint JNICALL
+JVM_ActiveProcessorCount(void);
+
+JNIEXPORT void * JNICALL
+JVM_LoadLibrary(const char *name);
+
+JNIEXPORT void JNICALL
+JVM_UnloadLibrary(void * handle);
+
+JNIEXPORT void * JNICALL
+JVM_FindLibraryEntry(void *handle, const char *name);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsSupportedJNIVersion(jint version);
+
+/*
+ * java.lang.Float and java.lang.Double
+ */
+JNIEXPORT jboolean JNICALL
+JVM_IsNaN(jdouble d);
+
+/*
+ * java.lang.Throwable
+ */
+JNIEXPORT void JNICALL
+JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
+
+JNIEXPORT void JNICALL
+JVM_PrintStackTrace(JNIEnv *env, jobject throwable, jobject printable);
+
+JNIEXPORT jint JNICALL
+JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable);
+
+JNIEXPORT jobject JNICALL
+JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index);
+
+/*
+ * java.lang.Compiler
+ */
+JNIEXPORT void JNICALL
+JVM_InitializeCompiler (JNIEnv *env, jclass compCls);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsSilentCompiler(JNIEnv *env, jclass compCls);
+
+JNIEXPORT jboolean JNICALL
+JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls);
+
+JNIEXPORT jboolean JNICALL
+JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname);
+
+JNIEXPORT jobject JNICALL
+JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg);
+
+JNIEXPORT void JNICALL
+JVM_EnableCompiler(JNIEnv *env, jclass compCls);
+
+JNIEXPORT void JNICALL
+JVM_DisableCompiler(JNIEnv *env, jclass compCls);
+
+/*
+ * java.lang.Thread
+ */
+JNIEXPORT void JNICALL
+JVM_StartThread(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_StopThread(JNIEnv *env, jobject thread, jobject exception);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsThreadAlive(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_SuspendThread(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_ResumeThread(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_SetThreadPriority(JNIEnv *env, jobject thread, jint prio);
+
+JNIEXPORT void JNICALL
+JVM_Yield(JNIEnv *env, jclass threadClass);
+
+JNIEXPORT void JNICALL
+JVM_Sleep(JNIEnv *env, jclass threadClass, jlong millis);
+
+JNIEXPORT jobject JNICALL
+JVM_CurrentThread(JNIEnv *env, jclass threadClass);
+
+JNIEXPORT jint JNICALL
+JVM_CountStackFrames(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_Interrupt(JNIEnv *env, jobject thread);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsInterrupted(JNIEnv *env, jobject thread, jboolean clearInterrupted);
+
+JNIEXPORT jboolean JNICALL
+JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj);
+
+JNIEXPORT void JNICALL
+JVM_DumpAllStacks(JNIEnv *env, jclass unused);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetAllThreads(JNIEnv *env, jclass dummy);
+
+/* getStackTrace() and getAllStackTraces() method */
+JNIEXPORT jobjectArray JNICALL
+JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads);
+
+/*
+ * java.lang.SecurityManager
+ */
+JNIEXPORT jclass JNICALL
+JVM_CurrentLoadedClass(JNIEnv *env);
+
+JNIEXPORT jobject JNICALL
+JVM_CurrentClassLoader(JNIEnv *env);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassContext(JNIEnv *env);
+
+JNIEXPORT jint JNICALL
+JVM_ClassDepth(JNIEnv *env, jstring name);
+
+JNIEXPORT jint JNICALL
+JVM_ClassLoaderDepth(JNIEnv *env);
+
+/*
+ * java.lang.Package
+ */
+JNIEXPORT jstring JNICALL
+JVM_GetSystemPackage(JNIEnv *env, jstring name);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetSystemPackages(JNIEnv *env);
+
+/*
+ * java.io.ObjectInputStream
+ */
+JNIEXPORT jobject JNICALL
+JVM_AllocateNewObject(JNIEnv *env, jobject obj, jclass currClass,
+ jclass initClass);
+
+JNIEXPORT jobject JNICALL
+JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass,
+ jint length);
+
+JNIEXPORT jobject JNICALL
+JVM_LatestUserDefinedLoader(JNIEnv *env);
+
+/*
+ * This function has been deprecated and should not be considered
+ * part of the specified JVM interface.
+ */
+JNIEXPORT jclass JNICALL
+JVM_LoadClass0(JNIEnv *env, jobject obj, jclass currClass,
+ jstring currClassName);
+
+/*
+ * java.lang.reflect.Array
+ */
+JNIEXPORT jint JNICALL
+JVM_GetArrayLength(JNIEnv *env, jobject arr);
+
+JNIEXPORT jobject JNICALL
+JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index);
+
+JNIEXPORT jvalue JNICALL
+JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode);
+
+JNIEXPORT void JNICALL
+JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val);
+
+JNIEXPORT void JNICALL
+JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v,
+ unsigned char vCode);
+
+JNIEXPORT jobject JNICALL
+JVM_NewArray(JNIEnv *env, jclass eltClass, jint length);
+
+JNIEXPORT jobject JNICALL
+JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim);
+
+/*
+ * java.lang.Class and java.lang.ClassLoader
+ */
+/*
+ * Returns the class in which the code invoking the native method
+ * belongs.
+ *
+ * Note that in JDK 1.1, native methods did not create a frame.
+ * In 1.2, they do. Therefore native methods like Class.forName
+ * can no longer look at the current frame for the caller class.
+ */
+JNIEXPORT jclass JNICALL
+JVM_GetCallerClass(JNIEnv *env, int n);
+
+/*
+ * Find primitive classes
+ * utf: class name
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
+
+/*
+ * Link the class
+ */
+JNIEXPORT void JNICALL
+JVM_ResolveClass(JNIEnv *env, jclass cls);
+
+/*
+ * Find a class from a given class loader. Throw ClassNotFoundException
+ * or NoClassDefFoundError depending on the value of the last
+ * argument.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromClassLoader(JNIEnv *env, const char *name, jboolean init,
+ jobject loader, jboolean throwError);
+
+/*
+ * Find a class from a given class.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init,
+ jclass from);
+
+/* Find a loaded class cached by the VM */
+JNIEXPORT jclass JNICALL
+JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name);
+
+/* Define a class */
+JNIEXPORT jclass JNICALL
+JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
+ jsize len, jobject pd);
+
+/* Define a class with a source (added in JDK1.5) */
+JNIEXPORT jclass JNICALL
+JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
+ const jbyte *buf, jsize len, jobject pd,
+ const char *source);
+
+/*
+ * Reflection support functions
+ */
+
+JNIEXPORT jstring JNICALL
+JVM_GetClassName(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassInterfaces(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobject JNICALL
+JVM_GetClassLoader(JNIEnv *env, jclass cls);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsInterface(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassSigners(JNIEnv *env, jclass cls);
+
+JNIEXPORT void JNICALL
+JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers);
+
+JNIEXPORT jobject JNICALL
+JVM_GetProtectionDomain(JNIEnv *env, jclass cls);
+
+JNIEXPORT void JNICALL
+JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsArrayClass(JNIEnv *env, jclass cls);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsPrimitiveClass(JNIEnv *env, jclass cls);
+
+JNIEXPORT jclass JNICALL
+JVM_GetComponentType(JNIEnv *env, jclass cls);
+
+JNIEXPORT jint JNICALL
+JVM_GetClassModifiers(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass);
+
+JNIEXPORT jclass JNICALL
+JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass);
+
+/* Generics support (JDK 1.5) */
+JNIEXPORT jstring JNICALL
+JVM_GetClassSignature(JNIEnv *env, jclass cls);
+
+/* Annotations support (JDK 1.5) */
+JNIEXPORT jbyteArray JNICALL
+JVM_GetClassAnnotations(JNIEnv *env, jclass cls);
+
+/*
+ * New (JDK 1.4) reflection implementation
+ */
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly);
+
+/* Differs from JVM_GetClassModifiers in treatment of inner classes.
+ This returns the access flags for the class as specified in the
+ class file rather than searching the InnerClasses attribute (if
+ present) to find the source-level access flags. Only the values of
+ the low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
+ valid. */
+JNIEXPORT jint JNICALL
+JVM_GetClassAccessFlags(JNIEnv *env, jclass cls);
+
+/* The following two reflection routines are still needed due to startup time issues */
+/*
+ * java.lang.reflect.Method
+ */
+JNIEXPORT jobject JNICALL
+JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0);
+
+/*
+ * java.lang.reflect.Constructor
+ */
+JNIEXPORT jobject JNICALL
+JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0);
+
+/*
+ * Constant pool access; currently used to implement reflective access to annotations (JDK 1.5)
+ */
+
+JNIEXPORT jobject JNICALL
+JVM_GetClassConstantPool(JNIEnv *env, jclass cls);
+
+JNIEXPORT jint JNICALL JVM_ConstantPoolGetSize
+(JNIEnv *env, jobject unused, jobject jcpool);
+
+JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAtIfLoaded
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAtIfLoaded
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAtIfLoaded
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetMemberRefInfoAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jint JNICALL JVM_ConstantPoolGetIntAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jlong JNICALL JVM_ConstantPoolGetLongAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jfloat JNICALL JVM_ConstantPoolGetFloatAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jdouble JNICALL JVM_ConstantPoolGetDoubleAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jstring JNICALL JVM_ConstantPoolGetStringAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jstring JNICALL JVM_ConstantPoolGetUTF8At
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+/*
+ * java.security.*
+ */
+
+JNIEXPORT jobject JNICALL
+JVM_DoPrivileged(JNIEnv *env, jclass cls,
+ jobject action, jobject context, jboolean wrapException);
+
+JNIEXPORT jobject JNICALL
+JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobject JNICALL
+JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls);
+
+/*
+ * Signal support, used to implement the shutdown sequence. Every VM must
+ * support JVM_SIGINT and JVM_SIGTERM, raising the former for user interrupts
+ * (^C) and the latter for external termination (kill, system shutdown, etc.).
+ * Other platform-dependent signal values may also be supported.
+ */
+
+JNIEXPORT void * JNICALL
+JVM_RegisterSignal(jint sig, void *handler);
+
+JNIEXPORT jboolean JNICALL
+JVM_RaiseSignal(jint sig);
+
+JNIEXPORT jint JNICALL
+JVM_FindSignal(const char *name);
+
+/*
+ * Retrieve the assertion directives for the specified class.
+ */
+JNIEXPORT jboolean JNICALL
+JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls);
+
+/*
+ * Retrieve the assertion directives from the VM.
+ */
+JNIEXPORT jobject JNICALL
+JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused);
+
+/*
+ * java.util.concurrent.AtomicLong
+ */
+JNIEXPORT jboolean JNICALL
+JVM_SupportsCX8(void);
+
+/*************************************************************************
+ PART 2: Support for the Verifier and Class File Format Checker
+ ************************************************************************/
+/*
+ * Return the class name in UTF format. The result is valid
+ * until JVM_ReleaseUTf is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetClassNameUTF(JNIEnv *env, jclass cb);
+
+/*
+ * Returns the constant pool types in the buffer provided by "types."
+ */
+JNIEXPORT void JNICALL
+JVM_GetClassCPTypes(JNIEnv *env, jclass cb, unsigned char *types);
+
+/*
+ * Returns the number of Constant Pool entries.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cb);
+
+/*
+ * Returns the number of *declared* fields or methods.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetClassFieldsCount(JNIEnv *env, jclass cb);
+
+JNIEXPORT jint JNICALL
+JVM_GetClassMethodsCount(JNIEnv *env, jclass cb);
+
+/*
+ * Returns the CP indexes of exceptions raised by a given method.
+ * Places the result in the given buffer.
+ *
+ * The method is identified by method_index.
+ */
+JNIEXPORT void JNICALL
+JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cb, jint method_index,
+ unsigned short *exceptions);
+/*
+ * Returns the number of exceptions raised by a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cb, jint method_index);
+
+/*
+ * Returns the byte code sequence of a given method.
+ * Places the result in the given buffer.
+ *
+ * The method is identified by method_index.
+ */
+JNIEXPORT void JNICALL
+JVM_GetMethodIxByteCode(JNIEnv *env, jclass cb, jint method_index,
+ unsigned char *code);
+
+/*
+ * Returns the length of the byte code sequence of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cb, jint method_index);
+
+/*
+ * A structure used to a capture exception table entry in a Java method.
+ */
+typedef struct {
+ jint start_pc;
+ jint end_pc;
+ jint handler_pc;
+ jint catchType;
+} JVM_ExceptionTableEntryType;
+
+/*
+ * Returns the exception table entry at entry_index of a given method.
+ * Places the result in the given buffer.
+ *
+ * The method is identified by method_index.
+ */
+JNIEXPORT void JNICALL
+JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cb, jint method_index,
+ jint entry_index,
+ JVM_ExceptionTableEntryType *entry);
+
+/*
+ * Returns the length of the exception table of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the modifiers of a given field.
+ * The field is identified by field_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetFieldIxModifiers(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the modifiers of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxModifiers(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the number of local variables of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the number of arguments (including this pointer) of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the maximum amount of stack (in words) used by a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Is a given method a constructor.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jboolean JNICALL
+JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the name of a given method in UTF format.
+ * The result remains valid until JVM_ReleaseUTF is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the signature of a given method in UTF format.
+ * The result remains valid until JVM_ReleaseUTF is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the name of the field refered to at a given constant pool
+ * index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the name of the method refered to at a given constant pool
+ * index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the signature of the method refered to at a given constant pool
+ * index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the signature of the field refered to at a given constant pool
+ * index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the class name refered to at a given constant pool index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPClassNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the class name refered to at a given constant pool index.
+ *
+ * The constant pool entry must refer to a CONSTANT_Fieldref.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the class name refered to at a given constant pool index.
+ *
+ * The constant pool entry must refer to CONSTANT_Methodref or
+ * CONSTANT_InterfaceMethodref.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the modifiers of a field in calledClass. The field is
+ * referred to in class cb at constant pool entry index.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ *
+ * Returns -1 if the field does not exist in calledClass.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetCPFieldModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass);
+
+/*
+ * Returns the modifiers of a method in calledClass. The method is
+ * referred to in class cb at constant pool entry index.
+ *
+ * Returns -1 if the method does not exist in calledClass.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetCPMethodModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass);
+
+/*
+ * Releases the UTF string obtained from the VM.
+ */
+JNIEXPORT void JNICALL
+JVM_ReleaseUTF(const char *utf);
+
+/*
+ * Compare if two classes are in the same package.
+ */
+JNIEXPORT jboolean JNICALL
+JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2);
+
+/* Constants in class files */
+
+#define JVM_ACC_PUBLIC 0x0001 /* visible to everyone */
+#define JVM_ACC_PRIVATE 0x0002 /* visible only to the defining class */
+#define JVM_ACC_PROTECTED 0x0004 /* visible to subclasses */
+#define JVM_ACC_STATIC 0x0008 /* instance variable is static */
+#define JVM_ACC_FINAL 0x0010 /* no further subclassing, overriding */
+#define JVM_ACC_SYNCHRONIZED 0x0020 /* wrap method call in monitor lock */
+#define JVM_ACC_SUPER 0x0020 /* funky handling of invokespecial */
+#define JVM_ACC_VOLATILE 0x0040 /* can not cache in registers */
+#define JVM_ACC_BRIDGE 0x0040 /* bridge method generated by compiler */
+#define JVM_ACC_TRANSIENT 0x0080 /* not persistant */
+#define JVM_ACC_VARARGS 0x0080 /* method declared with variable number of args */
+#define JVM_ACC_NATIVE 0x0100 /* implemented in C */
+#define JVM_ACC_INTERFACE 0x0200 /* class is an interface */
+#define JVM_ACC_ABSTRACT 0x0400 /* no definition provided */
+#define JVM_ACC_STRICT 0x0800 /* strict floating point */
+#define JVM_ACC_SYNTHETIC 0x1000 /* compiler-generated class, method or field */
+
+#define JVM_ACC_ANNOTATION 0x2000 /* annotation type */
+#define JVM_ACC_ENUM 0x4000 /* field is declared as element of enum */
+
+#define JVM_ACC_PUBLIC_BIT 0
+#define JVM_ACC_PRIVATE_BIT 1
+#define JVM_ACC_PROTECTED_BIT 2
+#define JVM_ACC_STATIC_BIT 3
+#define JVM_ACC_FINAL_BIT 4
+#define JVM_ACC_SYNCHRONIZED_BIT 5
+#define JVM_ACC_SUPER_BIT 5
+#define JVM_ACC_VOLATILE_BIT 6
+#define JVM_ACC_BRIDGE_BIT 6
+#define JVM_ACC_TRANSIENT_BIT 7
+#define JVM_ACC_VARARGS_BIT 7
+#define JVM_ACC_NATIVE_BIT 8
+#define JVM_ACC_INTERFACE_BIT 9
+#define JVM_ACC_ABSTRACT_BIT 10
+#define JVM_ACC_STRICT_BIT 11
+#define JVM_ACC_SYNTHETIC_BIT 12
+#define JVM_ACC_ANNOTATION_BIT 13
+#define JVM_ACC_ENUM_BIT 14
+
+enum {
+ JVM_CONSTANT_Utf8 = 1,
+ JVM_CONSTANT_Unicode, /* unused */
+ JVM_CONSTANT_Integer,
+ JVM_CONSTANT_Float,
+ JVM_CONSTANT_Long,
+ JVM_CONSTANT_Double,
+ JVM_CONSTANT_Class,
+ JVM_CONSTANT_String,
+ JVM_CONSTANT_Fieldref,
+ JVM_CONSTANT_Methodref,
+ JVM_CONSTANT_InterfaceMethodref,
+ JVM_CONSTANT_NameAndType
+};
+
+/* Used in the newarray instruction. */
+
+#define JVM_T_BOOLEAN 4
+#define JVM_T_CHAR 5
+#define JVM_T_FLOAT 6
+#define JVM_T_DOUBLE 7
+#define JVM_T_BYTE 8
+#define JVM_T_SHORT 9
+#define JVM_T_INT 10
+#define JVM_T_LONG 11
+
+/* JVM method signatures */
+
+#define JVM_SIGNATURE_ARRAY '['
+#define JVM_SIGNATURE_BYTE 'B'
+#define JVM_SIGNATURE_CHAR 'C'
+#define JVM_SIGNATURE_CLASS 'L'
+#define JVM_SIGNATURE_ENDCLASS ';'
+#define JVM_SIGNATURE_ENUM 'E'
+#define JVM_SIGNATURE_FLOAT 'F'
+#define JVM_SIGNATURE_DOUBLE 'D'
+#define JVM_SIGNATURE_FUNC '('
+#define JVM_SIGNATURE_ENDFUNC ')'
+#define JVM_SIGNATURE_INT 'I'
+#define JVM_SIGNATURE_LONG 'J'
+#define JVM_SIGNATURE_SHORT 'S'
+#define JVM_SIGNATURE_VOID 'V'
+#define JVM_SIGNATURE_BOOLEAN 'Z'
+
+/*
+ * A function defined by the byte-code verifier and called by the VM.
+ * This is not a function implemented in the VM.
+ *
+ * Returns JNI_FALSE if verification fails. A detailed error message
+ * will be places in msg_buf, whose length is specified by buf_len.
+ */
+typedef jboolean (*verifier_fn_t)(JNIEnv *env,
+ jclass cb,
+ char * msg_buf,
+ jint buf_len);
+
+
+/*
+ * Support for a VM-independent class format checker.
+ */
+typedef struct {
+ unsigned long code; /* byte code */
+ unsigned long excs; /* exceptions */
+ unsigned long etab; /* catch table */
+ unsigned long lnum; /* line number */
+ unsigned long lvar; /* local vars */
+} method_size_info;
+
+typedef struct {
+ unsigned int constants; /* constant pool */
+ unsigned int fields;
+ unsigned int methods;
+ unsigned int interfaces;
+ unsigned int fields2; /* number of static 2-word fields */
+ unsigned int innerclasses; /* # of records in InnerClasses attr */
+
+ method_size_info clinit; /* memory used in clinit */
+ method_size_info main; /* used everywhere else */
+} class_size_info;
+
+/*
+ * Functions defined in libjava.so to perform string conversions.
+ *
+ */
+
+typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str);
+
+typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b);
+
+/* This is the function defined in libjava.so that performs class
+ * format checks. This functions fills in size information about
+ * the class file and returns:
+ *
+ * 0: good
+ * -1: out of memory
+ * -2: bad format
+ * -3: unsupported version
+ * -4: bad class name
+ */
+
+typedef jint (*check_format_fn_t)(char *class_name,
+ unsigned char *data,
+ unsigned int data_size,
+ class_size_info *class_size,
+ char *message_buffer,
+ jint buffer_length,
+ jboolean measure_only,
+ jboolean check_relaxed);
+
+#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \
+ JVM_ACC_FINAL | \
+ JVM_ACC_SUPER | \
+ JVM_ACC_INTERFACE | \
+ JVM_ACC_ABSTRACT | \
+ JVM_ACC_ANNOTATION | \
+ JVM_ACC_ENUM | \
+ JVM_ACC_SYNTHETIC)
+
+#define JVM_RECOGNIZED_FIELD_MODIFIERS (JVM_ACC_PUBLIC | \
+ JVM_ACC_PRIVATE | \
+ JVM_ACC_PROTECTED | \
+ JVM_ACC_STATIC | \
+ JVM_ACC_FINAL | \
+ JVM_ACC_VOLATILE | \
+ JVM_ACC_TRANSIENT | \
+ JVM_ACC_ENUM | \
+ JVM_ACC_SYNTHETIC)
+
+#define JVM_RECOGNIZED_METHOD_MODIFIERS (JVM_ACC_PUBLIC | \
+ JVM_ACC_PRIVATE | \
+ JVM_ACC_PROTECTED | \
+ JVM_ACC_STATIC | \
+ JVM_ACC_FINAL | \
+ JVM_ACC_SYNCHRONIZED | \
+ JVM_ACC_BRIDGE | \
+ JVM_ACC_VARARGS | \
+ JVM_ACC_NATIVE | \
+ JVM_ACC_ABSTRACT | \
+ JVM_ACC_STRICT | \
+ JVM_ACC_SYNTHETIC)
+
+/*
+ * This is the function defined in libjava.so to perform path
+ * canonicalization. VM call this function before opening jar files
+ * to load system classes.
+ *
+ */
+
+typedef int (*canonicalize_fn_t)(JNIEnv *env, char *orig, char *out, int len);
+
+/*************************************************************************
+ PART 3: I/O and Network Support
+ ************************************************************************/
+
+/* Note that the JVM IO functions are expected to return JVM_IO_ERR
+ * when there is any kind of error. The caller can then use the
+ * platform specific support (e.g., errno) to get the detailed
+ * error info. The JVM_GetLastErrorString procedure may also be used
+ * to obtain a descriptive error string.
+ */
+#define JVM_IO_ERR (-1)
+
+/* For interruptible IO. Returning JVM_IO_INTR indicates that an IO
+ * operation has been disrupted by Thread.interrupt. There are a
+ * number of technical difficulties related to interruptible IO that
+ * need to be solved. For example, most existing programs do not handle
+ * InterruptedIOExceptions specially, they simply treat those as any
+ * IOExceptions, which typically indicate fatal errors.
+ *
+ * There are also two modes of operation for interruptible IO. In the
+ * resumption mode, an interrupted IO operation is guaranteed not to
+ * have any side-effects, and can be restarted. In the termination mode,
+ * an interrupted IO operation corrupts the underlying IO stream, so
+ * that the only reasonable operation on an interrupted stream is to
+ * close that stream. The resumption mode seems to be impossible to
+ * implement on Win32 and Solaris. Implementing the termination mode is
+ * easier, but it's not clear that's the right semantics.
+ *
+ * Interruptible IO is not supported on Win32.It can be enabled/disabled
+ * using a compile-time flag on Solaris. Third-party JVM ports do not
+ * need to implement interruptible IO.
+ */
+#define JVM_IO_INTR (-2)
+
+/* Write a string into the given buffer, in the platform's local encoding,
+ * that describes the most recent system-level error to occur in this thread.
+ * Return the length of the string or zero if no error occurred.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetLastErrorString(char *buf, int len);
+
+/*
+ * Convert a pathname into native format. This function does syntactic
+ * cleanup, such as removing redundant separator characters. It modifies
+ * the given pathname string in place.
+ */
+JNIEXPORT char * JNICALL
+JVM_NativePath(char *);
+
+/*
+ * JVM I/O error codes
+ */
+#define JVM_EEXIST -100
+
+/*
+ * Open a file descriptor. This function returns a negative error code
+ * on error, and a non-negative integer that is the file descriptor on
+ * success.
+ */
+JNIEXPORT jint JNICALL
+JVM_Open(const char *fname, jint flags, jint mode);
+
+/*
+ * Close a file descriptor. This function returns -1 on error, and 0
+ * on success.
+ *
+ * fd the file descriptor to close.
+ */
+JNIEXPORT jint JNICALL
+JVM_Close(jint fd);
+
+/*
+ * Read data from a file decriptor into a char array.
+ *
+ * fd the file descriptor to read from.
+ * buf the buffer where to put the read data.
+ * nbytes the number of bytes to read.
+ *
+ * This function returns -1 on error, and 0 on success.
+ */
+JNIEXPORT jint JNICALL
+JVM_Read(jint fd, char *buf, jint nbytes);
+
+/*
+ * Write data from a char array to a file decriptor.
+ *
+ * fd the file descriptor to read from.
+ * buf the buffer from which to fetch the data.
+ * nbytes the number of bytes to write.
+ *
+ * This function returns -1 on error, and 0 on success.
+ */
+JNIEXPORT jint JNICALL
+JVM_Write(jint fd, char *buf, jint nbytes);
+
+/*
+ * Returns the number of bytes available for reading from a given file
+ * descriptor
+ */
+JNIEXPORT jint JNICALL
+JVM_Available(jint fd, jlong *pbytes);
+
+/*
+ * Move the file descriptor pointer from whence by offset.
+ *
+ * fd the file descriptor to move.
+ * offset the number of bytes to move it by.
+ * whence the start from where to move it.
+ *
+ * This function returns the resulting pointer location.
+ */
+JNIEXPORT jlong JNICALL
+JVM_Lseek(jint fd, jlong offset, jint whence);
+
+/*
+ * Set the length of the file associated with the given descriptor to the given
+ * length. If the new length is longer than the current length then the file
+ * is extended; the contents of the extended portion are not defined. The
+ * value of the file pointer is undefined after this procedure returns.
+ */
+JNIEXPORT jint JNICALL
+JVM_SetLength(jint fd, jlong length);
+
+/*
+ * Synchronize the file descriptor's in memory state with that of the
+ * physical device. Return of -1 is an error, 0 is OK.
+ */
+JNIEXPORT jint JNICALL
+JVM_Sync(jint fd);
+
+/*
+ * Networking library support
+ */
+
+JNIEXPORT jint JNICALL
+JVM_InitializeSocketLibrary(void);
+
+struct sockaddr;
+
+JNIEXPORT jint JNICALL
+JVM_Socket(jint domain, jint type, jint protocol);
+
+JNIEXPORT jint JNICALL
+JVM_SocketClose(jint fd);
+
+JNIEXPORT jint JNICALL
+JVM_SocketShutdown(jint fd, jint howto);
+
+JNIEXPORT jint JNICALL
+JVM_Recv(jint fd, char *buf, jint nBytes, jint flags);
+
+JNIEXPORT jint JNICALL
+JVM_Send(jint fd, char *buf, jint nBytes, jint flags);
+
+JNIEXPORT jint JNICALL
+JVM_Timeout(int fd, long timeout);
+
+JNIEXPORT jint JNICALL
+JVM_Listen(jint fd, jint count);
+
+JNIEXPORT jint JNICALL
+JVM_Connect(jint fd, struct sockaddr *him, jint len);
+
+JNIEXPORT jint JNICALL
+JVM_Bind(jint fd, struct sockaddr *him, jint len);
+
+JNIEXPORT jint JNICALL
+JVM_Accept(jint fd, struct sockaddr *him, jint *len);
+
+JNIEXPORT jint JNICALL
+JVM_RecvFrom(jint fd, char *buf, int nBytes,
+ int flags, struct sockaddr *from, int *fromlen);
+
+JNIEXPORT jint JNICALL
+JVM_SendTo(jint fd, char *buf, int len,
+ int flags, struct sockaddr *to, int tolen);
+
+JNIEXPORT jint JNICALL
+JVM_SocketAvailable(jint fd, jint *result);
+
+
+JNIEXPORT jint JNICALL
+JVM_GetSockName(jint fd, struct sockaddr *him, int *len);
+
+JNIEXPORT jint JNICALL
+JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen);
+
+JNIEXPORT jint JNICALL
+JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen);
+
+/*
+ * These routines are only reentrant on Windows
+ */
+
+#ifdef WIN32
+
+JNIEXPORT struct protoent * JNICALL
+JVM_GetProtoByName(char* name);
+
+JNIEXPORT struct hostent* JNICALL
+JVM_GetHostByAddr(const char* name, int len, int type);
+
+JNIEXPORT struct hostent* JNICALL
+JVM_GetHostByName(char* name);
+
+#endif /* _WINDOWS */
+
+JNIEXPORT int JNICALL
+JVM_GetHostName(char* name, int namelen);
+
+/*
+ * The standard printing functions supported by the Java VM. (Should they
+ * be renamed to JVM_* in the future?
+ */
+
+/*
+ * BE CAREFUL! The following functions do not implement the
+ * full feature set of standard C printf formats.
+ */
+int
+jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
+
+int
+jio_snprintf(char *str, size_t count, const char *fmt, ...);
+
+int
+jio_fprintf(FILE *, const char *fmt, ...);
+
+int
+jio_vfprintf(FILE *, const char *fmt, va_list args);
+
+
+JNIEXPORT void * JNICALL
+JVM_RawMonitorCreate(void);
+
+JNIEXPORT void JNICALL
+JVM_RawMonitorDestroy(void *mon);
+
+JNIEXPORT jint JNICALL
+JVM_RawMonitorEnter(void *mon);
+
+JNIEXPORT void JNICALL
+JVM_RawMonitorExit(void *mon);
+
+/*
+ * java.lang.management support
+ */
+JNIEXPORT void* JNICALL
+JVM_GetManagement(jint version);
+
+/*
+ * com.sun.tools.attach.VirtualMachine support
+ *
+ * Initialize the agent properties with the properties maintained in the VM.
+ */
+JNIEXPORT jobject JNICALL
+JVM_InitAgentProperties(JNIEnv *env, jobject agent_props);
+
+/* Generics reflection support.
+ *
+ * Returns information about the given class's EnclosingMethod
+ * attribute, if present, or null if the class had no enclosing
+ * method.
+ *
+ * If non-null, the returned array contains three elements. Element 0
+ * is the java.lang.Class of which the enclosing method is a member,
+ * and elements 1 and 2 are the java.lang.Strings for the enclosing
+ * method's name and descriptor, respectively.
+ */
+JNIEXPORT jobjectArray JNICALL
+JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass);
+
+/*
+ * Java thread state support
+ */
+enum {
+ JAVA_THREAD_STATE_NEW = 0,
+ JAVA_THREAD_STATE_RUNNABLE = 1,
+ JAVA_THREAD_STATE_BLOCKED = 2,
+ JAVA_THREAD_STATE_WAITING = 3,
+ JAVA_THREAD_STATE_TIMED_WAITING = 4,
+ JAVA_THREAD_STATE_TERMINATED = 5,
+ JAVA_THREAD_STATE_COUNT = 6
+};
+
+/*
+ * Returns an array of the threadStatus values representing the
+ * given Java thread state. Returns NULL if the VM version is
+ * incompatible with the JDK or doesn't support the given
+ * Java thread state.
+ */
+JNIEXPORT jintArray JNICALL
+JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState);
+
+/*
+ * Returns an array of the substate names representing the
+ * given Java thread state. Returns NULL if the VM version is
+ * incompatible with the JDK or the VM doesn't support
+ * the given Java thread state.
+ * values must be the jintArray returned from JVM_GetThreadStateValues
+ * and javaThreadState.
+ */
+JNIEXPORT jobjectArray JNICALL
+JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values);
+
+/* =========================================================================
+ * The following defines a private JVM interface that the JDK can query
+ * for the JVM version and capabilities. sun.misc.Version defines
+ * the methods for getting the VM version and its capabilities.
+ *
+ * When a new bit is added, the following should be updated to provide
+ * access to the new capability:
+ * HS: JVM_GetVersionInfo and Abstract_VM_Version class
+ * SDK: Version class
+ *
+ * Similary, a private JDK interface JDK_GetVersionInfo0 is defined for
+ * JVM to query for the JDK version and capabilities.
+ *
+ * When a new bit is added, the following should be updated to provide
+ * access to the new capability:
+ * HS: JDK_Version class
+ * SDK: JDK_GetVersionInfo0
+ *
+ * ==========================================================================
+ */
+typedef struct {
+ /* Naming convention of RE build version string: n.n.n[_uu[c]][-<identifier>]-bxx */
+ unsigned int jvm_version; /* Consists of major, minor, micro (n.n.n) */
+ /* and build number (xx) */
+ unsigned int update_version : 8; /* Update release version (uu) */
+ unsigned int special_update_version : 8; /* Special update release version (c)*/
+ unsigned int reserved1 : 16;
+ unsigned int reserved2;
+
+ /* The following bits represents JVM supports that JDK has dependency on.
+ * JDK can use these bits to determine which JVM version
+ * and support it has to maintain runtime compatibility.
+ *
+ * When a new bit is added in a minor or update release, make sure
+ * the new bit is also added in the main/baseline.
+ */
+ unsigned int is_attach_supported : 1;
+ unsigned int is_kernel_jvm : 1;
+ unsigned int : 30;
+ unsigned int : 32;
+ unsigned int : 32;
+} jvm_version_info;
+
+#define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
+#define JVM_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
+#define JVM_VERSION_MICRO(version) ((version & 0x0000FF00) >> 8)
+
+/* Build number is available only for RE builds.
+ * It will be zero for internal builds.
+ */
+#define JVM_VERSION_BUILD(version) ((version & 0x000000FF))
+
+JNIEXPORT void JNICALL
+JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size);
+
+typedef struct {
+ // Naming convention of RE build version string: n.n.n[_uu[c]][-<identifier>]-bxx
+ unsigned int jdk_version; /* Consists of major, minor, micro (n.n.n) */
+ /* and build number (xx) */
+ unsigned int update_version : 8; /* Update release version (uu) */
+ unsigned int special_update_version : 8; /* Special update release version (c)*/
+ unsigned int reserved1 : 16;
+ unsigned int reserved2;
+
+ /* The following bits represents new JDK supports that VM has dependency on.
+ * VM implementation can use these bits to determine which JDK version
+ * and support it has to maintain runtime compatibility.
+ *
+ * When a new bit is added in a minor or update release, make sure
+ * the new bit is also added in the main/baseline.
+ */
+ unsigned int thread_park_blocker : 1;
+ unsigned int : 31;
+ unsigned int : 32;
+ unsigned int : 32;
+} jdk_version_info;
+
+#define JDK_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
+#define JDK_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
+#define JDK_VERSION_MICRO(version) ((version & 0x0000FF00) >> 8)
+
+/* Build number is available only for RE build (i.e. JDK_BUILD_NUMBER is set to bNN)
+ * It will be zero for internal builds.
+ */
+#define JDK_VERSION_BUILD(version) ((version & 0x000000FF))
+
+/*
+ * This is the function JDK_GetVersionInfo0 defined in libjava.so
+ * that is dynamically looked up by JVM.
+ */
+typedef void (*jdk_version_info_fn_t)(jdk_version_info* info, size_t info_size);
+
+/*
+ * This structure is used by the launcher to get the default thread
+ * stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a
+ * version of 1.1. As it is not supported otherwise, it has been removed
+ * from jni.h
+ */
+typedef struct JDK1_1InitArgs {
+ jint version;
+
+ char **properties;
+ jint checkSource;
+ jint nativeStackSize;
+ jint javaStackSize;
+ jint minHeapSize;
+ jint maxHeapSize;
+ jint verifyMode;
+ char *classpath;
+
+ jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args);
+ void (JNICALL *exit)(jint code);
+ void (JNICALL *abort)(void);
+
+ jint enableClassGC;
+ jint enableVerboseGC;
+ jint disableAsyncGC;
+ jint verbose;
+ jboolean debugging;
+ jint debugPort;
+} JDK1_1InitArgs;
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+
+#endif /* __cplusplus */
+
+#endif /* !_JAVASOFT_JVM_H_ */
diff --git a/launcher/jvm_md.h b/launcher/jvm_md.h
new file mode 100644
index 0000000..da69ebb
--- /dev/null
+++ b/launcher/jvm_md.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JAVASOFT_JVM_MD_H_
+#define _JAVASOFT_JVM_MD_H_
+
+/*
+ * This file is currently collecting system-specific dregs for the
+ * JNI conversion, which should be sorted out later.
+ */
+
+#include <dirent.h> /* For DIR */
+#include <sys/param.h> /* For MAXPATHLEN */
+#include <unistd.h> /* For F_OK, R_OK, W_OK */
+
+#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"}
+#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"}
+
+#define JNI_LIB_PREFIX "lib"
+#define JNI_LIB_SUFFIX ".so"
+
+#define JVM_MAXPATHLEN MAXPATHLEN
+
+#define JVM_R_OK R_OK
+#define JVM_W_OK W_OK
+#define JVM_X_OK X_OK
+#define JVM_F_OK F_OK
+
+/*
+ * File I/O
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/signal.h>
+
+/* O Flags */
+
+#define JVM_O_RDONLY O_RDONLY
+#define JVM_O_WRONLY O_WRONLY
+#define JVM_O_RDWR O_RDWR
+#define JVM_O_O_APPEND O_APPEND
+#define JVM_O_EXCL O_EXCL
+#define JVM_O_CREAT O_CREAT
+#define JVM_O_DELETE 0x10000
+
+/* Signals */
+
+#define JVM_SIGINT SIGINT
+#define JVM_SIGTERM SIGTERM
+
+
+#endif /* !_JAVASOFT_JVM_MD_H_ */
diff --git a/launcher/manifest_info.h b/launcher/manifest_info.h
new file mode 100644
index 0000000..44341f4
--- /dev/null
+++ b/launcher/manifest_info.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _MANIFEST_INFO_H
+#define _MANIFEST_INFO_H
+
+#include <sys/types.h>
+
+/*
+ * Zip file header signatures
+ */
+#define SIGSIZ 4 /* size of all header signatures */
+#define LOCSIG 0x04034b50L /* "PK\003\004" */
+#define EXTSIG 0x08074b50L /* "PK\007\008" */
+#define CENSIG 0x02014b50L /* "PK\001\002" */
+#define ENDSIG 0x06054b50L /* "PK\005\006" */
+
+/*
+ * Header sizes including signatures
+ */
+#define LOCHDR 30
+#define EXTHDR 16
+#define CENHDR 46
+#define ENDHDR 22
+
+/*
+ * Header field access macros
+ */
+#define CH(b, n) (((unsigned char *)(b))[n])
+#define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8))
+#define LG(b, n) (SH(b, n) | (SH(b, n+2) << 16))
+#define GETSIG(b) LG(b, 0)
+
+/*
+ * Macros for getting local file (LOC) header fields
+ */
+#define LOCVER(b) SH(b, 4) /* version needed to extract */
+#define LOCFLG(b) SH(b, 6) /* general purpose bit flags */
+#define LOCHOW(b) SH(b, 8) /* compression method */
+#define LOCTIM(b) LG(b, 10) /* modification time */
+#define LOCCRC(b) LG(b, 14) /* crc of uncompressed data */
+#define LOCSIZ(b) LG(b, 18) /* compressed data size */
+#define LOCLEN(b) LG(b, 22) /* uncompressed data size */
+#define LOCNAM(b) SH(b, 26) /* filename length */
+#define LOCEXT(b) SH(b, 28) /* extra field length */
+
+/*
+ * Macros for getting extra local (EXT) header fields
+ */
+#define EXTCRC(b) LG(b, 4) /* crc of uncompressed data */
+#define EXTSIZ(b) LG(b, 8) /* compressed size */
+#define EXTLEN(b) LG(b, 12) /* uncompressed size */
+
+/*
+ * Macros for getting central directory header (CEN) fields
+ */
+#define CENVEM(b) SH(b, 4) /* version made by */
+#define CENVER(b) SH(b, 6) /* version needed to extract */
+#define CENFLG(b) SH(b, 8) /* general purpose bit flags */
+#define CENHOW(b) SH(b, 10) /* compression method */
+#define CENTIM(b) LG(b, 12) /* modification time */
+#define CENCRC(b) LG(b, 16) /* crc of uncompressed data */
+#define CENSIZ(b) LG(b, 20) /* compressed size */
+#define CENLEN(b) LG(b, 24) /* uncompressed size */
+#define CENNAM(b) SH(b, 28) /* length of filename */
+#define CENEXT(b) SH(b, 30) /* length of extra field */
+#define CENCOM(b) SH(b, 32) /* file comment length */
+#define CENDSK(b) SH(b, 34) /* disk number start */
+#define CENATT(b) SH(b, 36) /* internal file attributes */
+#define CENATX(b) LG(b, 38) /* external file attributes */
+#define CENOFF(b) LG(b, 42) /* offset of local header */
+
+/*
+ * Macros for getting end of central directory header (END) fields
+ */
+#define ENDSUB(b) SH(b, 8) /* number of entries on this disk */
+#define ENDTOT(b) SH(b, 10) /* total number of entries */
+#define ENDSIZ(b) LG(b, 12) /* central directory size */
+#define ENDOFF(b) LG(b, 16) /* central directory offset */
+#define ENDCOM(b) SH(b, 20) /* size of zip file comment */
+
+/*
+ * A comment of maximum length of 64kb can follow the END record. This
+ * is the furthest the END record can be from the end of the file.
+ */
+#define END_MAXLEN (0xFFFF + ENDHDR)
+
+/*
+ * Supported compression methods.
+ */
+#define STORED 0
+#define DEFLATED 8
+
+/*
+ * Information from the CEN entry to inflate a file.
+ */
+typedef struct zentry { /* Zip file entry */
+ size_t isize; /* size of inflated data */
+ size_t csize; /* size of compressed data (zero if uncompressed) */
+ off_t offset; /* position of compressed data */
+ int how; /* compression method (if any) */
+} zentry;
+
+/*
+ * Information returned from the Manifest file by the ParseManifest() routine.
+ * Certainly (much) more could be returned, but this is the information
+ * currently of interest to the C based Java utilities (particularly the
+ * Java launcher).
+ */
+typedef struct manifest_info { /* Interesting fields from the Manifest */
+ char *manifest_version; /* Manifest-Version string */
+ char *main_class; /* Main-Class entry */
+ char *jre_version; /* Appropriate J2SE release spec */
+ char jre_restrict_search; /* Restricted JRE search */
+ char *splashscreen_image_file_name; /* splashscreen image file */
+} manifest_info;
+
+/*
+ * Attribute closure to provide to manifest_iterate.
+ */
+typedef void (*attribute_closure)(const char *name, const char *value,
+ void *user_data);
+
+/*
+ * Function prototypes.
+ */
+int JLI_ParseManifest(char *jarfile, manifest_info *info);
+void *JLI_JarUnpackFile(const char *jarfile, const char *filename,
+ int *size);
+void JLI_FreeManifest(void);
+int JLI_ManifestIterate(const char *jarfile, attribute_closure ac,
+ void *user_data);
+
+#endif /* _MANIFEST_INFO_H */
diff --git a/launcher/splashscreen.h b/launcher/splashscreen.h
new file mode 100644
index 0000000..da64bf6
--- /dev/null
+++ b/launcher/splashscreen.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+int DoSplashLoadMemory(void* pdata, int size); /* requires preloading the file */
+int DoSplashLoadFile(const char* filename);
+void DoSplashInit(void);
+void DoSplashClose(void);
+void DoSplashSetFileJarName(const char* fileName, const char* jarName);
diff --git a/launcher/splashscreen_stubs.c b/launcher/splashscreen_stubs.c
new file mode 100644
index 0000000..1ceee65
--- /dev/null
+++ b/launcher/splashscreen_stubs.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include "splashscreen.h"
+
+extern void* SplashProcAddress(const char* name); /* in java_md.c */
+
+/*
+ * Prototypes of pointers to functions in splashscreen shared lib
+ */
+typedef int (*SplashLoadMemory_t)(void* pdata, int size);
+typedef int (*SplashLoadFile_t)(const char* filename);
+typedef void (*SplashInit_t)(void);
+typedef void (*SplashClose_t)(void);
+typedef void (*SplashSetFileJarName_t)(const char* fileName,
+ const char* jarName);
+
+/*
+ * This macro invokes a function from the shared lib.
+ * it locates a function with SplashProcAddress on demand.
+ * if SplashProcAddress fails, def value is returned.
+ *
+ * it is further wrapped with INVOKEV (works with functions which return
+ * void and INVOKE (for all other functions). INVOKEV looks a bit ugly,
+ * that's due being unable to return a value of type void in C. INVOKEV
+ * works around this by using semicolon instead of return operator.
+ */
+#define _INVOKE(name,def,ret) \
+ static void* proc = NULL; \
+ if (!proc) { proc = SplashProcAddress(#name); } \
+ if (!proc) { return def; } \
+ ret ((name##_t)proc)
+
+#define INVOKE(name,def) _INVOKE(name,def,return)
+#define INVOKEV(name) _INVOKE(name, ,;)
+
+int DoSplashLoadMemory(void* pdata, int size) {
+ INVOKE(SplashLoadMemory,0)(pdata, size);
+}
+
+int DoSplashLoadFile(const char* filename) {
+ INVOKE(SplashLoadFile,0)(filename);
+}
+
+void DoSplashInit(void) {
+ INVOKEV(SplashInit)();
+}
+
+void DoSplashClose(void) {
+ INVOKEV(SplashClose)();
+}
+
+void DoSplashSetFileJarName(const char* fileName, const char* jarName) {
+ INVOKEV(SplashSetFileJarName)(fileName, jarName);
+}
diff --git a/launcher/version_comp.h b/launcher/version_comp.h
new file mode 100644
index 0000000..d450907
--- /dev/null
+++ b/launcher/version_comp.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _VERSION_COMP_H
+#define _VERSION_COMP_H
+
+/*
+ * Function prototypes.
+ */
+int JLI_ExactVersionId(char *id1, char *id2);
+int JLI_PrefixVersionId(char *id1, char *id2);
+int JLI_AcceptableRelease(char *release, char *version_string);
+int JLI_ValidVersionString(char *version_string);
+
+#endif /* _VERSION_COMP_H */
diff --git a/launcher/wildcard.h b/launcher/wildcard.h
new file mode 100644
index 0000000..7626a10
--- /dev/null
+++ b/launcher/wildcard.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef WILDCARD_H_
+#define WILDCARD_H_
+
+#ifdef EXPAND_CLASSPATH_WILDCARDS
+const char *JLI_WildcardExpandClasspath(const char *classpath);
+#else
+#define JLI_WildcardExpandClasspath(s) (s)
+#endif
+
+#endif /* include guard */