Pure Java access to environment variables

(For some reason Google sometimes thinks that this page is more important than my page on a native implementation of getenv. Well, they're entitled to their opinion, but I think you should really go here.)

Pierre-Charles David has pointed out that on Linux, and possibly other similar systems, the environment variables for a process are available as null-delimited strings in the file /proc/self/environ. This opens the way to a neat pure Java implementation of getenv. Here's his e-mail and proof-of-concept code.


Hi.

I was looking for a way to get access to the environment in Java, and Google gave me the address of your page on the subject (http://www.tigress.co.uk/rmy/java/getenv/index.html). I'm sure your solution works, but I don't really like having to deal with JNI.

However, reading your pages made me think about other possible solutions, and I finally realised that, at least under Linux (and maybe other Unices), it is possible to do it in pure Java: Linux provides a virtual filesystem named /proc where text files are generated on the fly by the kernel on demand. In this filesystem are all kinds of informations about the system, and in particular about the running processes. More specifically, the /proc/self directory contains informations about the current process, and among them, you guessed, a file called 'environ' with a textual representation of the process's environement.

It's not portable in any way (although the same technique might work for other Unices) but it's pure Java, and hence much simpler to deal with than a JNI solution.

I've attached a quick hack which shows how it can be done (requires JDK 1.4 because I used String.split() for convenience, and of course Linux).

Bye.

import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

// @license

/**
 * @author pcdavid
 */
public class GetEnv {
    public static Map getEnvironment() {
        Map env = new HashMap();
        LineNumberReader reader = null;
        try {
            reader = new LineNumberReader(new FileReader("/proc/self/environ"));
            String[] lines = reader.readLine().split("\000");
            for (int i = 0; i < lines.length; i++) {
                String line = lines[i];
                int n = line.indexOf('=');
                env.put(line.substring(0, n), line.substring(n+1));
            }            
        } catch (Exception e) {
            return null;
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException ioe) {
                /* ignore */
            }
        }
        return env;
    }
    
    public static String getEnv(String varName) {
        return (String) getEnvironment().get(varName); 
    }
    
    public static void main(String[] args) {
        Map env = GetEnv.getEnvironment();
        for (Iterator iter = env.keySet().iterator(); iter.hasNext();) {
            String var= (String) iter.next();
            System.out.println(var + "=" + env.get(var));
        }
    }
}