changeset 1945:de45eac5670e

6367077: Purge LD_LIBRARY_PATH usage from the launcher 6899834: (launcher) remove the solaris libjvm.so symlink Summary: Fixes other related issues as well. Reviewed-by: darcy, ohair, xlu, martin
author ksrini
date Fri, 20 Nov 2009 11:01:32 -0800
parents d5a1c012921d
children f07f6eb5d597 f0b63b6d9709
files make/java/jli/Makefile make/java/main/java/Makefile make/java/redist/Makefile src/share/bin/java.c src/solaris/bin/java_md.c test/tools/launcher/Arrrghs.java test/tools/launcher/ExecutionEnvironment.java test/tools/launcher/SolarisDataModel.sh test/tools/launcher/SolarisRunpath.sh test/tools/launcher/TestHelper.java test/tools/launcher/libraryCaller.c test/tools/launcher/libraryCaller.h test/tools/launcher/libraryCaller.java
diffstat 13 files changed, 504 insertions(+), 860 deletions(-) [+]
line wrap: on
line diff
--- a/make/java/jli/Makefile	Sun Nov 29 15:24:32 2009 -0800
+++ b/make/java/jli/Makefile	Fri Nov 20 11:01:32 2009 -0800
@@ -96,6 +96,7 @@
 
 
 ifneq ($(PLATFORM), windows)	# UNIX systems
+        LD_RUNPATH_EXTRAS += ..
 	LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/jli
 	# Note: its important to keep this order meaning -lc is the
 	# last library otherwise it could cause compatibility issues
--- a/make/java/main/java/Makefile	Sun Nov 29 15:24:32 2009 -0800
+++ b/make/java/main/java/Makefile	Fri Nov 20 11:01:32 2009 -0800
@@ -61,8 +61,5 @@
 
 ifeq ($(PLATFORM), solaris)
 LDFLAGS += -R$(OPENWIN_LIB)
-endif
-
-ifeq ($(PLATFORM), solaris)
 LDFLAGS += -M mapfile-$(ARCH)
 endif
--- a/make/java/redist/Makefile	Sun Nov 29 15:24:32 2009 -0800
+++ b/make/java/redist/Makefile	Fri Nov 20 11:01:32 2009 -0800
@@ -194,10 +194,8 @@
 # For backwards compatability, make a link of the 32-bit client JVM to $(LIBDIR)
 IMPORT_LIST += $(LIB_LOCATION)/$(JVM_NAME)
 
-# create a link from lib/libjvm.so to client/libjvm.so
 $(LIB_LOCATION)/$(JVM_NAME): $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME)
 	@$(prep-target)
-	$(LN) -s $(CLIENT_LOCATION)/$(JVM_NAME) $@
 
 #  solaris   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ solaris
 endif # 32bit solaris
--- a/src/share/bin/java.c	Sun Nov 29 15:24:32 2009 -0800
+++ b/src/share/bin/java.c	Fri Nov 20 11:01:32 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,15 +41,13 @@
  * options are turned into "-foo" options to the vm.  This option
  * filtering is handled in a number of places in the launcher, some of
  * it in machine-dependent code.  In this file, the function
- * CheckJVMType removes vm style options and TranslateApplicationArgs
- * removes "-J" prefixes.  On unix platforms, the
- * CreateExecutionEnvironment function from the unix java_md.c file
- * processes and removes -d<n> options.  However, in case
- * CreateExecutionEnvironment does not need to exec because
- * LD_LIBRARY_PATH is set acceptably and the data model does not need
- * to be changed, ParseArguments will screen out the redundant -d<n>
- * options and prevent them from being passed to the vm; this is done
- * by RemovableOption.
+ * CheckJvmType removes vm style options and TranslateApplicationArgs
+ * removes "-J" prefixes.  The CreateExecutionEnvironment function processes
+ * and removes -d<n> options. On unix, there is a possibility that the running
+ * data model may not match to the desired data model, in this case an exec is
+ * required to start the desired model. If the data models match, then
+ * ParseArguments will remove the -d<n> flags. If the data models do not match
+ * the CreateExecutionEnviroment will remove the -d<n> flags.
  */
 
 
@@ -1891,11 +1889,11 @@
  * Return JNI_TRUE for an option string that has no effect but should
  * _not_ be passed on to the vm; return JNI_FALSE otherwise.  On
  * Solaris SPARC, this screening needs to be done if:
- * 1) LD_LIBRARY_PATH does _not_ need to be reset and
- * 2) -d32 or -d64 is passed to a binary with a matching data model
- *    (the exec in SetLibraryPath removes -d<n> options and points the
- *    exec to the proper binary).  When this exec is not done, these options
- *    would end up getting passed onto the vm.
+ *    -d32 or -d64 is passed to a binary with an unmatched data model
+ *    (the exec in CreateExecutionEnvironment removes -d<n> options and points the
+ *    exec to the proper binary).  In the case of when the data model and the
+ *    requested version is matched, an exec would not occur, and these options
+ *    were erroneously passed to the vm.
  */
 jboolean
 RemovableOption(char * option)
--- a/src/solaris/bin/java_md.c	Sun Nov 29 15:24:32 2009 -0800
+++ b/src/solaris/bin/java_md.c	Fri Nov 20 11:01:32 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,9 +51,9 @@
  * two data models and cohabitation of jre/jdk bits with both data
  * models is supported, then DUAL_MODE is defined.  When DUAL_MODE is
  * defined, the architecture names for the narrow and wide version of
- * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME.  Currently
- * only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE; linux
- * i586/amd64 could be defined as DUAL_MODE but that is not the
+ * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME.
+ * Currently  only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE;
+ * linux i586/amd64 could be defined as DUAL_MODE but that is not the
  * current policy.
  */
 
@@ -103,49 +103,56 @@
  * platform independent routine SelectVersion.  This may result in
  * the exec of the specified launcher version.
  *
- * Typically, the launcher execs at least once to ensure a suitable
- * LD_LIBRARY_PATH is in effect for the process.  The first exec
- * screens out all the data model options; leaving the choice of data
- * model implicit in the binary selected to run.  However, in case no
- * exec is done, the data model options are screened out before the vm
- * is invoked.
+ * Previously the launcher modified the LD_LIBRARY_PATH appropriately for the
+ * desired data model path, regardless if data models matched or not. The
+ * launcher subsequently exec'ed the desired executable, in order to make the
+ * LD_LIBRARY_PATH path available for the runtime linker. This is no longer the
+ * case, the launcher dlopens the target libjvm.so. All other required
+ * libraries are loaded by the runtime linker, by virtue of the $ORIGIN paths
+ * baked into the shared libraries, by the build infrastructure at compile time.
  *
- *  incoming argv ------------------------------
- *  |                                          |
- * \|/                                         |
- * CheckJVMType                                |
- * (removes -client, -server, etc.)            |
- *                                            \|/
- *                                            CreateExecutionEnvironment
- *                                            (removes -d32 and -d64,
- *                                             determines desired data model,
- *                                             sets up LD_LIBRARY_PATH,
- *                                             and exec's)
- *                                             |
- *  --------------------------------------------
+ *  Main
+ *  (incoming argv)
  *  |
  * \|/
- * exec child 1 incoming argv -----------------
+ * SelectVersion
+ * (selects the JRE version, note: not data model)
+ *  |
+ * \|/
+ * CreateExecutionEnvironment
+ * (determines desired data model)
+ *  |
+ *  |
+ * \|/
+ *  Have Desired Model ? --> NO --> Is Dual-Mode ? --> NO --> Exit(with error)
  *  |                                          |
- * \|/                                         |
- * CheckJVMType                                |
- * (removes -client, -server, etc.)            |
+ *  |                                          |
  *  |                                         \|/
- *  |                                          CreateExecutionEnvironment
- *  |                                          (verifies desired data model
- *  |                                           is running and acceptable
- *  |                                           LD_LIBRARY_PATH;
- *  |                                           no-op in child)
+ *  |                                         YES
+ *  |                                          |
+ *  |                                          |
+ *  |                                         \|/
+ *  |                                CheckJvmType
+ *  |                               (removes -client, -server etc.)
+ *  |                                          |
+ *  |                                          |
+ * \|/                                        \|/
+ * YES                              (find the desired executable and exec child)
+ *  |                                          |
+ *  |                                          |
+ * \|/                                        \|/
+ * CheckJvmType                                Main
+ * (removes -client, -server, etc.)
+ *  |
  *  |
  * \|/
  * TranslateDashJArgs...
  * (Prepare to pass args to vm)
  *  |
  *  |
- *  |
  * \|/
  * ParseArguments
- * (ignores -d32 and -d64,
+ * (removes -d32 and -d64 if any,
  *  processes version options,
  *  creates argument list for vm,
  *  etc.)
@@ -199,17 +206,13 @@
     /* Compute/set the name of the executable */
     SetExecname(*_argvp);
 
-    /* Set the LD_LIBRARY_PATH environment variable, check data model
-       flags, and exec process, if needed */
+    /* Check data model flags, and exec process, if needed */
     {
       char *arch        = (char *)GetArch(); /* like sparc or sparcv9 */
       char * jvmtype    = NULL;
       int argc          = *_argcp;
       char **argv       = original_argv;
 
-      char *runpath     = NULL; /* existing effective LD_LIBRARY_PATH
-                                   setting */
-
       int running       = CURRENT_DATA_MODEL;
 
       int wanted        = running;      /* What data mode is being
@@ -217,18 +220,8 @@
                                            fine unless another model
                                            is asked for */
 
-      char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
-      char* newpath     = NULL; /* path on new LD_LIBRARY_PATH */
-      char* lastslash   = NULL;
-
-      char** newenvp    = NULL; /* current environment */
-
       char** newargv    = NULL;
       int    newargc    = 0;
-#ifdef __solaris__
-      char*  dmpath     = NULL;  /* data model specific LD_LIBRARY_PATH,
-                                    Solaris only */
-#endif
 
       /*
        * Starting in 1.5, all unix platforms accept the -d32 and -d64
@@ -306,6 +299,11 @@
           JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
           exit(4);
         }
+        /*
+         * we seem to have everything we need, so without further ado
+         * we return back.
+         */
+        return;
       } else {  /* do the same speculatively or exit */
 #ifdef DUAL_MODE
         if (running != wanted) {
@@ -335,190 +333,6 @@
 #endif
       }
 
-      /*
-       * We will set the LD_LIBRARY_PATH as follows:
-       *
-       *     o          $JVMPATH (directory portion only)
-       *     o          $JRE/lib/$LIBARCHNAME
-       *     o          $JRE/../lib/$LIBARCHNAME
-       *
-       * followed by the user's previous effective LD_LIBRARY_PATH, if
-       * any.
-       */
-
-#ifdef __solaris__
-      /*
-       * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
-       * variables:
-       *
-       * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
-       * data-model specific variables are not set.
-       *
-       * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
-       * for 64-bit binaries.
-       *
-       * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
-       * for 32-bit binaries.
-       *
-       * The vm uses LD_LIBRARY_PATH to set the java.library.path system
-       * property.  To shield the vm from the complication of multiple
-       * LD_LIBRARY_PATH variables, if the appropriate data model
-       * specific variable is set, we will act as if LD_LIBRARY_PATH had
-       * the value of the data model specific variant and the data model
-       * specific variant will be unset.  Note that the variable for the
-       * *wanted* data model must be used (if it is set), not simply the
-       * current running data model.
-       */
-
-      switch(wanted) {
-      case 0:
-        if(running == 32) {
-          dmpath = getenv("LD_LIBRARY_PATH_32");
-          wanted = 32;
-        }
-        else {
-          dmpath = getenv("LD_LIBRARY_PATH_64");
-          wanted = 64;
-        }
-        break;
-
-      case 32:
-        dmpath = getenv("LD_LIBRARY_PATH_32");
-        break;
-
-      case 64:
-        dmpath = getenv("LD_LIBRARY_PATH_64");
-        break;
-
-      default:
-        JLI_ReportErrorMessage(JRE_ERROR3, __LINE__);
-        exit(1); /* unknown value in wanted */
-        break;
-      }
-
-      /*
-       * If dmpath is NULL, the relevant data model specific variable is
-       * not set and normal LD_LIBRARY_PATH should be used.
-       */
-      if( dmpath == NULL) {
-        runpath = getenv("LD_LIBRARY_PATH");
-      }
-      else {
-        runpath = dmpath;
-      }
-#else
-      /*
-       * If not on Solaris, assume only a single LD_LIBRARY_PATH
-       * variable.
-       */
-      runpath = getenv("LD_LIBRARY_PATH");
-#endif /* __solaris__ */
-
-#ifdef __linux
-      /*
-       * On linux, if a binary is running as sgid or suid, glibc sets
-       * LD_LIBRARY_PATH to the empty string for security purposes.  (In
-       * contrast, on Solaris the LD_LIBRARY_PATH variable for a
-       * privileged binary does not lose its settings; but the dynamic
-       * linker does apply more scrutiny to the path.) The launcher uses
-       * the value of LD_LIBRARY_PATH to prevent an exec loop.
-       * Therefore, if we are running sgid or suid, this function's
-       * setting of LD_LIBRARY_PATH will be ineffective and we should
-       * return from the function now.  Getting the right libraries to
-       * be found must be handled through other mechanisms.
-       */
-      if((getgid() != getegid()) || (getuid() != geteuid()) ) {
-        return;
-      }
-#endif
-
-      /* runpath contains current effective LD_LIBRARY_PATH setting */
-
-      jvmpath = JLI_StringDup(jvmpath);
-      new_runpath = JLI_MemAlloc( ((runpath!=NULL)?JLI_StrLen(runpath):0) +
-                              2*JLI_StrLen(jrepath) + 2*JLI_StrLen(arch) +
-                              JLI_StrLen(jvmpath) + 52);
-      newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH=");
-
-
-      /*
-       * Create desired LD_LIBRARY_PATH value for target data model.
-       */
-      {
-        /* remove the name of the .so from the JVM path */
-        lastslash = JLI_StrRChr(jvmpath, '/');
-        if (lastslash)
-          *lastslash = '\0';
-
-
-        /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */
-
-        sprintf(new_runpath, "LD_LIBRARY_PATH="
-                "%s:"
-                "%s/lib/%s:"
-                "%s/../lib/%s",
-                jvmpath,
-#ifdef DUAL_MODE
-                jrepath, GetArchPath(wanted),
-                jrepath, GetArchPath(wanted)
-#else
-                jrepath, arch,
-                jrepath, arch
-#endif
-                );
-
-
-        /*
-         * Check to make sure that the prefix of the current path is the
-         * desired environment variable setting.
-         */
-        if (runpath != NULL &&
-            JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath))==0 &&
-            (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') &&
-            (running == wanted) /* data model does not have to be changed */
-#ifdef __solaris__
-            && (dmpath == NULL)    /* data model specific variables not set  */
-#endif
-            ) {
-
-          return;
-
-        }
-      }
-
-      /*
-       * Place the desired environment setting onto the prefix of
-       * LD_LIBRARY_PATH.  Note that this prevents any possible infinite
-       * loop of execv() because we test for the prefix, above.
-       */
-      if (runpath != 0) {
-        JLI_StrCat(new_runpath, ":");
-        JLI_StrCat(new_runpath, runpath);
-      }
-
-      if( putenv(new_runpath) != 0) {
-        exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
-                    properly */
-      }
-
-      /*
-       * Unix systems document that they look at LD_LIBRARY_PATH only
-       * once at startup, so we have to re-exec the current executable
-       * to get the changed environment variable to have an effect.
-       */
-
-#ifdef __solaris__
-      /*
-       * If dmpath is not NULL, remove the data model specific string
-       * in the environment for the exec'ed child.
-       */
-
-      if( dmpath != NULL)
-        (void)UnsetEnv((wanted==32)?"LD_LIBRARY_PATH_32":"LD_LIBRARY_PATH_64");
-#endif
-
-      newenvp = environ;
-
       {
         char *newexec = execname;
 #ifdef DUAL_MODE
@@ -549,17 +363,16 @@
           argv[0] = newexec;
         }
 #endif
-
+        JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
         (void)fflush(stdout);
         (void)fflush(stderr);
-        execve(newexec, argv, newenvp);
+        execv(newexec, argv);
         JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
 
 #ifdef DUAL_MODE
         if (running != wanted) {
           JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
 #  ifdef __solaris__
-
 #    ifdef __sparc
           JLI_ReportErrorMessage(JRE_ERROR6);
 #    else
@@ -570,13 +383,11 @@
 #endif
 
       }
-
       exit(1);
     }
 
 }
 
-
 /*
  * On Solaris VM choosing is done by the launcher (java.c).
  */
@@ -1123,6 +934,7 @@
             printf(" %s", argv[i]);
         printf("\n");
     }
+    JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
     (void)fflush(stdout);
     (void)fflush(stderr);
     execv(wanted, argv);
--- a/test/tools/launcher/Arrrghs.java	Sun Nov 29 15:24:32 2009 -0800
+++ b/test/tools/launcher/Arrrghs.java	Fri Nov 20 11:01:32 2009 -0800
@@ -25,7 +25,7 @@
  * @test
  * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881
  * @summary Argument parsing validation.
- * @compile Arrrghs.java TestHelper.java
+ * @compile -XDignore.symbol.file Arrrghs.java TestHelper.java
  * @run main Arrrghs
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/launcher/ExecutionEnvironment.java	Fri Nov 20 11:01:32 2009 -0800
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4780570 4731671 6354700 6367077 6670965 4882974
+ * @summary Checks for LD_LIBRARY_PATH and execution  on *nixes
+ * @compile -XDignore.symbol.file ExecutionEnvironment.java TestHelper.java
+ * @run main ExecutionEnvironment
+ */
+
+/*
+ * This test tests for various things as follows:
+ * Ensures that:
+ *   1. uneccessary execs do not occur
+ *   2. the environment is pristine,  users environment variable wrt.
+ *      LD_LIBRARY_PATH if set are not modified in any way.
+ *   3. the correct vm is chosen with -server and -client options
+ *   4. the VM on Solaris correctly interprets the LD_LIBRARY_PATH32
+ *      and LD_LIBRARY_PATH64 variables if set by the user, ie.
+ *      i. on 32 bit systems:
+ *         a. if LD_LIBRARY_PATH32 is set it will override LD_LIBRARY_PATH
+ *         b. LD_LIBRARY_PATH64 is ignored if set
+ *      ii. on 64 bit systems:
+ *            a. if LD_LIBRARY_PATH64 is set it will override LD_LIBRARY_PATH
+ *            b. LD_LIBRARY_PATH32 is ignored if set
+ *   5. no extra symlink exists on Solaris ie.
+ *      jre/lib/$arch/libjvm.so -> client/libjvm.so
+ * TODO:
+ *      a. perhaps we need to add a test to audit all environment variables are
+ *         in pristine condition after the launch, there may be a few that the
+ *         launcher may add as implementation details.
+ *      b. add a pldd for solaris to ensure only one libjvm.so is linked
+ */
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class ExecutionEnvironment {
+    static final String LD_LIBRARY_PATH    = "LD_LIBRARY_PATH";
+    static final String LD_LIBRARY_PATH_32 = LD_LIBRARY_PATH + "_32";
+    static final String LD_LIBRARY_PATH_64 = LD_LIBRARY_PATH + "_64";
+
+    // Note: these paths need not exist on the filesytem
+    static final String LD_LIBRARY_PATH_VALUE    = "/Bridge/On/The/River/Kwai";
+    static final String LD_LIBRARY_PATH_32_VALUE = "/Lawrence/Of/Arabia";
+    static final String LD_LIBRARY_PATH_64_VALUE = "/A/Passage/To/India";
+
+    static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG";
+    static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC";
+
+    static final String[] LD_PATH_STRINGS = {
+        LD_LIBRARY_PATH + "=" + LD_LIBRARY_PATH_VALUE,
+        LD_LIBRARY_PATH_32 + "=" + LD_LIBRARY_PATH_32_VALUE,
+        LD_LIBRARY_PATH_64 + "=" + LD_LIBRARY_PATH_64_VALUE
+    };
+
+    static final File testJarFile = new File("EcoFriendly.jar");
+
+    static int errors = 0;
+    static int passes = 0;
+
+    private static void createTestJar() {
+        try {
+            List<String> codeList = new ArrayList<String>();
+            codeList.add("static void printValue(String name, boolean property) {\n");
+            codeList.add("    String value = (property) ? System.getProperty(name) : System.getenv(name);\n");
+            codeList.add("    System.out.println(name + \"=\" + value);\n");
+            codeList.add("}\n");
+            codeList.add("public static void main(String... args) {\n");
+            codeList.add("    System.out.println(\"Execute test:\");\n");
+            codeList.add("    printValue(\"os.name\", true);\n");
+            codeList.add("    printValue(\"os.arch\", true);\n");
+            codeList.add("    printValue(\"os.version\", true);\n");
+            codeList.add("    printValue(\"sun.arch.data.model\", true);\n");
+            codeList.add("    printValue(\"java.library.path\", true);\n");
+            codeList.add("    printValue(\"" + LD_LIBRARY_PATH + "\", false);\n");
+            codeList.add("    printValue(\"" + LD_LIBRARY_PATH_32 + "\", false);\n");
+            codeList.add("    printValue(\"" + LD_LIBRARY_PATH_64 + "\", false);\n");
+            codeList.add("}\n");
+            String[] clist = new String[codeList.size()];
+            TestHelper.createJar(testJarFile, codeList.toArray(clist));
+        } catch (FileNotFoundException fnfe) {
+            throw new RuntimeException(fnfe);
+        }
+    }
+
+    /*
+     * tests if the launcher pollutes the LD_LIBRARY_PATH variables ie. there
+     * should not be any new variables or pollution/mutations of any kind, the
+     * environment should be pristine.
+     */
+    private static void ensureEcoFriendly() {
+        TestHelper.TestResult tr = null;
+
+        Map<String, String> env = new HashMap<String, String>();
+        for (String x : LD_PATH_STRINGS) {
+            String pairs[] = x.split("=");
+            env.put(pairs[0], pairs[1]);
+        }
+
+        tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                testJarFile.getAbsolutePath());
+
+        if (!tr.isNotZeroOutput()) {
+            throw new RuntimeException("Error: No output at all. Did the test execute ?");
+        }
+
+        for (String x : LD_PATH_STRINGS) {
+            if (!tr.contains(x)) {
+                System.out.println("FAIL: did not get <" + x + ">");
+                System.out.println(tr);
+                errors++;
+            } else {
+                passes++;
+            }
+        }
+    }
+
+    /*
+     * ensures that there are no execs as long as we are in the same
+     * data model
+     */
+    static void ensureNoExec() {
+        Map<String, String> env = new HashMap<String, String>();
+        env.put(JLDEBUG_KEY, "true");
+        TestHelper.TestResult tr =
+                TestHelper.doExec(env, TestHelper.javaCmd, "-version");
+        if (tr.testOutput.contains(EXPECTED_MARKER)) {
+            System.out.println("FAIL: EnsureNoExecs: found expected warning <" +
+                    EXPECTED_MARKER +
+                    "> the process execing ?");
+            errors++;
+        } else {
+            passes++;
+        }
+        return;
+    }
+
+    /*
+     * This test ensures that LD_LIBRARY_PATH* values are interpreted by the VM
+     * and the expected java.library.path behaviour.
+     * For Generic platforms (All *nixes):
+     *    * All LD_LIBRARY_PATH variable should be on java.library.path
+     * For Solaris 32-bit
+     *    * The LD_LIBRARY_PATH_32 should override LD_LIBRARY_PATH if specified
+     * For Solaris 64-bit
+     *    * The LD_LIBRARY_PATH_64 should override LD_LIBRARY_PATH if specified
+     */
+
+    static void verifyJavaLibraryPath() {
+        TestHelper.TestResult tr = null;
+
+        Map<String, String> env = new HashMap<String, String>();
+
+
+        if (TestHelper.isLinux) {
+            for (String x : LD_PATH_STRINGS) {
+                String pairs[] = x.split("=");
+                env.put(pairs[0], pairs[1]);
+            }
+
+            tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                    testJarFile.getAbsolutePath());
+            verifyJavaLibraryPathGeneric(tr);
+        } else {
+            // no override
+            env.clear();
+            env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+            tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                    testJarFile.getAbsolutePath());
+            verifyJavaLibraryPathGeneric(tr);
+
+            env.clear();
+            for (String x : LD_PATH_STRINGS) {
+                String pairs[] = x.split("=");
+                env.put(pairs[0], pairs[1]);
+            }
+
+            // verify the override occurs, since we know the invocation always
+            // uses by default is 32-bit, therefore we also set the test
+            // expectation to be the same.
+            tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                    testJarFile.getAbsolutePath());
+            verifyJavaLibraryPathOverride(tr, true);
+
+            // try changing the model from 32 to 64 bit
+            if (TestHelper.java64Cmd != null && TestHelper.is32Bit) {
+                // verify the override occurs
+                env.clear();
+                for (String x : LD_PATH_STRINGS) {
+                    String pairs[] = x.split("=");
+                    env.put(pairs[0], pairs[1]);
+                }
+                tr = TestHelper.doExec(env, TestHelper.javaCmd, "-d64", "-jar",
+                    testJarFile.getAbsolutePath());
+                verifyJavaLibraryPathOverride(tr, false);
+
+                // no override
+                env.clear();
+                env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+                tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                        testJarFile.getAbsolutePath());
+                verifyJavaLibraryPathGeneric(tr);
+            }
+
+            // try changing the model from 64 to 32 bit
+            if (TestHelper.java64Cmd != null && TestHelper.is64Bit) {
+                // verify the override occurs
+                env.clear();
+                for (String x : LD_PATH_STRINGS) {
+                    String pairs[] = x.split("=");
+                    env.put(pairs[0], pairs[1]);
+                }
+                tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar",
+                    testJarFile.getAbsolutePath());
+                verifyJavaLibraryPathOverride(tr, true);
+
+                // no override
+                env.clear();
+                env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+                tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar",
+                        testJarFile.getAbsolutePath());
+                verifyJavaLibraryPathGeneric(tr);
+            }
+        }
+    }
+
+    private static void verifyJavaLibraryPathGeneric(TestHelper.TestResult tr) {
+        if (!tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) {
+            System.out.print("FAIL: verifyJavaLibraryPath: ");
+            System.out.println(" java.library.path does not contain " +
+                    LD_LIBRARY_PATH_VALUE);
+            System.out.println(tr);
+            errors++;
+        } else {
+            passes++;
+        }
+    }
+
+    private static void verifyJavaLibraryPathOverride(TestHelper.TestResult tr,
+            boolean is32Bit) {
+        // make sure the 32/64 bit value exists
+        if (!tr.matches("java.library.path=.*" +
+                (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE) + ".*")) {
+            System.out.print("FAIL: verifyJavaLibraryPathOverride: ");
+            System.out.println(" java.library.path does not contain " +
+                    (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE));
+            System.out.println(tr);
+            errors++;
+        } else {
+            passes++;
+        }
+        // make sure the generic value is absent
+        if (tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) {
+            System.out.print("FAIL: verifyJavaLibraryPathOverride: ");
+            System.out.println(" java.library.path contains " +
+                    LD_LIBRARY_PATH_VALUE);
+            System.out.println(tr);
+            errors++;
+        } else {
+            passes++;
+        }
+    }
+
+    /*
+     * ensures we have indeed exec'ed the correct vm of choice, all VMs support
+     * -server, however 32-bit VMs support -client and -server.
+     */
+    static void verifyVmSelection() {
+
+        TestHelper.TestResult tr = null;
+
+        if (TestHelper.is32Bit) {
+            tr = TestHelper.doExec(TestHelper.javaCmd, "-client", "-version");
+            if (!tr.matches("Java.*Client VM.*")) {
+                System.out.println("FAIL: the expected vm -client did launch");
+                System.out.println(tr);
+                errors++;
+            } else {
+                passes++;
+            }
+        }
+        tr = TestHelper.doExec(TestHelper.javaCmd, "-server", "-version");
+        if (!tr.matches("Java.*Server VM.*")) {
+            System.out.println("FAIL: the expected vm -server did launch");
+            System.out.println(tr);
+            errors++;
+        } else {
+            passes++;
+        }
+    }
+
+    /*
+     * checks to see there is no extra libjvm.so than needed
+     */
+    static void verifyNoSymLink() {
+        if (TestHelper.is64Bit) {
+            return;
+        }
+
+        File symLink = null;
+        String libPathPrefix = TestHelper.isSDK ? "jre/lib" : "/lib";
+        symLink = new File(TestHelper.JAVAHOME, libPathPrefix +
+                TestHelper.getJreArch() + "/libjvm.so");
+        if (symLink.exists()) {
+            System.out.println("FAIL: The symlink exists " +
+                    symLink.getAbsolutePath());
+            errors++;
+        } else {
+            passes++;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        if (TestHelper.isWindows) {
+            System.out.println("Warning: noop on windows");
+            return;
+        }
+        // create our test jar first
+        createTestJar();
+        ensureNoExec();
+        verifyVmSelection();
+        ensureEcoFriendly();
+        verifyJavaLibraryPath();
+        verifyNoSymLink();
+        if (errors > 0) {
+            throw new Exception("ExecutionEnvironment: FAIL: with " +
+                    errors + " errors and passes " + passes );
+        } else {
+            System.out.println("ExecutionEnvironment: PASS " + passes);
+        }
+    }
+}
--- a/test/tools/launcher/SolarisDataModel.sh	Sun Nov 29 15:24:32 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-# Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-
-# @test
-# @bug 4780570
-# @run shell SolarisDataModel.sh
-# @summary Verify Solaris SPARC -d32 and -d64 options work with preset LD_LIBRARY_PATH
-# @author Joseph D. Darcy
-
-# Test to see if presetting LD_LIBRARY_PATH affects the treatment of
-# -d32 and -d64 options; also checks that -d<n> options result in the
-# desired data model.
-
-# If the test is not being run on a Solaris SPARC box SPARC the test
-# succeeds immediately.
-
-OS=`uname -s`;
-
-case "$OS" in
-	SunOS )
-		# ARCH should be sparc or i386
-		ARCH=`uname -p`
-		case "$ARCH" in 
-			sparc)
-			PATHSEP=":"
-			;;
-
-			* )
-			echo "Non-SPARC Solaris environment; test vacuously succeeds."
-			exit 0
-		esac
-	;;
-
-	* )
-	echo "Not a Solaris SPARC environment; test vacuously succeeds."
-	exit 0;
-	;;
-esac
-
-
-# Verify directory context variables are set
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-if [ "${TESTSRC}" = "" ]
-then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-
-JAVAC="$TESTJAVA/bin/javac"
-
-# Create our little Java tests on the fly
-( printf "public class GetDataModel {"
-  printf "   public static void main(String argv[]) {"
-  printf "      System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));"
-  printf "   }"
-  printf "}"
-) > GetDataModel.java
-
-$JAVAC  GetDataModel.java
-
-( printf "public class GetLdLibraryPath {"
-  printf "   public static void main(String argv[]) {"
-  printf "      System.out.println(System.getProperty(\"java.library.path\"));"
-  printf "   }"
-  printf "}"
-) > GetLdLibraryPath.java
-
-$JAVAC  GetLdLibraryPath.java
-
-
-
-# All preconditions are met; run the tests
-
-
-# Construct path to 32-bit Java executable
-JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}."
-
-
-# Construct path to 64-bit Java executable, might not exist
-JAVA64="$TESTJAVA/bin/sparcv9/java -classpath $TESTCLASSES${PATHSEP}."
-JAVA64FILE="$TESTJAVA/bin/sparcv9/java"
-
-
-# java -d32 tests
-
-LD_LIBRARY_PATH=""
-export LD_LIBRARY_PATH
-
-DM=`$JAVA -d32 GetDataModel`
-case "$DM" in
-        32 )
-        ;;
-
-        * )
-	echo "The combination \"java -d32\" failed."
-	echo $DM
-        exit 1
-esac
-
-# Rerun test with LD_LIBRARY_PATH preset
-LD_LIBRARY_PATH=`$JAVA GetLdLibraryPath`;
-DM=`$JAVA -d32 GetDataModel`
-case "$DM" in
-        32 )
-        ;;
-
-        * )
-	echo "The combination \"java -d32\" failed with preset LD_LIBRARY_PATH."
-	echo $DM
-        exit 1
-esac
-
-# Reset LD_LIBRARY_PATH
-LD_LIBRARY_PATH=
-
-
-# Test for 64-bit executable
-
-if [ -f $JAVA64FILE ]; then
-
-	DM=`$JAVA -d64 GetDataModel`
-	case "$DM" in
-        	64 )
-        	;;
-
-        	* )
-		echo "The combination \"java -d64\" failed."
-        	exit 1
-	esac
-
-	DM=`$JAVA64 -d32 GetDataModel`
-	case "$DM" in
-        	32 )
-        	;;
-
-        	* )
-		echo "The combination \"sparcv9/java -d32\" failed."
-        	exit 1
-	esac
-
-	DM=`$JAVA64 -d64 GetDataModel`
-	case "$DM" in
-        	64 )
-        	;;
-
-        	* )
-		echo "The combination \"sparcv9/java -d64\" failed."
-        	exit 1
-	esac
-
-	# Rerun tests with LD_LIBRARY_PATH preset
-	LD_LIBRARY_PATH=`$JAVA GetLdLibraryPath`;
-	echo "Presetting LD_LIBRARY_PATH"
-
-	DM=`$JAVA -d64 GetDataModel`
-	case "$DM" in
-        	64 )
-        	;;
-
-        	* )
-		echo "The combination \"java -d64\" failed with preset LD_LIBRARY_PATH."
-        	exit 1
-	esac
-
-	DM=`$JAVA64 -d32 GetDataModel`
-	case "$DM" in
-        	32 )
-        	;;
-
-        	* )
-		echo "The combination \"sparcv9/java -d32\" failed with preset LD_LIBRARY_PATH."
-        	exit 1
-	esac
-
-	DM=`$JAVA64 -d64 GetDataModel`
-	case "$DM" in
-        	64 )
-        	;;
-
-        	* )
-		echo "The combination \"sparcv9/java -d64\" failed with preset LD_LIBRARY_PATH."
-        	exit 1
-	esac
-
-else
-  echo "Warning: no 64-bit components found; only java -d32 tests have been run."
-fi
-exit 0;
--- a/test/tools/launcher/SolarisRunpath.sh	Sun Nov 29 15:24:32 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-# Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-
-
-# @test
-# @bug 4731671
-# @build libraryCaller
-# @run shell SolarisRunpath.sh
-# @summary Verify that Solaris LD_LIBRARY_PATH rules are followed
-# @author Joseph D. Darcy
-
-# The launcher has been updated to properly take account of Solaris
-# LD_LIBRARY_PATH rules when constructing the runpath for the Java
-# executable.  That is, data model dependent LD_LIBRARY_PATH variables
-# are tested for and override LD_LIBRARY_PATH if present.  The current
-# launcher design relies on LD_LIBRARY_PATH settings to ensure the
-# proper jre/jdk libraries are opening during program execution.  In
-# the future, this dependence might be removed by having the vm
-# explicitly dlopen the needed files.  If that change occurs, this
-# test will be harmless but no long relevant.
-
-# A more robust test for Solaris SPARC would set the different
-# LD_LIBRARY_PATH variables while also varying the -d[32|64] options
-# to make sure the LD_LIBRARY_PATH of the *target* data model were
-# being respected.  That is "java -d64" should use the 64-bit
-# LD_LIBRARY_PATH while "java -d32" should use the 32-bit
-# LD_LIBRARY_PATH regardless of the data model of the "java" binary.
-# However, by default builds do not contain both 32 and 64 bit
-# components so such a test would often not be applicable.
-
-
-# If the test is not being run on a Solaris box, SPARC or x86, the
-# test succeeds immediately.
-
-OS=`uname -s`;
-
-case "$OS" in
-	SunOS )
-	PATHSEP=":"
-	;;
-
-	* )
-	echo "Not a Solaris environment; test vacuously succeeds."
-	exit 0;
-	;;
-esac
-
-# Verify directory context variables are set
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-if [ "${TESTSRC}" = "" ]
-then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-# Construct paths to default Java executables
-JAVAC="$TESTJAVA/bin/javac"
-
-
-# Create our little Java test on the fly
-( printf "public class GetDataModel {"
-  printf "   public static void main(String argv[]) {"
-  printf "      System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));"
-  printf "   }"
-  printf "}"
-) > GetDataModel.java
-
-$JAVAC GetDataModel.java
-
-
-# ARCH should be sparc or i386
-ARCH=`uname -p`
-case "$ARCH" in 
-	sparc | i386 )
-	;;
-
-	* )
-	echo "Unrecognized architecture; test fails."
-	exit 1
-esac
-
-# The following construction may not work as desired in a
-# 64-bit build.
-JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}."
-
-# Determine data model
-DM=`$JAVA GetDataModel`
-
-# verify DM is 32 or 64
-case "$DM" in 
-	32 )
-	ODM=64;
-	;;
-	
-	64 )
-	ODM=32;
-	;;
-
-	* )
-	echo "Unknown data model \"$DM\"; test fails."
-	exit 1
-esac
-
-# -------------------- Test 1 --------------------
-
-LD_LIBRARY_PATH=$TESTSRC/lib/$ARCH/lib$DM
-export LD_LIBRARY_PATH
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-	
-# With plain LD_LIBRARY_PATH, result should always be 0
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "0" ]; 
-then
-	echo "Not using LD_LIBRARY_PATH; test fails."
-	exit 1
-fi
-
-# The following two tests sets both data model dependent
-# LD_LIBRARY_PATH variables individually.
-
-# -------------------- Test 2 --------------------
-
-# Set opposite data model variable; should return same result
-# as plain LD_LIBRARY_PATH.
-
-if [ "${DM}" = "32"  ]; then
-	LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_64
-else
-	LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_32
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "0" ]; 
-then
-	echo "Using LD_LIBRARY_PATH_$ODM for $DM binary;"
-	echo "test fails."
-	exit 1
-fi
-
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-
-# -------------------- Test 3 --------------------
-
-# Set appropriate data model variable; result should match
-# data model.
-if [ "${DM}" = "32"  ]; then
-	LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_32
-else
-	LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_64
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "$DM" ]; 
-then
-	echo "Data model dependent LD_LIBRARY_PATH_$DM"
-	echo "not overriding LD_LIBRARY_PATH; test fails."
-	exit 1
-fi
-
-unset LD_LIBRARY_PATH
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-
-# -------------------- Test 4 --------------------
-
-# Have only data model dependent LD_LIBRARY_PATH set; result
-# should match data model.
-
-if [ "${DM}" = "32"  ]; then
-	LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_32
-else
-	LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_64
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "$DM" ]; 
-then
-	echo "Not using data-model dependent LD_LIBRARY_PATH; test fails."
-	exit 1
-fi
-
-# All tests have passed
-exit 0
--- a/test/tools/launcher/TestHelper.java	Sun Nov 29 15:24:32 2009 -0800
+++ b/test/tools/launcher/TestHelper.java	Fri Nov 20 11:01:32 2009 -0800
@@ -39,18 +39,36 @@
  */
 public enum TestHelper {
     INSTANCE;
-    static final String JAVAHOME = System.getProperty("java.home", ".");
+    static final String JAVAHOME = System.getProperty("java.home");
     static final boolean isSDK = JAVAHOME.endsWith("jre");
     static final String javaCmd;
+    static final String java64Cmd;
     static final String javacCmd;
     static final JavaCompiler compiler;
 
-    static final boolean debug = Boolean.getBoolean("Arrrghs.Debug");
+    static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
     static final boolean isWindows =
             System.getProperty("os.name", "unknown").startsWith("Windows");
+    static final boolean is64Bit =
+            System.getProperty("sun.arch.data.model").equals("64");
+    static final boolean is32Bit =
+            System.getProperty("sun.arch.data.model").equals("32");
+    static final boolean isSolaris =
+            System.getProperty("os.name", "unknown").startsWith("SunOS");
+    static final boolean isLinux =
+            System.getProperty("os.name", "unknown").startsWith("Linux");
+    static final boolean isDualMode = isSolaris;
+    static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
+
     static int testExitValue = 0;
 
     static {
+        if (is64Bit && is32Bit) {
+            throw new RuntimeException("arch model cannot be both 32 and 64 bit");
+        }
+        if (!is64Bit && !is32Bit) {
+            throw new RuntimeException("arch model is not 32 or 64 bit ?");
+        }
         compiler = ToolProvider.getSystemJavaCompiler();
         File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
             : new File(JAVAHOME, "bin");
@@ -69,6 +87,33 @@
         if (!javacCmdFile.canExecute()) {
             throw new RuntimeException("java <" + javacCmd + "> must exist");
         }
+        if (isSolaris) {
+            File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
+            File java64CmdFile= new File(sparc64BinDir, "java");
+            if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
+                java64Cmd = java64CmdFile.getAbsolutePath();
+            } else {
+                java64Cmd = null;
+            }
+        } else {
+            java64Cmd = null;
+        }
+    }
+
+    /*
+     * usually the jre/lib/arch-name is the same as os.arch, except for x86.
+     */
+    static String getJreArch() {
+        String arch = System.getProperty("os.arch");
+        return arch.equals("x86") ? "i386" : arch;
+    }
+
+    /*
+     * A convenience method to create a jar with jar file name and defs
+     */
+    static void createJar(File jarName, String... mainDefs)
+            throws FileNotFoundException{
+        createJar(null, jarName, new File("Foo"), mainDefs);
     }
 
     /*
@@ -123,16 +168,23 @@
         }
     }
 
+    static TestResult doExec(String...cmds) {
+        return doExec(null, cmds);
+    }
+
     /*
      * A method which executes a java cmd and returns the results in a container
      */
-    static TestResult doExec(String...cmds) {
+    static TestResult doExec(Map<String, String> envToSet, String...cmds) {
         String cmdStr = "";
         for (String x : cmds) {
             cmdStr = cmdStr.concat(x + " ");
         }
         ProcessBuilder pb = new ProcessBuilder(cmds);
         Map<String, String> env = pb.environment();
+        if (envToSet != null) {
+            env.putAll(envToSet);
+        }
         BufferedReader rdr = null;
         try {
             List<String> outputList = new ArrayList<String>();
@@ -163,21 +215,25 @@
         List<String> testOutput;
 
         public TestResult(String str, int rv, List<String> oList) {
-            status = new StringBuilder(str);
+            status = new StringBuilder("Executed command: " + str + "\n");
             exitValue = rv;
             testOutput = oList;
         }
 
+        void appendStatus(String x) {
+            status = status.append("  " + x + "\n");
+        }
+
         void checkNegative() {
             if (exitValue == 0) {
-                status = status.append("  Error: test must not return 0 exit value");
+                appendStatus("Error: test must not return 0 exit value");
                 testExitValue++;
             }
         }
 
         void checkPositive() {
             if (exitValue != 0) {
-                status = status.append("  Error: test did not return 0 exit value");
+                appendStatus("Error: test did not return 0 exit value");
                 testExitValue++;
             }
         }
@@ -188,7 +244,7 @@
 
         boolean isZeroOutput() {
             if (!testOutput.isEmpty()) {
-                status = status.append("  Error: No message from cmd please");
+                appendStatus("Error: No message from cmd please");
                 testExitValue++;
                 return false;
             }
@@ -197,19 +253,20 @@
 
         boolean isNotZeroOutput() {
             if (testOutput.isEmpty()) {
-                status = status.append("  Error: Missing message");
+                appendStatus("Error: Missing message");
                 testExitValue++;
                 return false;
             }
             return true;
         }
 
+        @Override
         public String toString() {
-            if (debug) {
-                for (String x : testOutput) {
-                    status = status.append(x + "\n");
-                }
+            status = status.append("++++Test Output Begin++++\n");
+            for (String x : testOutput) {
+                appendStatus(x);
             }
+            status = status.append("++++Test Output End++++\n");
             return status.toString();
         }
 
@@ -219,7 +276,18 @@
                     return true;
                 }
             }
-            status = status.append("   Error: string <" + str + "> not found ");
+            appendStatus("Error: string <" + str + "> not found");
+            testExitValue++;
+            return false;
+        }
+
+        boolean matches(String stringToMatch) {
+          for (String x : testOutput) {
+                if (x.matches(stringToMatch)) {
+                    return true;
+                }
+            }
+            appendStatus("Error: string <" + stringToMatch + "> not found");
             testExitValue++;
             return false;
         }
--- a/test/tools/launcher/libraryCaller.c	Sun Nov 29 15:24:32 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-/*
- *
- *
- * Indictly used by SolarisRunpath.sh; this file is used to generate
- * the shared objects:
- *
- * ./lib/sparc/lib32/liblibrary.so
- * ./lib/sparc/lib32/lib32/liblibrary.so
- *
- * ./lib/sparc/lib64/liblibrary.so
- * ./lib/sparc/lib64/lib64/liblibrary.so
- *
- * ./lib/i386/lib32/liblibrary.so
- * ./lib/i386/lib32/lib32/liblibrary.so
- *
- * The function defined below returns either 0 or the size of an
- * integer in the data model used to compile the file (32 for ILP; 64
- * for LP).  The libraries in ./lib/$ARCH/lib$DM return 0; those in
- * ./lib/$ARCH/lib$DM/lib$DM return 32 or 64.
- */
-
-
-#include <jni.h>
-#include "libraryCaller.h"
-
-#ifndef RETURN_VALUE
-#define RETURN_VALUE 0
-#endif
-
-JNIEXPORT jint JNICALL Java_libraryCaller_number
-(JNIEnv *je, jclass jc) {
-  return RETURN_VALUE;
-}
--- a/test/tools/launcher/libraryCaller.h	Sun Nov 29 15:24:32 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-/* DO NOT EDIT THIS FILE - it is machine generated */
-
-#include <jni.h>
-/* Header for class libraryCaller */
-
-#ifndef _Included_libraryCaller
-#define _Included_libraryCaller
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     libraryCaller
- * Method:    number
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_libraryCaller_number
-  (JNIEnv *, jclass);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
--- a/test/tools/launcher/libraryCaller.java	Sun Nov 29 15:24:32 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-
-/*
- *
- *
- * Used by SolarisRunpath.sh to help test if the launcher fully
- * respects Solaris LD_LIBRARY_PATH semantics.  The ./lib directory is
- * structured so that the results of the dynamically linked number
- * method varies depending on the value the data model dependent
- * LD_LIBRARY_PATH variable.
- */
-
-
-
-class libraryCaller {
-    static {
-        System.loadLibrary("library");
-    }
-    static native int number();
-
-    public static void main(String argv[]) {
-        System.out.println(number());
-    }
-}