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
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