1 /* src/vm/properties.cpp - handling commandline properties
3 Copyright (C) 1996-2010
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "mm/memory.hpp"
38 #include "native/llni.h"
40 #include "vm/class.hpp"
41 #include "vm/global.h"
42 #include "vm/method.hpp"
43 #include "vm/options.h"
45 #include "vm/properties.hpp"
46 #include "vm/string.hpp"
49 #include "vm/jit/asmpart.h"
56 * Constructor fills the properties list with default values.
58 Properties::Properties()
63 char *boot_class_path;
65 #if defined(ENABLE_JAVASE)
67 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
68 struct utsname *utsnamebuf;
72 #if defined(ENABLE_JRE_LAYOUT)
73 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
77 if (os::readlink("/proc/self/exe", p, 4095) == -1)
78 os::abort_errno("readlink failed");
80 /* We have a path like:
82 /path/to/executable/bin/java
86 /path/to/executeable/jre/bin/java
88 Now let's strip two levels. */
93 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
97 char* java_home = strdup(p);
99 /* Set the path to Java core native libraries. */
101 len = strlen(java_home) + strlen("/lib/classpath") + strlen("0");
103 char* boot_library_path = MNEW(char, len);
105 strcpy(boot_library_path, java_home);
106 strcat(boot_library_path, "/lib/classpath");
108 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
110 /* Find correct java.home. We check if there is a JRE
113 /* NOTE: We use the server VM here as it should be available on
114 all architectures. */
118 strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
121 char* java_home = MNEW(char, len);
123 strcpy(java_home, p);
124 strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
126 // Check if that libjvm.so exists.
127 if (os::access(java_home, F_OK) == 0) {
128 // Yes, we add /jre to java.home.
129 strcpy(java_home, p);
130 strcat(java_home, "/jre");
133 // No, java.home is parent directory.
134 strcpy(java_home, p);
137 /* Set the path to Java core native libraries. */
139 len = strlen(java_home) + strlen("/lib/"JAVA_ARCH) + strlen("0");
141 char* boot_library_path = MNEW(char, len);
143 strcpy(boot_library_path, java_home);
144 strcat(boot_library_path, "/lib/"JAVA_ARCH);
147 # error unknown classpath configuration
155 const char* java_home = CACAO_PREFIX;
157 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
159 const char* boot_library_path = JAVA_RUNTIME_LIBRARY_LIBDIR"/classpath";
161 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
163 const char* boot_library_path = JAVA_RUNTIME_LIBRARY_LIBDIR;
165 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
167 // No boot_library_path required.
170 # error unknown classpath configuration
174 put("java.home", java_home);
176 /* Set the bootclasspath. */
178 p = os::getenv("BOOTCLASSPATH");
181 boot_class_path = MNEW(char, strlen(p) + strlen("0"));
182 strcpy(boot_class_path, p);
185 #if defined(ENABLE_JRE_LAYOUT)
186 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
189 strlen(java_home) + strlen("/share/cacao/vm.zip:") +
190 strlen(java_home) + strlen("/share/classpath/glibj.zip") +
193 boot_class_path = MNEW(char, len);
195 strcpy(boot_class_path, java_home);
196 strcat(boot_class_path, "/share/cacao/vm.zip");
197 strcat(boot_class_path, ":");
198 strcat(boot_class_path, java_home);
199 strcat(boot_class_path, "/share/classpath/glibj.zip");
201 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
203 /* This is the bootclasspath taken from HotSpot (see
204 hotspot/src/share/vm/runtime/os.cpp
205 (os::set_boot_path)). */
208 strlen(java_home) + strlen("/lib/resources.jar:") +
209 strlen(java_home) + strlen("/lib/rt.jar:") +
210 strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
211 strlen(java_home) + strlen("/lib/jsse.jar:") +
212 strlen(java_home) + strlen("/lib/jce.jar:") +
213 strlen(java_home) + strlen("/lib/charsets.jar:") +
214 strlen(java_home) + strlen("/classes") +
217 boot_class_path = MNEW(char, len);
219 strcpy(boot_class_path, java_home);
220 strcat(boot_class_path, "/lib/resources.jar:");
221 strcat(boot_class_path, java_home);
222 strcat(boot_class_path, "/lib/rt.jar:");
223 strcat(boot_class_path, java_home);
224 strcat(boot_class_path, "/lib/sunrsasign.jar:");
225 strcat(boot_class_path, java_home);
226 strcat(boot_class_path, "/lib/jsse.jar:");
227 strcat(boot_class_path, java_home);
228 strcat(boot_class_path, "/lib/jce.jar:");
229 strcat(boot_class_path, java_home);
230 strcat(boot_class_path, "/lib/charsets.jar:");
231 strcat(boot_class_path, java_home);
232 strcat(boot_class_path, "/classes");
235 # error unknown classpath configuration
238 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
241 strlen(CACAO_VM_ZIP) +
243 strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
246 boot_class_path = MNEW(char, len);
248 strcpy(boot_class_path, CACAO_VM_ZIP);
249 strcat(boot_class_path, ":");
250 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_CLASSES);
252 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
254 /* This is the bootclasspath taken from HotSpot (see
255 hotspot/src/share/vm/runtime/os.cpp
256 (os::set_boot_path)). */
259 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/resources.jar:") +
260 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/rt.jar:") +
261 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/sunrsasign.jar:") +
262 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jsse.jar:") +
263 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jce.jar:") +
264 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/charsets.jar:") +
265 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/classes") +
268 boot_class_path = MNEW(char, len);
270 strcpy(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/resources.jar:");
271 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/rt.jar:");
272 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/sunrsasign.jar:");
273 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jsse.jar:");
274 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jce.jar:");
275 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/charsets.jar:");
276 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/classes");
278 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
281 strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
284 boot_class_path = MNEW(char, len);
286 strcpy(boot_class_path, JAVA_RUNTIME_LIBRARY_CLASSES);
289 # error unknown classpath configuration
294 put("sun.boot.class.path", boot_class_path);
295 put("java.boot.class.path", boot_class_path);
297 #if defined(ENABLE_JAVASE)
299 /* Set the classpath. */
301 p = os::getenv("CLASSPATH");
306 class_path = MNEW(char, strlen(p) + strlen("0"));
307 strcpy(class_path, p);
310 class_path = MNEW(char, strlen(".") + strlen("0"));
311 strcpy(class_path, ".");
314 put("java.class.path", class_path);
316 // Add java.vm properties.
317 put("java.vm.specification.version", "1.0");
318 put("java.vm.specification.vendor", "Sun Microsystems Inc.");
319 put("java.vm.specification.name", "Java Virtual Machine Specification");
320 put("java.vm.version", VERSION_FULL);
321 put("java.vm.vendor", "CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
322 put("java.vm.name", "CACAO");
324 # if defined(ENABLE_INTRP)
326 /* XXX We don't support java.lang.Compiler */
327 /* put("java.compiler", "cacao.intrp"); */
328 put("java.vm.info", "interpreted mode");
333 /* XXX We don't support java.lang.Compiler */
334 /* put("java.compiler", "cacao.jit"); */
335 put("java.vm.info", "compiled mode");
338 // Get and set java.library.path.
339 const char* java_library_path = os::getenv("LD_LIBRARY_PATH");
341 if (java_library_path == NULL)
342 java_library_path = "";
344 put("java.library.path", java_library_path);
346 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
348 /* Get properties from system. */
350 char* cwd = os::getcwd();
352 char* env_user = os::getenv("USER");
353 char* env_home = os::getenv("HOME");
354 char* env_lang = os::getenv("LANG");
356 utsnamebuf = NEW(struct utsname);
360 put("java.runtime.version", VERSION_FULL);
361 put("java.runtime.name", "CACAO");
363 put("java.specification.version", "1.5");
364 put("java.specification.vendor", "Sun Microsystems Inc.");
365 put("java.specification.name", "Java Platform API Specification");
367 put("java.version", JAVA_VERSION);
368 put("java.vendor", "GNU Classpath");
369 put("java.vendor.url", "http://www.gnu.org/software/classpath/");
371 put("java.class.version", CLASS_VERSION);
373 put("gnu.classpath.boot.library.path", boot_library_path);
375 put("java.io.tmpdir", "/tmp");
377 # if defined(ENABLE_INTRP)
379 put("gnu.java.compiler.name", "cacao.intrp");
384 put("gnu.java.compiler.name", "cacao.jit");
387 /* Set the java.ext.dirs property. */
389 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
391 char* extdirs = MNEW(char, len);
393 sprintf(extdirs, "%s/jre/lib/ext", java_home);
395 put("java.ext.dirs", extdirs);
397 /* Set the java.ext.endorsed property. */
399 len = strlen(java_home) + strlen("/jre/lib/endorsed") + strlen("0");
401 char* endorseddirs = MNEW(char, len);
403 sprintf(endorseddirs, "%s/jre/lib/endorsed", java_home);
405 put("java.endorsed.dirs", endorseddirs);
407 # if defined(DISABLE_GC)
408 /* When we disable the GC, we mmap the whole heap to a specific
409 address, so we can compare call traces. For this reason we have
410 to add the same properties on different machines, otherwise
411 more memory may be allocated (e.g. strlen("i386")
412 vs. strlen("alpha"). */
414 put("os.arch", "unknown");
415 put("os.name", "unknown");
416 put("os.version", "unknown");
418 put("os.arch", JAVA_ARCH);
419 put("os.name", utsnamebuf->sysname);
420 put("os.version", utsnamebuf->release);
423 # if WORDS_BIGENDIAN == 1
424 put("gnu.cpu.endian", "big");
426 put("gnu.cpu.endian", "little");
429 put("file.separator", "/");
430 put("path.separator", ":");
431 put("line.separator", "\n");
433 put("user.name", env_user ? env_user : "null");
434 put("user.home", env_home ? env_home : "null");
435 put("user.dir", cwd ? cwd : "null");
439 bool use_en_US = true;
440 if (env_lang != NULL) {
441 #if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
442 /* get the locale stuff from the environment */
445 if ((locale = setlocale(LC_MESSAGES, ""))) {
446 int len = strlen(locale);
447 if (((len >= 5) && (locale[2] == '_')) || len == 2) {
449 char* lang = MNEW(char, 3);
450 strncpy(lang, (char*) &locale[0], 2);
452 put("user.language", lang);
455 char* country = MNEW(char, 3);
456 strncpy(country, (char*) &locale[3], 2);
459 put("user.country", country);
466 /* if no default locale was specified, use `en_US' */
468 put("user.language", "en");
469 put("user.country", "US");
472 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
474 /* Actually this property is set by OpenJDK, but we need it in
475 nativevm_preinit(). */
477 put("sun.boot.library.path", boot_library_path);
479 // Set the java.ext.dirs property.
481 strlen(java_home) + strlen("/lib/ext") +
483 strlen("/usr/java/packages/lib/ext") +
486 char* extdirs = MNEW(char, len);
488 sprintf(extdirs, "%s/lib/ext:/usr/java/packages/lib/ext", java_home);
490 put("java.ext.dirs", extdirs);
492 // Set the java.ext.endorsed property.
493 len = strlen(java_home) + strlen("/lib/endorsed") + strlen("0");
495 char* endorseddirs = MNEW(char, len);
497 sprintf(endorseddirs, "%s/lib/endorsed", java_home);
499 put("java.endorsed.dirs", endorseddirs);
503 # error unknown classpath configuration
507 #elif defined(ENABLE_JAVAME_CLDC1_1)
509 put("microedition.configuration", "CLDC-1.1");
510 put("microedition.platform", "generic");
511 put("microedition.encoding", "ISO8859_1");
512 put("microedition.profiles", "");
516 # error unknown Java configuration
523 * Add the given property to the given Java system properties.
525 * @param p Java properties object.
527 * @param value Value.
529 void Properties::put(java_handle_t* p, const char* key, const char* value)
531 // Get Properties.put() method to add properties.
533 LLNI_class_get(p, c);
535 methodinfo* m = class_resolveclassmethod(c,
537 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
544 // Add to the Java system properties.
545 java_handle_t* k = javastring_new_from_utf_string(key);
546 java_handle_t* v = javastring_new_from_utf_string(value);
548 (void) vm_call_method(m, p, k, v);
553 * Put the given property into the internal property map. If there's
554 * already an entry with the same key, replace it.
557 * @param value Value.
559 void Properties::put(const char* key, const char* value)
561 // Try to find the key.
562 std::map<const char*, const char*>::iterator it = _properties.find(key);
564 // The key is already in the map.
565 if (it != _properties.end()) {
567 if (opt_DebugProperties) {
568 printf("[Properties::put: key=%s, old value=%s, new value=%s]\n",
569 key, it->second, value);
573 // Replace the value in the current entry.
579 // The key was not found, insert the pair.
581 if (opt_DebugProperties) {
582 printf("[Properties::put: key=%s, value=%s]\n", key, value);
586 _properties.insert(std::make_pair(key, value));
591 * Get a property entry from the internal property map.
595 * @return Value associated with the key or NULL when not found.
597 const char* Properties::get(const char* key)
599 // Try to find the key.
600 std::map<const char*, const char*>::iterator it = _properties.find(key);
602 // The key is not in the map.
603 if (it == _properties.end())
612 * Fill the given Java system properties with all properties from the
613 * internal properties map.
615 * @param p Java Properties object.
617 #if defined(ENABLE_JAVASE)
618 void Properties::fill(java_handle_t* p)
620 // Get Properties.put() method to add properties.
622 LLNI_class_get(p, c);
624 methodinfo* m = class_resolveclassmethod(c,
626 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
633 // Iterator over all properties.
634 for (std::map<const char*, const char*>::iterator it = _properties.begin(); it != _properties.end(); it++) {
635 // Put into the Java system properties.
636 java_handle_t* key = javastring_new_from_utf_string(it->first);
637 java_handle_t* value = javastring_new_from_utf_string(it->second);
639 (void) vm_call_method(m, p, key, value);
646 * Dump all property entries.
649 void Properties::dump()
651 for (std::map<const char*, const char*>::iterator it = _properties.begin(); it != _properties.end(); it++) {
652 log_println("[Properties::dump: key=%s, value=%s]", it->first, it->second);
659 * These are local overrides for various environment variables in Emacs.
660 * Please do not remove this and leave it at the end of the file, where
661 * Emacs will automagically detect them.
662 * ---------------------------------------------------------------------
665 * indent-tabs-mode: t
669 * vim:noexpandtab:sw=4:ts=4: