From 41d00b744b7772f9302fdb94dddadb165b951220 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 14 May 2013 17:58:33 -0700 Subject: Simplify defaulting for system properties, and trust the environment less. The originally-reported bug (https://android-review.googlesource.com/58258) was that dalvik would fail to start if LD_LIBRARY_PATH was unset. This changes things so we no longer have multiple default values for java.library.path, cope better with that not being set, and don't set it if LD_LIBRARY_PATH isn't set. Change-Id: I55d48a35b1b42df872e6dcd0a38fc7bc4b8cad5a --- luni/src/main/java/java/lang/Runtime.java | 31 +++++++++-------- luni/src/main/java/java/lang/System.java | 58 ++++++++++++++++--------------- 2 files changed, 47 insertions(+), 42 deletions(-) (limited to 'luni') diff --git a/luni/src/main/java/java/lang/Runtime.java b/luni/src/main/java/java/lang/Runtime.java index 5ded981..88d4cc6 100644 --- a/luni/src/main/java/java/lang/Runtime.java +++ b/luni/src/main/java/java/lang/Runtime.java @@ -47,6 +47,7 @@ import java.util.List; import java.util.StringTokenizer; import libcore.io.IoUtils; import libcore.io.Libcore; +import libcore.util.EmptyArray; import static libcore.io.OsConstants._SC_NPROCESSORS_CONF; /** @@ -66,7 +67,22 @@ public class Runtime { /** * Holds the library paths, used for native library lookup. */ - private final String[] mLibPaths; + private final String[] mLibPaths = initLibPaths(); + + private static String[] initLibPaths() { + String javaLibraryPath = System.getProperty("java.library.path"); + if (javaLibraryPath == null) { + return EmptyArray.STRING; + } + String[] paths = javaLibraryPath.split(":"); + // Add a '/' to the end of each directory so we don't have to do it every time. + for (int i = 0; i < paths.length; ++i) { + if (!paths[i].endsWith("/")) { + paths[i] += "/"; + } + } + return paths; + } /** * Holds the list of threads to run when the VM terminates @@ -93,19 +109,6 @@ public class Runtime { * Prevent this class from being instantiated. */ private Runtime() { - String pathList = System.getProperty("java.library.path", "."); - String pathSep = System.getProperty("path.separator", ":"); - String fileSep = System.getProperty("file.separator", "/"); - - mLibPaths = pathList.split(pathSep); - - // Add a '/' to the end so we don't have to do the property lookup - // and concatenation later. - for (int i = 0; i < mLibPaths.length; i++) { - if (!mLibPaths[i].endsWith(fileSep)) { - mLibPaths[i] += fileSep; - } - } } /** diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java index 6ba8452..da1e460 100644 --- a/luni/src/main/java/java/lang/System.java +++ b/luni/src/main/java/java/lang/System.java @@ -51,7 +51,9 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import libcore.icu.ICU; +import libcore.io.ErrnoException; import libcore.io.Libcore; +import libcore.io.StructPasswd; import libcore.io.StructUtsname; import libcore.util.ZoneInfoDB; @@ -179,13 +181,10 @@ public final class System { public static native long nanoTime(); /** - * Causes the VM to stop running and the program to exit. If - * {@link #runFinalizersOnExit(boolean)} has been previously invoked with a + * Causes the VM to stop running and the program to exit with the given exit status. + * If {@link #runFinalizersOnExit(boolean)} has been previously invoked with a * {@code true} argument, then all objects will be properly * garbage-collected and finalized first. - * - * @param code - * the return code. */ public static void exit(int code) { Runtime.getRuntime().exit(code); @@ -201,30 +200,18 @@ public final class System { } /** - * Returns the value of the environment variable with the given name {@code - * var}. - * - * @param name - * the name of the environment variable. - * @return the value of the specified environment variable or {@code null} - * if no variable exists with the given name. + * Returns the value of the environment variable with the given name, or null if no such + * variable exists. */ public static String getenv(String name) { - return getenv(name, null); - } - - private static String getenv(String name, String defaultValue) { if (name == null) { throw new NullPointerException("name == null"); } - String value = Libcore.os.getenv(name); - return (value != null) ? value : defaultValue; + return Libcore.os.getenv(name); } /** - * Returns an unmodifiable map of all available environment variables. - * - * @return the map representing all environment variables. + * Returns an unmodifiable map of all environment variables to their values. */ public static Map getenv() { Map map = new HashMap(); @@ -283,10 +270,21 @@ public final class System { p.put("java.ext.dirs", ""); p.put("java.version", "0"); - p.put("java.home", getenv("JAVA_HOME", "/system")); + // TODO: does this make any sense? Should we just leave java.home unset? + String javaHome = getenv("JAVA_HOME"); + if (javaHome == null) { + javaHome = "/system"; + } + p.put("java.home", javaHome); + // On Android, each app gets its own temporary directory. This is just a fallback + // default, useful only on the host. p.put("java.io.tmpdir", "/tmp"); - p.put("java.library.path", getenv("LD_LIBRARY_PATH")); + + String ldLibraryPath = getenv("LD_LIBRARY_PATH"); + if (ldLibraryPath != null) { + p.put("java.library.path", ldLibraryPath); + } p.put("java.specification.name", "Dalvik Core Library"); p.put("java.specification.vendor", projectName); @@ -313,8 +311,13 @@ public final class System { p.put("user.language", "en"); p.put("user.region", "US"); - p.put("user.home", getenv("HOME", "")); - p.put("user.name", getenv("USER", "")); + try { + StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid()); + p.put("user.home", passwd.pw_dir); + p.put("user.name", passwd.pw_name); + } catch (ErrnoException exception) { + throw new AssertionError(exception); + } StructUtsname info = Libcore.os.uname(); p.put("os.arch", info.machine); @@ -325,8 +328,7 @@ public final class System { p.put("android.icu.library.version", ICU.getIcuVersion()); p.put("android.icu.unicode.version", ICU.getUnicodeVersion()); p.put("android.icu.cldr.version", ICU.getCldrVersion()); - // TODO: it would be nice to have this but currently it causes circularity. - // p.put("android.tzdata.version", ZoneInfoDB.getVersion()); + parsePropertyAssignments(p, specialProperties()); // Override built-in properties with settings from the command line. @@ -370,7 +372,7 @@ public final class System { * java.ext.dirs (Not useful on Android) Empty * java.home Location of the VM on the file system {@code /system} * java.io.tmpdir See {@link java.io.File#createTempFile} {@code /sdcard} - * java.library.path Search path for JNI libraries {@code /system/lib} + * java.library.path Search path for JNI libraries {@code /vendor/lib:/system/lib} * java.vendor Human-readable VM vendor {@code The Android Project} * java.vendor.url URL for VM vendor's web site {@code http://www.android.com/} * java.version (Not useful on Android) {@code 0} -- cgit v1.1