Question: I have a big program developed in C, and most functions have several
`fprintf(stderr, "message")` lines.

But right now I need to use those functions in a Java program. So, I implement a JNI interface to communicate between Java and C. Everything is ok, Java and C can communicate, but now I want to capture the several stderr's of C in Java... How can I do that?

Cheers ;)

Answer: 
Out of my experience exactly with the same problem, i can tell that JNI bridge has very strange opinion on the importance of what's going out of JNI through standard streams. Generally it does heavy caching, spilling in unpredictable chunks and timing, and we didn't figure out how to force flushing.

We ended up with mass regex replacement of `*printf()` statements with logging to a file, done altogether on C side. Tailing the resulting logfile was way more reliable than any attempts to convince JVM that you really need the logging when C layer says so, not when JVM makes its mind on the buffers.
A possible workaround for this is to do the following, found at <http://www.thecodingforums.com/threads/redirect-cout-and-cerr-to-system-out-and-system-err.635861/>

> 
> The solution I came up with was to create some JNI code with two
>  methods:
> 
> 
> * one that redirect stdout to a pipe
> * one that get the output stored there
> 
> 
> Then the fow is:
> 
> 
> * call the function that redirect
> * make multiple other JNI calls
> * fetch the output and write it where I want it
> 
> 
> 

The [implementation](http://www.vajhoej.dk/arne/eksperten/jniredirect/) provided from the link above looks like this 

```
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <jni.h>

#include "Nat1.h"

#define MAXBUF 20480

static int oldstdout;
static int pipehandles[2];
static char buf[MAXBUF];

JNIEXPORT void JNICALL Java_Nat2_init(JNIEnv *cntx, jobject me)
{
    oldstdout = _dup(_fileno(stdout));
    _pipe(pipehandles,MAXBUF,_O_BINARY);
    _dup2(pipehandles[1],_fileno(stdout));
 }

JNIEXPORT jstring JNICALL Java_Nat2_done(JNIEnv *cntx, jobject me)
{
    int n;
    fflush(stdout);
    _dup2(oldstdout,_fileno(stdout));
    n = _read(pipehandles[0],buf,sizeof(buf));
    buf[n] = '\0';
    return (*cntx)->NewStringUTF(cntx,buf);
}

```

It is a bit cumbersome since you'd need to *start* capturing the stderr and then fetch it at a later point when you want to view it.