/* * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ #if defined(__sun) && defined(__SVR4) #define _POSIX_PTHREAD_SEMANTICS #include #include #include #include #include #include #include #include void *handle; char* error; char path[PATH_MAX]; jint(JNICALL *jni_create_java_vm)(JavaVM **, JNIEnv **, void *) = NULL; JavaVM *jvm; extern void exit(int); void loadJVM() { char lib[PATH_MAX]; sprintf(lib, "%s/lib/sparcv9/server/libjvm.so", path); handle = dlopen(lib, RTLD_LAZY); if (!handle) { fputs(dlerror(), stderr); fputs(" : 2\n", stderr); exit(1); } fputs("Will load JVM...\n", stderr); //find the address of function *(void **) (&jni_create_java_vm) = dlsym(handle, "JNI_CreateJavaVM"); if ((error = dlerror()) != NULL) { fputs(error, stderr); fputs(" : 3\n", stderr); exit(1); } fputs("JVM loaded okay.\n", stderr); } JNIEnv* initJVM() /* The JDK1.2 way of doing it */ { JNIEnv *env = NULL; JavaVMInitArgs vm_args; JavaVMOption options[1]; jint res; /* options[0].optionString = "-Djava.class.path=."; */ /* user classes */ options[0].optionString = "-Xrs"; /* user classes */ vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 1; vm_args.options = options; vm_args.ignoreUnrecognized = JNI_FALSE; fputs("Will create JVM...\n", stderr); res = (*jni_create_java_vm)(&jvm, &env, &vm_args); if (res < 0) { fprintf(stderr, "Can't create Java VM: %d\n", res); exit(1); } fputs("JVM created OK!\n", stderr); return env; } void doStuff(JNIEnv *env) { jclass cls; jmethodID mid; jstring jstr; jobjectArray args; cls = (*env)->FindClass(env, "Prog"); if (cls == 0) { fprintf(stderr, "Can't find Prog class\n"); exit(1); } mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V"); if (mid == 0) { fprintf(stderr, "Can't find Prog.main\n"); exit(1); } jstr = (*env)->NewStringUTF(env, "from C!"); if (jstr == 0) { fprintf(stderr, "Out of memory\n"); exit(1); } args = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), jstr); if (args == 0) { fprintf(stderr, "Out of memory\n"); exit(1); } (*env)->CallStaticVoidMethod(env, cls, mid, args); } JNIEnv* atchJVM() { JNIEnv *env = NULL; int res; res = (*jvm)->AttachCurrentThread(jvm, (void**) &env, NULL); if (res < 0) { fprintf(stderr, "Thread attach failed\n"); return NULL; } return env; } void* somethr(void* x) { JNIEnv *env; fprintf(stderr, "Some thread will create JVM.\n"); loadJVM(); env = initJVM(); fprintf(stderr, "Some thread will call Java.\n"); doStuff(env); if ((*jvm)->DetachCurrentThread(jvm) != 0) fputs("Error: thread not detached!\n", stderr); fprintf(stderr, "Some thread exiting.\n"); return env; } int main(int argc, char **argv) { JNIEnv *env; sigset_t set; pthread_t thr1; pthread_attr_t attr; size_t ss = 0; int sig; if (argc != 2) { printf("usage: a.out jdk_path\n"); exit(0); } strncpy(path, argv[1], PATH_MAX); fprintf(stderr, "Main thread will set signal mask.\n"); sigemptyset(&set); sigaddset(&set, SIGPIPE); sigaddset(&set, SIGTERM); sigaddset(&set, SIGHUP); sigaddset(&set, SIGINT); pthread_sigmask(SIG_BLOCK, &set, NULL); pthread_attr_init(&attr); ss = 1024 * 1024; pthread_attr_setstacksize(&attr, ss); pthread_attr_getstacksize(&attr, &ss); fprintf(stderr, "Stack size: %zu\n", ss); pthread_create(&thr1, NULL, somethr, NULL); sigemptyset(&set); sigaddset(&set, SIGTERM); sigaddset(&set, SIGHUP); sigaddset(&set, SIGINT); fprintf(stderr, "Main thread waiting for signal.\n"); do { int err; sig = 0; err = sigwait(&set, &sig); if (err != 0 && err != EINTR) { fprintf(stderr, "main: sigwait() error: %s\n", strerror(err)); } else { fprintf(stderr, "main: sigwait() got: %d\nSucceed!\n", sig); exit(0); } } while (sig != SIGTERM && sig != SIGINT); pthread_join(thr1, NULL); dlclose(handle); fputs("Main thread exiting.\n", stderr); return 0; } #else int main(int argc, char **argv) { return 0; } #endif