This commit introduces C++ wrapper classes for Java heap objects.
[cacao.git] / src / vm / properties.c
index b053f4499abc699944acd8eaa05d117690999aa8..599e05879ea0bb81a5ec30eef945aac3825c5417 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/properties.c - handling commandline properties
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
-   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
-   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
-   Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+*/
 
-   Authors: Christian Thalinger
 
-   Changes:
+#include "config.h"
 
-   $Id: properties.c 4003 2005-12-22 15:07:43Z twisti $
+#include <stdint.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/utsname.h>
 
-*/
+#include "mm/memory.h"
 
+#include "native/jni.h"
+#include "native/llni.h"
 
-#include "config.h"
-#include "vm/types.h"
+#include "toolbox/list.h"
+#include "toolbox/util.h"
 
 #include "vm/global.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_util_Properties.h"
-#include "toolbox/list.h"
-#include "vm/method.h"
-#include "vm/stringlocal.h"
+#include "vm/properties.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
 #include "vm/jit/asmpart.h"
 
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+#include "vmcore/os.hpp"
+
 
-/* temporary property structure ***********************************************/
+/* internal property structure ************************************************/
 
-typedef struct list_properties_entry list_properties_entry;
+typedef struct list_properties_entry_t list_properties_entry_t;
 
-struct list_properties_entry {
-       char     *key;
-       char     *value;
-       listnode linkage;
+struct list_properties_entry_t {
+       const char* key;
+       const char* value;
+       listnode_t  linkage;
 };
 
 
 /* global variables ***********************************************************/
 
-static list *list_properties = NULL;
-
-static java_util_Properties *psystem;
-static methodinfo *mput;
+static list_t *list_properties = NULL;
 
 
 /* properties_init *************************************************************
 
-   Initialize the properties list.
+   Initialize the properties list and fill the list with default
+   values.
 
 *******************************************************************************/
 
-bool properties_init(void)
+void properties_init(void)
 {
-       list_properties = NEW(list);
-
-       list_init(list_properties, OFFSET(list_properties_entry, linkage));
-
-       /* everything's ok */
+       TRACESUBSYSTEMINITIALIZATION("properties_init");
 
-       return true;
+       list_properties = list_create(OFFSET(list_properties_entry_t, linkage));
 }
 
 
-/* properties_postinit *********************************************************
+/* properties_set **************************************************************
 
-   Post-initialize the properties.  The passed properties table is the
-   Java system properties table.
+   Fill the properties list with default values.
 
 *******************************************************************************/
 
-bool properties_postinit(java_util_Properties *p)
+void properties_set(void)
 {
-       /* set global Java system properties pointer */
+       int             len;
+       char           *p;
 
-       psystem = p;
+       char           *java_home;
+       char           *boot_class_path;
 
-       /* search for method to add properties */
+#if defined(ENABLE_JAVASE)
+       char           *class_path;
+       char           *boot_library_path;
+       char           *extdirs;
+       char           *endorseddirs;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       char           *cwd;
+       char           *env_user;
+       char           *env_home;
+       char           *env_lang;
+       char           *lang;
+       char           *country;
+       struct utsname *utsnamebuf;
+
+       char           *java_library_path;
+# endif
+#endif
+
+#if defined(ENABLE_JRE_LAYOUT)
+       /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
+
+       p = MNEW(char, 4096);
+
+       if (readlink("/proc/self/exe", p, 4095) == -1)
+               vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
+
+       /* We have a path like:
+
+          /path/to/executable/bin/java
+
+          or
+          
+          /path/to/executeable/jre/bin/java
+
+          Now let's strip two levels. */
+
+       p = os_dirname(p);
+       p = os_dirname(p);
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       /* Set java.home. */
+
+       java_home = strdup(p);
+
+       /* Set the path to Java core native libraries. */
+
+       len = strlen(java_home) + strlen("/lib/classpath") + strlen("0");
+
+       boot_library_path = MNEW(char, len);
+
+       strcpy(boot_library_path, java_home);
+       strcat(boot_library_path, "/lib/classpath");
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       /* Find correct java.home.  We check if there is a JRE
+          co-located. */
+
+       /* NOTE: We use the server VM here as it should be available on
+          all architectures. */
+
+       len =
+               strlen(p) +
+               strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
+               strlen("0");
+
+       java_home = MNEW(char, len);
+
+       strcpy(java_home, p);
+       strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
+
+       /* Check if that libjvm.so exists. */
+
+       if (os_access(java_home, F_OK) == 0) {
+               /* Yes, we add /jre to java.home. */
+
+               strcpy(java_home, p);
+               strcat(java_home, "/jre");
+       }
+       else {
+               /* No, java.home is parent directory. */
+
+               strcpy(java_home, p);
+       }
+
+       /* Set the path to Java core native libraries. */
+
+       len = strlen(java_home) + strlen("/lib/"JAVA_ARCH) + strlen("0");
+
+       boot_library_path = MNEW(char, len);
+
+       strcpy(boot_library_path, java_home);
+       strcat(boot_library_path, "/lib/"JAVA_ARCH);
+
+# else
+#  error unknown classpath configuration
+# endif
+
+       /* Free path. */
+
+       MFREE(p, char, len);
+
+#else
+       java_home         = CACAO_PREFIX;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       boot_library_path = JAVA_RUNTIME_LIBRARY_LIBDIR"/classpath";
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       boot_library_path = JAVA_RUNTIME_LIBRARY_LIBDIR;
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       /* No boot_library_path required. */
+
+# else
+#  error unknown classpath configuration
+# endif
+#endif
+
+       properties_add("java.home", java_home);
+
+       /* Set the bootclasspath. */
+
+       p = getenv("BOOTCLASSPATH");
+
+       if (p != NULL) {
+               boot_class_path = MNEW(char, strlen(p) + strlen("0"));
+               strcpy(boot_class_path, p);
+       }
+       else {
+#if defined(ENABLE_JRE_LAYOUT)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+               len =
+                       strlen(java_home) + strlen("/share/cacao/vm.zip:") +
+                       strlen(java_home) + strlen("/share/classpath/glibj.zip") +
+                       strlen("0");
+
+               boot_class_path = MNEW(char, len);
+
+               strcpy(boot_class_path, java_home);
+               strcat(boot_class_path, "/share/cacao/vm.zip");
+               strcat(boot_class_path, ":");
+               strcat(boot_class_path, java_home);
+               strcat(boot_class_path, "/share/classpath/glibj.zip");
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+               /* This is the bootclasspath taken from HotSpot (see
+                  hotspot/src/share/vm/runtime/os.cpp
+                  (os::set_boot_path)). */
+
+               len =
+                       strlen(java_home) + strlen("/lib/resources.jar:") +
+                       strlen(java_home) + strlen("/lib/rt.jar:") +
+                       strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
+                       strlen(java_home) + strlen("/lib/jsse.jar:") +
+                       strlen(java_home) + strlen("/lib/jce.jar:") +
+                       strlen(java_home) + strlen("/lib/charsets.jar:") +
+                       strlen(java_home) + strlen("/classes") +
+                       strlen("0");
+
+               boot_class_path = MNEW(char, len);
+
+               strcpy(boot_class_path, java_home);
+               strcat(boot_class_path, "/lib/resources.jar:");
+               strcat(boot_class_path, java_home);
+               strcat(boot_class_path, "/lib/rt.jar:");
+               strcat(boot_class_path, java_home);
+               strcat(boot_class_path, "/lib/sunrsasign.jar:");
+               strcat(boot_class_path, java_home);
+               strcat(boot_class_path, "/lib/jsse.jar:");
+               strcat(boot_class_path, java_home);
+               strcat(boot_class_path, "/lib/jce.jar:");
+               strcat(boot_class_path, java_home);
+               strcat(boot_class_path, "/lib/charsets.jar:");
+               strcat(boot_class_path, java_home);
+               strcat(boot_class_path, "/classes");
+
+# else
+#  error unknown classpath configuration
+# endif
+#else
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+               len =
+                       strlen(CACAO_VM_ZIP) +
+                       strlen(":") +
+                       strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
+                       strlen("0");
+
+               boot_class_path = MNEW(char, len);
+
+               strcpy(boot_class_path, CACAO_VM_ZIP);
+               strcat(boot_class_path, ":");
+               strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_CLASSES);
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+               /* This is the bootclasspath taken from HotSpot (see
+                  hotspot/src/share/vm/runtime/os.cpp
+                  (os::set_boot_path)). */
+
+               len =
+                       strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/resources.jar:") +
+                       strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/rt.jar:") +
+                       strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/sunrsasign.jar:") +
+                       strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jsse.jar:") +
+                       strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jce.jar:") +
+                       strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/charsets.jar:") +
+                       strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/classes") +
+                       strlen("0");
+
+               boot_class_path = MNEW(char, len);
+
+               strcpy(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/resources.jar:");
+               strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/rt.jar:");
+               strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/sunrsasign.jar:");
+               strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jsse.jar:");
+               strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jce.jar:");
+               strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/charsets.jar:");
+               strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/classes");
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+               len =
+                       strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
+                       strlen("0");
+
+               boot_class_path = MNEW(char, len);
+
+               strcpy(boot_class_path, JAVA_RUNTIME_LIBRARY_CLASSES);
+
+# else
+#  error unknown classpath configuration
+# endif
+#endif
+       }
+
+       properties_add("sun.boot.class.path", boot_class_path);
+       properties_add("java.boot.class.path", boot_class_path);
+
+#if defined(ENABLE_JAVASE)
+
+       /* Set the classpath. */
+
+       p = getenv("CLASSPATH");
+
+       if (p != NULL) {
+               class_path = MNEW(char, strlen(p) + strlen("0"));
+               strcpy(class_path, p);
+       }
+       else {
+               class_path = MNEW(char, strlen(".") + strlen("0"));
+               strcpy(class_path, ".");
+       }
+
+       properties_add("java.class.path", class_path);
+
+       /* Add java.vm properties. */
+
+       properties_add("java.vm.specification.version", "1.0");
+       properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
+       properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
+       properties_add("java.vm.version", VERSION);
+       properties_add("java.vm.vendor", "CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
+       properties_add("java.vm.name", "CACAO");
+
+# if defined(ENABLE_INTRP)
+       if (opt_intrp) {
+               /* XXX We don't support java.lang.Compiler */
+/*             properties_add("java.compiler", "cacao.intrp"); */
+               properties_add("java.vm.info", "interpreted mode");
+       }
+       else
+# endif
+       {
+               /* XXX We don't support java.lang.Compiler */
+/*             properties_add("java.compiler", "cacao.jit"); */
+               properties_add("java.vm.info", "JIT mode");
+       }
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       /* Get properties from system. */
+
+       cwd      = _Jv_getcwd();
+
+       env_user = getenv("USER");
+       env_home = getenv("HOME");
+       env_lang = getenv("LANG");
+
+       utsnamebuf = NEW(struct utsname);
+
+       uname(utsnamebuf);
+
+       properties_add("java.runtime.version", VERSION);
+       properties_add("java.runtime.name", "CACAO");
+
+       properties_add("java.specification.version", "1.5");
+       properties_add("java.specification.vendor", "Sun Microsystems Inc.");
+       properties_add("java.specification.name", "Java Platform API Specification");
+
+       properties_add("java.version", JAVA_VERSION);
+       properties_add("java.vendor", "GNU Classpath");
+       properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
 
-       mput = class_resolveclassmethod(p->header.vftbl->class,
-                                                                       utf_new_char("put"),
-                                                                       utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
-                                                                       NULL,
-                                                                       true);
+       properties_add("java.class.version", CLASS_VERSION);
 
-       if (mput == NULL)
-               return false;
+       properties_add("gnu.classpath.boot.library.path", boot_library_path);
 
-       return true;
+       /* Get and set java.library.path. */
+
+       java_library_path = getenv("LD_LIBRARY_PATH");
+
+       if (java_library_path == NULL)
+               java_library_path = "";
+
+       properties_add("java.library.path", java_library_path);
+
+       properties_add("java.io.tmpdir", "/tmp");
+
+#  if defined(ENABLE_INTRP)
+       if (opt_intrp) {
+               properties_add("gnu.java.compiler.name", "cacao.intrp");
+       }
+       else
+#  endif
+       {
+               properties_add("gnu.java.compiler.name", "cacao.jit");
+       }
+
+       /* Set the java.ext.dirs property. */
+
+       len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
+
+       extdirs = MNEW(char, len);
+
+       sprintf(extdirs, "%s/jre/lib/ext", java_home);
+
+       properties_add("java.ext.dirs", extdirs);
+
+       /* Set the java.ext.endorsed property. */
+
+       len = strlen(java_home) + strlen("/jre/lib/endorsed") + strlen("0");
+
+       endorseddirs = MNEW(char, len);
+
+       sprintf(endorseddirs, "%s/jre/lib/endorsed", java_home);
+
+       properties_add("java.endorsed.dirs", endorseddirs);
+
+#  if defined(DISABLE_GC)
+       /* When we disable the GC, we mmap the whole heap to a specific
+          address, so we can compare call traces. For this reason we have
+          to add the same properties on different machines, otherwise
+          more memory may be allocated (e.g. strlen("i386")
+          vs. strlen("alpha"). */
+
+       properties_add("os.arch", "unknown");
+       properties_add("os.name", "unknown");
+       properties_add("os.version", "unknown");
+#  else
+       properties_add("os.arch", JAVA_ARCH);
+       properties_add("os.name", utsnamebuf->sysname);
+       properties_add("os.version", utsnamebuf->release);
+#  endif
+
+#  if WORDS_BIGENDIAN == 1
+       properties_add("gnu.cpu.endian", "big");
+#  else
+       properties_add("gnu.cpu.endian", "little");
+#  endif
+
+       properties_add("file.separator", "/");
+       properties_add("path.separator", ":");
+       properties_add("line.separator", "\n");
+
+       properties_add("user.name", env_user ? env_user : "null");
+       properties_add("user.home", env_home ? env_home : "null");
+       properties_add("user.dir", cwd ? cwd : "null");
+
+       /* get locale */
+
+       if (env_lang != NULL) {
+               /* get the local stuff from the environment */
+
+               if (strlen(env_lang) <= 2) {
+                       properties_add("user.language", env_lang);
+               }
+               else {
+                       if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
+                               lang = MNEW(char, 3);
+                               strncpy(lang, (char *) &env_lang[0], 2);
+                               lang[2] = '\0';
+
+                               country = MNEW(char, 3);
+                               strncpy(country, (char *) &env_lang[3], 2);
+                               country[2] = '\0';
+
+                               properties_add("user.language", lang);
+                               properties_add("user.country", country);
+                       }
+               }
+       }
+       else {
+               /* if no default locale was specified, use `en_US' */
+
+               properties_add("user.language", "en");
+               properties_add("user.country", "US");
+       }
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       /* Actually this property is set by OpenJDK, but we need it in
+          nativevm_preinit(). */
+
+       properties_add("sun.boot.library.path", boot_library_path);
+
+       /* Set the java.ext.dirs property. */
+
+       len =
+               strlen(java_home) + strlen("/lib/ext") +
+               strlen(":") +
+               strlen("/usr/java/packages/lib/ext") +
+               strlen("0");
+
+       extdirs = MNEW(char, len);
+
+       sprintf(extdirs, "%s/lib/ext:/usr/java/packages/lib/ext", java_home);
+
+       properties_add("java.ext.dirs", extdirs);
+
+       /* Set the java.ext.endorsed property. */
+
+       len = strlen(java_home) + strlen("/lib/endorsed") + strlen("0");
+
+       endorseddirs = MNEW(char, len);
+
+       sprintf(endorseddirs, "%s/lib/endorsed", java_home);
+
+       properties_add("java.endorsed.dirs", endorseddirs);
+
+# else
+
+#  error unknown classpath configuration
+
+# endif
+
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+
+    properties_add("microedition.configuration", "CLDC-1.1");
+    properties_add("microedition.platform", "generic");
+    properties_add("microedition.encoding", "ISO8859_1");
+    properties_add("microedition.profiles", "");
+
+#else
+
+# error unknown Java configuration
+
+#endif
 }
 
 
 /* properties_add **************************************************************
 
-   Adds a property entry for a command line property definition.
+   Adds a property entry to the internal property list.  If there's
+   already an entry with the same key, replace it.
 
 *******************************************************************************/
 
-void properties_add(char *key, char *value)
+void properties_add(const char *key, const char *value)
 {
-       list_properties_entry *p;
+       list_properties_entry_t *pe;
+
+       /* search for the entry */
+
+       for (pe = list_first(list_properties); pe != NULL;
+                pe = list_next(list_properties, pe)) {
+               if (strcmp(pe->key, key) == 0) {
+                       /* entry was found, replace the value */
 
-       p = NEW(list_properties_entry);
-       p->key   = key;
-       p->value = value;
+#if !defined(NDEBUG)
+                       if (opt_DebugProperties) {
+                               printf("[properties_add: key=%s, old value=%s, new value=%s]\n",
+                                          key, pe->value, value);
+                       }
+#endif
 
-       list_addlast(list_properties, p);
+                       pe->value = value;
+
+                       return;
+               }
+       }
+
+       /* entry was not found, insert a new one */
+
+#if !defined(NDEBUG)
+       if (opt_DebugProperties) {
+               printf("[properties_add: key=%s, value=%s]\n", key, value);
+       }
+#endif
+
+       pe = NEW(list_properties_entry_t);
+
+       pe->key   = key;
+       pe->value = value;
+
+       list_add_last(list_properties, pe);
 }
 
 
-/* get_property ****************************************************************
+/* properties_get **************************************************************
 
-   Get a property entry from a command line property definition.
+   Get a property entry from the internal property list.
 
 *******************************************************************************/
 
-char *properties_get(char *key)
+const char *properties_get(const char *key)
 {
-       list_properties_entry *p;
+       list_properties_entry_t *pe;
 
-       for (p = list_first(list_properties); p != NULL;
-                p = list_next(list_properties, p)) {
-               if (strcmp(p->key, key) == 0)
-                       return p->value;
+       for (pe = list_first(list_properties); pe != NULL;
+                pe = list_next(list_properties, pe)) {
+               if (strcmp(pe->key, key) == 0)
+                       return pe->value;
        }
 
        return NULL;
@@ -150,46 +638,103 @@ char *properties_get(char *key)
 
 /* properties_system_add *******************************************************
 
-   Adds a property to the Java system properties.
+   Adds a given property to the Java system properties.
 
 *******************************************************************************/
 
-void properties_system_add(char *key, char *value)
+void properties_system_add(java_handle_t *p, const char *key, const char *value)
 {
-       java_lang_String *k;
-       java_lang_String *v;
+       classinfo     *c;
+       methodinfo    *m;
+       java_handle_t *k;
+       java_handle_t *v;
+
+       /* search for method to add properties */
 
-       k = javastring_new_char(key);
-       v = javastring_new_char(value);
+       LLNI_class_get(p, c);
 
-       asm_calljavafunction(mput, psystem, k, v, NULL);
+       m = class_resolveclassmethod(c,
+                                                                utf_put,
+                                                                utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
+                                                                NULL,
+                                                                true);
+
+       if (m == NULL)
+               return;
+
+       /* add to the Java system properties */
+
+       k = javastring_new_from_utf_string(key);
+       v = javastring_new_from_utf_string(value);
+
+       (void) vm_call_method(m, p, k, v);
 }
 
 
 /* properties_system_add_all ***************************************************
 
-   Adds a all properties from the properties list to the Java system
+   Adds all properties from the properties list to the Java system
    properties.
 
+   ARGUMENTS:
+       p.... is actually a java_util_Properties structure
+
 *******************************************************************************/
 
-void properties_system_add_all(void)
+#if defined(ENABLE_JAVASE)
+void properties_system_add_all(java_handle_t *p)
 {
-       list_properties_entry *p;
+       list_properties_entry_t *pe;
+       classinfo               *c;
+       methodinfo              *m;
+       java_handle_t           *key;
+       java_handle_t           *value;
+
+       /* search for method to add properties */
+
+       LLNI_class_get(p, c);
+
+       m = class_resolveclassmethod(c,
+                                                                utf_put,
+                                                                utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
+                                                                NULL,
+                                                                true);
+
+       if (m == NULL)
+               return;
 
-       for (p = list_first(list_properties); p != NULL;
-                p = list_first(list_properties)) {
+       /* process all properties stored in the internal table */
+
+       for (pe = list_first(list_properties); pe != NULL;
+                pe = list_next(list_properties, pe)) {
                /* add to the Java system properties */
 
-               properties_system_add(p->key, p->value);
+               key   = javastring_new_from_utf_string(pe->key);
+               value = javastring_new_from_utf_string(pe->value);
+
+               (void) vm_call_method(m, (java_handle_t *) p, key, value);
+       }
+}
+#endif /* defined(ENABLE_JAVASE) */
+
 
-               /* remove the entry from the list */
+/* properties_dump *************************************************************
+
+   Dump all property entries.
+
+*******************************************************************************/
+
+void properties_dump(void)
+{
+       list_t                  *l;
+       list_properties_entry_t *pe;
 
-               list_remove(list_properties, p);
+       /* For convenience. */
 
-               /* and free the memory */
+       l = list_properties;
 
-               FREE(p, list_properties_entry);
+       for (pe = list_first(l); pe != NULL; pe = list_next(l, pe)) {
+               log_println("[properties_dump: key=%s, value=%s]", pe->key, pe->value);
        }
 }