POSIX from Java

I have been doing more traditionally unix-y stuff from Java lately, and one of the things I have needed is proper access to POSIX and libc system calls. Luckily, there are now a couple fabulous libraries to make this easy – no more need to do your own JNI muckery.

I’ve been using jnr-posix with great success. Using it for something like execv(3) looks like:

POSIX posix = POSIXFactory.getPOSIX(new POSIXHandler()
{
    @Override
    public void error(Errno errno, String s)
    {
    }

    @Override
    public void unimplementedError(String s)
    {
    }

    @Override
    public void warn(WARNING_ID warning_id, String s, Object... objects)
    {
    }

    @Override
    public boolean isVerbose()
    {
        return false;
    }

    @Override
    public File getCurrentWorkingDirectory()
    {
    return new File(".");
    }

    @Override
    public String[] getEnv()
    {
        return new String[0];
    }

    @Override
    public InputStream getInputStream()
    {
        return System.in;
    }

    @Override
    public PrintStream getOutputStream()
    {
        return System.out;
    }

    @Override
    public int getPID()
    {
        return 0;
    }

    @Override
    public PrintStream getErrorStream()
    {
        return System.err;
    }

}, true);
    
String[] args = new String[] {
  "/usr/bin/ssh", "lasker.skife.org"
};
posix.execv("/usr/bin/ssh", args);

The bulk of that snippet is setting up the POSIXHandler which provides nice callbacks for the things that are not obvious how to handle, or might want to be overidden in a specific environment. The boolean flag at the end says to use the native POSIX implementation rather than emulating it in Java. The library will sniff your system and dynamically link the right things – is very nice.

The library doesn’t properly declare its dependencies in its pom, so if you want to use it you need to depend on each of:

<dependency>
    <groupId>com.github.jnr</groupId>
    <artifactId>jnr-posix</artifactId>
    <version>2.0</version>
</dependency>

<dependency>
    <groupId>com.github.jnr</groupId>
    <artifactId>jnr-ffi</artifactId>
    <version>0.6.0</version>
</dependency>

<dependency>
    <groupId>com.github.jnr</groupId>
    <artifactId>jnr-constants</artifactId>
    <version>0.8.2</version>
</dependency>

The jnr-posix pom lists jnr-constants and jnr-ffi as provided for some reason. Hopefully that will be remedied in $version.next().