1 /* src/vm/properties.cpp - handling commandline properties
3 Copyright (C) 1996-2005, 2006, 2007, 2008
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
35 #include <sys/utsname.h>
37 #include "mm/memory.h"
39 #include "native/llni.h"
41 #include "toolbox/util.h"
44 #include "vm/global.h"
45 #include "vm/method.h"
46 #include "vm/options.h"
48 #include "vm/properties.hpp"
49 #include "vm/string.hpp"
52 #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);
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", "JIT mode");
338 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
340 /* Get properties from system. */
342 char* cwd = _Jv_getcwd();
344 char* env_user = os::getenv("USER");
345 char* env_home = os::getenv("HOME");
346 char* env_lang = os::getenv("LANG");
348 utsnamebuf = NEW(struct utsname);
352 put("java.runtime.version", VERSION);
353 put("java.runtime.name", "CACAO");
355 put("java.specification.version", "1.5");
356 put("java.specification.vendor", "Sun Microsystems Inc.");
357 put("java.specification.name", "Java Platform API Specification");
359 put("java.version", JAVA_VERSION);
360 put("java.vendor", "GNU Classpath");
361 put("java.vendor.url", "http://www.gnu.org/software/classpath/");
363 put("java.class.version", CLASS_VERSION);
365 put("gnu.classpath.boot.library.path", boot_library_path);
367 // Get and set java.library.path.
368 const char* java_library_path = os::getenv("LD_LIBRARY_PATH");
370 if (java_library_path == NULL)
371 java_library_path = "";
373 put("java.library.path", java_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 if (env_lang != NULL) {
440 /* get the local stuff from the environment */
442 if (strlen(env_lang) <= 2) {
443 put("user.language", env_lang);
446 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
447 char* lang = MNEW(char, 3);
448 strncpy(lang, (char*) &env_lang[0], 2);
451 char* country = MNEW(char, 3);
452 strncpy(country, (char*) &env_lang[3], 2);
455 put("user.language", lang);
456 put("user.country", country);
461 /* if no default locale was specified, use `en_US' */
463 put("user.language", "en");
464 put("user.country", "US");
467 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
469 /* Actually this property is set by OpenJDK, but we need it in
470 nativevm_preinit(). */
472 put("sun.boot.library.path", boot_library_path);
474 // Set the java.ext.dirs property.
476 strlen(java_home) + strlen("/lib/ext") +
478 strlen("/usr/java/packages/lib/ext") +
481 char* extdirs = MNEW(char, len);
483 sprintf(extdirs, "%s/lib/ext:/usr/java/packages/lib/ext", java_home);
485 put("java.ext.dirs", extdirs);
487 // Set the java.ext.endorsed property.
488 len = strlen(java_home) + strlen("/lib/endorsed") + strlen("0");
490 char* endorseddirs = MNEW(char, len);
492 sprintf(endorseddirs, "%s/lib/endorsed", java_home);
494 put("java.endorsed.dirs", endorseddirs);
498 # error unknown classpath configuration
502 #elif defined(ENABLE_JAVAME_CLDC1_1)
504 put("microedition.configuration", "CLDC-1.1");
505 put("microedition.platform", "generic");
506 put("microedition.encoding", "ISO8859_1");
507 put("microedition.profiles", "");
511 # error unknown Java configuration
518 * Add the given property to the given Java system properties.
520 * @param p Java properties object.
522 * @param value Value.
524 void Properties::put(java_handle_t* p, const char* key, const char* value)
526 // Get Properties.put() method to add properties.
528 LLNI_class_get(p, c);
530 methodinfo* m = class_resolveclassmethod(c,
532 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
539 // Add to the Java system properties.
540 java_handle_t* k = javastring_new_from_utf_string(key);
541 java_handle_t* v = javastring_new_from_utf_string(value);
543 (void) vm_call_method(m, p, k, v);
548 * Put the given property into the internal property map. If there's
549 * already an entry with the same key, replace it.
552 * @param value Value.
554 void Properties::put(const char* key, const char* value)
556 // Try to find the key.
557 std::map<const char*, const char*>::iterator it = _properties.find(key);
559 // The key is already in the map.
560 if (it != _properties.end()) {
562 if (opt_DebugProperties) {
563 printf("[Properties::put: key=%s, old value=%s, new value=%s]\n",
564 key, it->second, value);
568 // Replace the value in the current entry.
574 // The key was not found, insert the pair.
576 if (opt_DebugProperties) {
577 printf("[Properties::put: key=%s, value=%s]\n", key, value);
581 _properties.insert(std::make_pair(key, value));
586 * Get a property entry from the internal property map.
590 * @return Value associated with the key or NULL when not found.
592 const char* Properties::get(const char* key)
594 // Try to find the key.
595 std::map<const char*, const char*>::iterator it = _properties.find(key);
597 // The key is not in the map.
598 if (it == _properties.end())
607 * Fill the given Java system properties with all properties from the
608 * internal properties map.
610 * @param p Java Properties object.
612 #if defined(ENABLE_JAVASE)
613 void Properties::fill(java_handle_t* p)
615 // Get Properties.put() method to add properties.
617 LLNI_class_get(p, c);
619 methodinfo* m = class_resolveclassmethod(c,
621 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
628 // Iterator over all properties.
629 for (std::map<const char*, const char*>::iterator it = _properties.begin(); it != _properties.end(); it++) {
630 // Put into the Java system properties.
631 java_handle_t* key = javastring_new_from_utf_string(it->first);
632 java_handle_t* value = javastring_new_from_utf_string(it->second);
634 (void) vm_call_method(m, p, key, value);
641 * Dump all property entries.
644 void Properties::dump()
646 for (std::map<const char*, const char*>::iterator it = _properties.begin(); it != _properties.end(); it++) {
647 log_println("[Properties::dump: key=%s, value=%s]", it->first, it->second);
653 // Legacy C interface.
655 void Properties_put(const char *key, const char *value) { VM::get_current()->get_properties().put(key, value); }
656 const char *Properties_get(const char *key) { return VM::get_current()->get_properties().get(key); }
661 * These are local overrides for various environment variables in Emacs.
662 * Please do not remove this and leave it at the end of the file, where
663 * Emacs will automagically detect them.
664 * ---------------------------------------------------------------------
667 * indent-tabs-mode: t
671 * vim:noexpandtab:sw=4:ts=4: