Subscribe to RSS

Some rights reserved

Except where otherwise noted, content on this site is licensed under a Creative Commons License


blog‎ > ‎

JNA on JLine

posted May 3, 2009 3:59 PM by Davide Angelocola   [ updated May 3, 2009 4:27 PM ]
For the sake of curiosity I'm in charge porting some JNI code to JNA. My target refactoring was JLine because I like very much this library, it is simple but complete. During the port I've spotted some interesting problems:
  • a memory leak in native code (a true classic) * 
  • the jar comes with two dll, jline32.dll and jline64.dll
  • under linux it uses sh -c stty in order to set/reset the controlling terminal
  • it is a little outdated (latest release 2007)
  • some code maybe improved using java5 (completors)
  • still using StringBuffer
  • junit declared as compile scope 
Well, after just 2 hours of "soft hacking" (while watching a movie!) I've successfully revamped the WindowsTerminal class using JNA. Unit tests still passes on Windows. The real problem is refactoring the call to stty on UNIX.  I'm wondering about a fork of JLine.

*  the memory leak:

JNIEXPORT jint JNICALL 
Java_jline_WindowsTerminal_getWindowsTerminalHeight (JNIEnv *env, jclass class) 
{
HANDLE outputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
PCONSOLE_SCREEN_BUFFER_INFO info = malloc(sizeof CONSOLE_SCREEN_BUFFER_INFO);
GetConsoleScreenBufferInfo(outputHandle, info);
return info->srWindow.Bottom - info->srWindow.Top+1;
}

as you can see info is never released within this function. Now take a look at the Java version:

private int getWindowsTerminalWidth() {
        int h = kernel32.GetStdHandle(kernel32.STD_OUTPUT_HANDLE);
        CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO();
        kernel32.GetConsoleScreenBufferInfo(h, info);
        return info.wWindowRight - info.wWindowLeft + 1;
}


Č
ċ
ď
jline_WindowsTerminal.c
(2k)
Davide Angelocola,
May 3, 2009 4:15 PM
ċ
ď
jnaReplacement.java
(3k)
Davide Angelocola,
May 3, 2009 4:16 PM