There is a Windows C problem, using JNI when creating a JVM to run a simple Java problem (System.out.println("Hello World")). If redirection of stdout to a file is done on the C side before creating the JVM, the output does not appear in the file and an IOException is thrown Detail Analysis: Customer has written a simple java class which simulates the this problem. It will print out the IOException whenever write() fails. The following exception is seen: java.io.IOException: The handle is invalid at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:260) at java.io.BufferedOutputStream.flushBuffer BufferedOutputStream.java:66) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:124) at IntClient_jni.Los(PrintStream_Sim.java:12) STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : 1) Write a simple "Hello World" Java program which uses System.out.println("Hello World"); 2) Write a C program that does the following: a)redirect stdout to a log file (freopen) b)using JNI to create JVM c)run the main() method of the Java program by using JNI. You will not see the "Hello World" in the file. But if you take out the stdout redirection from the C program, you will see the Hello World from console and no exception on Java side. EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - You should see the System.out redirect output to the log file if we redirect the stdout from C side before creating JVM. ACTUAL BEHAVIOR - There is printout in the redirected log file and an exception is seen: java.io.IOException: The handle is invalid at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:260) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:66) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:124) at IntClient_jni.Los(PrintStream_Sim.java:12) exception on Java side. ERROR MESSAGES/STACK TRACES THAT OCCUR : java.io.IOException: The handle is invalid at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:260) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:66) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:124) at IntClient_jni.Los(PrintStream_Sim.java:12) REPRODUCIBILITY : This bug is easily reproduced. ---------- BEGIN SOURCE ---------- 1) Java Side "Hello World" Program: =========================== import java.io.*; public class PrintStream_Sim{ public static void main(String [] argv) { try { FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); BufferedOutputStream bout = new BufferedOutputStream(fdOut, 128); bout.write(45); bout.flush(); } catch (Throwable t) { try { PrintStream o = new PrintStream(new FileOutputStream("mythrowable.txt")); t.printStackTrace(o); o.close(); } catch (Exception e) {} } } } 2) The C program that creates the JVM and run the Hello World: ================================================ int main(int argc, char* argv[]) { FILE * t = freopen("D:\\temp\\stdout.log", "w", stdout); t = freopen("D:\\temp\\stderr.log", "w", stderr); JavaVM *jvm; JNIEnv *env; JavaVMInitArgs vm_args; jclass cls; jmethodID mid; printf("beginning execution...\n"); JavaVMOption options[2]; options[0].optionString = "-Djava.class.path=."; options[1].optionString = "vfprintf"; options[1].extraInfo = (void*)jio_vfprintf; vm_args.version = JNI_VERSION_1_2; vm_args.options = options; vm_args.nOptions = 2; vm_args.ignoreUnrecognized = JNI_TRUE; jint res = JNI_CreateJavaVM(&jvm, (void **)&env,&vm_args); if (res < 0) { printf("Can't create Java VM\n"); fflush(stdout); return 1; } /* Find the class */ cls = env->FindClass("PrintStream_Sim"); if (cls == 0) { fprintf(stderr, "Could not locate class your CLASSPATH.\n"); return 1 ; } /* Find the method */ mid = env->GetStaticMethodID(cls, "main", "(Ljava/lang/String;)V"); if (mid == 0) { fprintf(stderr, "Could not locate method main with signature \n"); return 1; } /* Invoke the method */ env->CallStaticVoidMethod(cls, mid, NULL); /* we are done */ jvm->DestroyJavaVM(); return 0; } ---------- END SOURCE ---------- workaround: None
|