System.java revision a6c26760ff2f6d3ae5794f5b15509f965b991f17
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/* 18 * Copyright (C) 2008 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33package java.lang; 34 35import dalvik.system.VMRuntime; 36import dalvik.system.VMStack; 37import java.io.BufferedInputStream; 38import java.io.Console; 39import java.io.FileDescriptor; 40import java.io.FileInputStream; 41import java.io.FileOutputStream; 42import java.io.IOException; 43import java.io.InputStream; 44import java.io.PrintStream; 45import java.nio.channels.Channel; 46import java.nio.channels.spi.SelectorProvider; 47import java.util.AbstractMap; 48import java.util.Collections; 49import java.util.HashMap; 50import java.util.Map; 51import java.util.Properties; 52import java.util.Set; 53import libcore.icu.ICU; 54import libcore.io.ErrnoException; 55import libcore.io.Libcore; 56import libcore.io.StructPasswd; 57import libcore.io.StructUtsname; 58 59/** 60 * Provides access to system-related information and resources including 61 * standard input and output. Enables clients to dynamically load native 62 * libraries. All methods of this class are accessed in a static way and the 63 * class itself can not be instantiated. 64 * 65 * @see Runtime 66 */ 67public final class System { 68 69 /** 70 * Default input stream. 71 */ 72 public static final InputStream in; 73 74 /** 75 * Default output stream. 76 */ 77 public static final PrintStream out; 78 79 /** 80 * Default error output stream. 81 */ 82 public static final PrintStream err; 83 84 private static final String lineSeparator; 85 private static final Properties unchangeableSystemProperties; 86 private static Properties systemProperties; 87 88 static { 89 err = new PrintStream(new FileOutputStream(FileDescriptor.err)); 90 out = new PrintStream(new FileOutputStream(FileDescriptor.out)); 91 in = new BufferedInputStream(new FileInputStream(FileDescriptor.in)); 92 unchangeableSystemProperties = initUnchangeableSystemProperties(); 93 systemProperties = createSystemProperties(); 94 lineSeparator = System.getProperty("line.separator"); 95 } 96 97 /** 98 * Sets the standard input stream to the given user defined input stream. 99 * 100 * @param newIn 101 * the user defined input stream to set as the standard input 102 * stream. 103 */ 104 public static void setIn(InputStream newIn) { 105 setFieldImpl("in", "Ljava/io/InputStream;", newIn); 106 } 107 108 /** 109 * Sets the standard output stream to the given user defined output stream. 110 * 111 * @param newOut 112 * the user defined output stream to set as the standard output 113 * stream. 114 */ 115 public static void setOut(PrintStream newOut) { 116 setFieldImpl("out", "Ljava/io/PrintStream;", newOut); 117 } 118 119 /** 120 * Sets the standard error output stream to the given user defined output 121 * stream. 122 * 123 * @param newErr 124 * the user defined output stream to set as the standard error 125 * output stream. 126 */ 127 public static void setErr(PrintStream newErr) { 128 setFieldImpl("err", "Ljava/io/PrintStream;", newErr); 129 } 130 131 /** 132 * Prevents this class from being instantiated. 133 */ 134 private System() { 135 } 136 137 /** 138 * Copies {@code length} elements from the array {@code src}, 139 * starting at offset {@code srcPos}, into the array {@code dst}, 140 * starting at offset {@code dstPos}. 141 * 142 * <p>The source and destination arrays can be the same array, 143 * in which case copying is performed as if the source elements 144 * are first copied into a temporary array and then into the 145 * destination array. 146 * 147 * @param src 148 * the source array to copy the content. 149 * @param srcPos 150 * the starting index of the content in {@code src}. 151 * @param dst 152 * the destination array to copy the data into. 153 * @param dstPos 154 * the starting index for the copied content in {@code dst}. 155 * @param length 156 * the number of elements to be copied. 157 */ 158 public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length); 159 160 /** 161 * The char array length threshold below which to use a Java 162 * (non-native) version of arraycopy() instead of the native 163 * version. See b/7103825. 164 */ 165 private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 64; 166 167 /** 168 * The char[] specialized version of arraycopy(). 169 * 170 * @hide internal use only 171 */ 172 public static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) { 173 if (src == null) { 174 throw new NullPointerException("src == null"); 175 } 176 if (dst == null) { 177 throw new NullPointerException("dst == null"); 178 } 179 if (srcPos < 0 || dstPos < 0 || length < 0 || 180 srcPos > src.length - length || dstPos > dst.length - length) { 181 throw new ArrayIndexOutOfBoundsException( 182 "src.length=" + src.length + " srcPos=" + srcPos + 183 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); 184 } 185 if (length <= ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD) { 186 // Copy char by char for shorter arrays. 187 if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { 188 // Copy backward (to avoid overwriting elements before 189 // they are copied in case of an overlap on the same 190 // array.) 191 for (int i = length - 1; i >= 0; --i) { 192 dst[dstPos + i] = src[srcPos + i]; 193 } 194 } else { 195 // Copy forward. 196 for (int i = 0; i < length; ++i) { 197 dst[dstPos + i] = src[srcPos + i]; 198 } 199 } 200 } else { 201 // Call the native version for longer arrays. 202 arraycopyCharUnchecked(src, srcPos, dst, dstPos, length); 203 } 204 } 205 206 /** 207 * The char[] specialized, unchecked, native version of 208 * arraycopy(). This assumes error checking has been done. 209 */ 210 private static native void arraycopyCharUnchecked(char[] src, int srcPos, 211 char[] dst, int dstPos, int length); 212 213 /** 214 * Returns the current time in milliseconds since January 1, 1970 00:00:00.0 UTC. 215 * 216 * <p>This method always returns UTC times, regardless of the system's time zone. 217 * This is often called "Unix time" or "epoch time". 218 * Use a {@link java.text.DateFormat} instance to format this time for display to a human. 219 * 220 * <p>This method shouldn't be used for measuring timeouts or 221 * other elapsed time measurements, as changing the system time can affect 222 * the results. Use {@link #nanoTime} for that. 223 */ 224 public static native long currentTimeMillis(); 225 226 /** 227 * Returns the current timestamp of the most precise timer available on the 228 * local system, in nanoseconds. Equivalent to Linux's {@code CLOCK_MONOTONIC}. 229 * 230 * <p>This timestamp should only be used to measure a duration by comparing it 231 * against another timestamp on the same device. 232 * Values returned by this method do not have a defined correspondence to 233 * wall clock times; the zero value is typically whenever the device last booted. 234 * Use {@link #currentTimeMillis} if you want to know what time it is. 235 */ 236 public static native long nanoTime(); 237 238 /** 239 * Causes the VM to stop running and the program to exit with the given exit status. 240 * If {@link #runFinalizersOnExit(boolean)} has been previously invoked with a 241 * {@code true} argument, then all objects will be properly 242 * garbage-collected and finalized first. 243 */ 244 public static void exit(int code) { 245 Runtime.getRuntime().exit(code); 246 } 247 248 /** 249 * Indicates to the VM that it would be a good time to run the 250 * garbage collector. Note that this is a hint only. There is no guarantee 251 * that the garbage collector will actually be run. 252 */ 253 public static void gc() { 254 Runtime.getRuntime().gc(); 255 } 256 257 /** 258 * Returns the value of the environment variable with the given name, or null if no such 259 * variable exists. 260 */ 261 public static String getenv(String name) { 262 if (name == null) { 263 throw new NullPointerException("name == null"); 264 } 265 return Libcore.os.getenv(name); 266 } 267 268 /** 269 * Returns an unmodifiable map of all environment variables to their values. 270 */ 271 public static Map<String, String> getenv() { 272 Map<String, String> map = new HashMap<String, String>(); 273 for (String entry : Libcore.os.environ()) { 274 int index = entry.indexOf('='); 275 if (index != -1) { 276 map.put(entry.substring(0, index), entry.substring(index + 1)); 277 } 278 } 279 return new SystemEnvironment(map); 280 } 281 282 /** 283 * Returns the inherited channel from the creator of the current virtual 284 * machine. 285 * 286 * @return the inherited {@link Channel} or {@code null} if none exists. 287 * @throws IOException 288 * if an I/O error occurred. 289 * @see SelectorProvider 290 * @see SelectorProvider#inheritedChannel() 291 */ 292 public static Channel inheritedChannel() throws IOException { 293 return SelectorProvider.provider().inheritedChannel(); 294 } 295 296 /** 297 * Returns the system properties. Note that this is not a copy, so that 298 * changes made to the returned Properties object will be reflected in 299 * subsequent calls to getProperty and getProperties. 300 * 301 * @return the system properties. 302 */ 303 public static Properties getProperties() { 304 return systemProperties; 305 } 306 307 private static Properties initUnchangeableSystemProperties() { 308 VMRuntime runtime = VMRuntime.getRuntime(); 309 Properties p = new Properties(); 310 311 String projectUrl = "http://www.android.com/"; 312 String projectName = "The Android Project"; 313 314 p.put("java.boot.class.path", runtime.bootClassPath()); 315 p.put("java.class.path", runtime.classPath()); 316 317 // None of these four are meaningful on Android, but these keys are guaranteed 318 // to be present for System.getProperty. For java.class.version, we use the maximum 319 // class file version that dx currently supports. 320 p.put("java.class.version", "50.0"); 321 p.put("java.compiler", ""); 322 p.put("java.ext.dirs", ""); 323 p.put("java.version", "0"); 324 325 // TODO: does this make any sense? Should we just leave java.home unset? 326 String javaHome = getenv("JAVA_HOME"); 327 if (javaHome == null) { 328 javaHome = "/system"; 329 } 330 p.put("java.home", javaHome); 331 332 String ldLibraryPath = getenv("LD_LIBRARY_PATH"); 333 if (ldLibraryPath != null) { 334 p.put("java.library.path", ldLibraryPath); 335 } 336 337 p.put("java.specification.name", "Dalvik Core Library"); 338 p.put("java.specification.vendor", projectName); 339 p.put("java.specification.version", "0.9"); 340 341 p.put("java.vendor", projectName); 342 p.put("java.vendor.url", projectUrl); 343 p.put("java.vm.name", "Dalvik"); 344 p.put("java.vm.specification.name", "Dalvik Virtual Machine Specification"); 345 p.put("java.vm.specification.vendor", projectName); 346 p.put("java.vm.specification.version", "0.9"); 347 p.put("java.vm.vendor", projectName); 348 p.put("java.vm.version", runtime.vmVersion()); 349 350 p.put("file.separator", "/"); 351 p.put("line.separator", "\n"); 352 p.put("path.separator", ":"); 353 354 p.put("java.runtime.name", "Android Runtime"); 355 p.put("java.runtime.version", "0.9"); 356 p.put("java.vm.vendor.url", projectUrl); 357 358 p.put("file.encoding", "UTF-8"); 359 p.put("user.language", "en"); 360 p.put("user.region", "US"); 361 362 try { 363 StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid()); 364 p.put("user.home", passwd.pw_dir); 365 p.put("user.name", passwd.pw_name); 366 } catch (ErrnoException exception) { 367 throw new AssertionError(exception); 368 } 369 370 StructUtsname info = Libcore.os.uname(); 371 p.put("os.arch", info.machine); 372 p.put("os.name", info.sysname); 373 p.put("os.version", info.release); 374 375 // Undocumented Android-only properties. 376 p.put("android.icu.library.version", ICU.getIcuVersion()); 377 p.put("android.icu.unicode.version", ICU.getUnicodeVersion()); 378 p.put("android.icu.cldr.version", ICU.getCldrVersion()); 379 380 parsePropertyAssignments(p, specialProperties()); 381 382 // Override built-in properties with settings from the command line. 383 parsePropertyAssignments(p, runtime.properties()); 384 return p; 385 } 386 387 private static Properties createSystemProperties() { 388 Properties p = new PropertiesWithNonOverrideableDefaults(unchangeableSystemProperties); 389 // On Android, each app gets its own temporary directory. 390 // (See android.app.ActivityThread.) This is just a fallback default, 391 // useful only on the host. 392 p.put("java.io.tmpdir", "/tmp"); 393 return p; 394 } 395 396 /** 397 * Returns an array of "key=value" strings containing information not otherwise 398 * easily available, such as #defined library versions. 399 */ 400 private static native String[] specialProperties(); 401 402 /** 403 * Adds each element of 'assignments' to 'p', treating each element as an 404 * assignment in the form "key=value". 405 */ 406 private static void parsePropertyAssignments(Properties p, String[] assignments) { 407 for (String assignment : assignments) { 408 int split = assignment.indexOf('='); 409 String key = assignment.substring(0, split); 410 String value = assignment.substring(split + 1); 411 p.put(key, value); 412 } 413 } 414 415 /** 416 * Returns the value of a particular system property or {@code null} if no 417 * such property exists. 418 * 419 * <p>The following properties are always provided by the Dalvik VM <b>and 420 * cannot be modified</b>: 421 * <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY=""> 422 * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 423 * <td><b>Name</b></td> <td><b>Meaning</b></td> <td><b>Example</b></td></tr> 424 * <tr><td>file.separator</td> <td>{@link java.io.File#separator}</td> <td>{@code /}</td></tr> 425 * 426 * <tr><td>java.class.path</td> <td>System class path</td> <td>{@code .}</td></tr> 427 * <tr><td>java.class.version</td> <td>(Not useful on Android)</td> <td>{@code 50.0}</td></tr> 428 * <tr><td>java.compiler</td> <td>(Not useful on Android)</td> <td>Empty</td></tr> 429 * <tr><td>java.ext.dirs</td> <td>(Not useful on Android)</td> <td>Empty</td></tr> 430 * <tr><td>java.home</td> <td>Location of the VM on the file system</td> <td>{@code /system}</td></tr> 431 * <tr><td>java.io.tmpdir</td> <td>See {@link java.io.File#createTempFile}</td> <td>{@code /sdcard}</td></tr> 432 * <tr><td>java.library.path</td> <td>Search path for JNI libraries</td> <td>{@code /vendor/lib:/system/lib}</td></tr> 433 * <tr><td>java.vendor</td> <td>Human-readable VM vendor</td> <td>{@code The Android Project}</td></tr> 434 * <tr><td>java.vendor.url</td> <td>URL for VM vendor's web site</td> <td>{@code http://www.android.com/}</td></tr> 435 * <tr><td>java.version</td> <td>(Not useful on Android)</td> <td>{@code 0}</td></tr> 436 * 437 * <tr><td>java.specification.version</td> <td>VM libraries version</td> <td>{@code 0.9}</td></tr> 438 * <tr><td>java.specification.vendor</td> <td>VM libraries vendor</td> <td>{@code The Android Project}</td></tr> 439 * <tr><td>java.specification.name</td> <td>VM libraries name</td> <td>{@code Dalvik Core Library}</td></tr> 440 * <tr><td>java.vm.version</td> <td>VM implementation version</td> <td>{@code 1.2.0}</td></tr> 441 * <tr><td>java.vm.vendor</td> <td>VM implementation vendor</td> <td>{@code The Android Project}</td></tr> 442 * <tr><td>java.vm.name</td> <td>VM implementation name</td> <td>{@code Dalvik}</td></tr> 443 * <tr><td>java.vm.specification.version</td> <td>VM specification version</td> <td>{@code 0.9}</td></tr> 444 * <tr><td>java.vm.specification.vendor</td> <td>VM specification vendor</td> <td>{@code The Android Project}</td></tr> 445 * <tr><td>java.vm.specification.name</td> <td>VM specification name</td> <td>{@code Dalvik Virtual Machine Specification}</td></tr> 446 * 447 * <tr><td>line.separator</td> <td>The system line separator</td> <td>{@code \n}</td></tr> 448 * 449 * <tr><td>os.arch</td> <td>OS architecture</td> <td>{@code armv7l}</td></tr> 450 * <tr><td>os.name</td> <td>OS (kernel) name</td> <td>{@code Linux}</td></tr> 451 * <tr><td>os.version</td> <td>OS (kernel) version</td> <td>{@code 2.6.32.9-g103d848}</td></tr> 452 * 453 * <tr><td>path.separator</td> <td>See {@link java.io.File#pathSeparator}</td> <td>{@code :}</td></tr> 454 * 455 * <tr><td>user.dir</td> <td>Base of non-absolute paths</td> <td>{@code /}</td></tr> 456 * <tr><td>user.home</td> <td>(Not useful on Android)</td> <td>Empty</td></tr> 457 * <tr><td>user.name</td> <td>(Not useful on Android)</td> <td>Empty</td></tr> 458 * 459 * </table> 460 * 461 * <p>It is an error to override anyone of these properties. Any attempt to 462 * do so will leave their values unchanged. 463 * 464 * @param propertyName 465 * the name of the system property to look up. 466 * @return the value of the specified system property or {@code null} if the 467 * property doesn't exist. 468 */ 469 public static String getProperty(String propertyName) { 470 return getProperty(propertyName, null); 471 } 472 473 /** 474 * Returns the value of a particular system property. The {@code 475 * defaultValue} will be returned if no such property has been found. 476 */ 477 public static String getProperty(String name, String defaultValue) { 478 checkPropertyName(name); 479 return systemProperties.getProperty(name, defaultValue); 480 } 481 482 /** 483 * Sets the value of a particular system property. Most system properties 484 * are read only and cannot be cleared or modified. See {@link #setProperty} for a 485 * list of such properties. 486 * 487 * @return the old value of the property or {@code null} if the property 488 * didn't exist. 489 */ 490 public static String setProperty(String name, String value) { 491 checkPropertyName(name); 492 return (String) systemProperties.setProperty(name, value); 493 } 494 495 /** 496 * Removes a specific system property. Most system properties 497 * are read only and cannot be cleared or modified. See {@link #setProperty} for a 498 * list of such properties. 499 * 500 * @return the property value or {@code null} if the property didn't exist. 501 * @throws NullPointerException 502 * if the argument is {@code null}. 503 * @throws IllegalArgumentException 504 * if the argument is empty. 505 */ 506 public static String clearProperty(String name) { 507 checkPropertyName(name); 508 return (String) systemProperties.remove(name); 509 } 510 511 private static void checkPropertyName(String name) { 512 if (name == null) { 513 throw new NullPointerException("name == null"); 514 } 515 if (name.isEmpty()) { 516 throw new IllegalArgumentException("name is empty"); 517 } 518 } 519 520 /** 521 * Returns the {@link java.io.Console} associated with this VM, or null. 522 * Not all VMs will have an associated console. A console is typically only 523 * available for programs run from the command line. 524 * @since 1.6 525 */ 526 public static Console console() { 527 return Console.getConsole(); 528 } 529 530 /** 531 * Returns null. Android does not use {@code SecurityManager}. This method 532 * is only provided for source compatibility. 533 * 534 * @return null 535 */ 536 public static SecurityManager getSecurityManager() { 537 return null; 538 } 539 540 /** 541 * Returns an integer hash code for the parameter. The hash code returned is 542 * the same one that would be returned by the method {@code 543 * java.lang.Object.hashCode()}, whether or not the object's class has 544 * overridden hashCode(). The hash code for {@code null} is {@code 0}. 545 * 546 * @param anObject 547 * the object to calculate the hash code. 548 * @return the hash code for the given object. 549 * @see java.lang.Object#hashCode 550 */ 551 public static native int identityHashCode(Object anObject); 552 553 /** 554 * Returns the system's line separator. On Android, this is {@code "\n"}. The value 555 * comes from the value of the {@code line.separator} system property when the VM 556 * starts. Later changes to the property will not affect the value returned by this 557 * method. 558 * @since 1.7 559 */ 560 public static String lineSeparator() { 561 return lineSeparator; 562 } 563 564 /** 565 * Loads and links the dynamic library that is identified through the 566 * specified path. This method is similar to {@link #loadLibrary(String)}, 567 * but it accepts a full path specification whereas {@code loadLibrary} just 568 * accepts the name of the library to load. 569 * 570 * @param pathName 571 * the path of the file to be loaded. 572 */ 573 public static void load(String pathName) { 574 Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader()); 575 } 576 577 /** 578 * Loads and links the library with the specified name. The mapping of the 579 * specified library name to the full path for loading the library is 580 * implementation-dependent. 581 * 582 * @param libName 583 * the name of the library to load. 584 * @throws UnsatisfiedLinkError 585 * if the library could not be loaded. 586 */ 587 public static void loadLibrary(String libName) { 588 Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader()); 589 } 590 591 /** 592 * @hide internal use only 593 */ 594 public static void logE(String message) { 595 log('E', message, null); 596 } 597 598 /** 599 * @hide internal use only 600 */ 601 public static void logE(String message, Throwable th) { 602 log('E', message, th); 603 } 604 605 /** 606 * @hide internal use only 607 */ 608 public static void logI(String message) { 609 log('I', message, null); 610 } 611 612 /** 613 * @hide internal use only 614 */ 615 public static void logI(String message, Throwable th) { 616 log('I', message, th); 617 } 618 619 /** 620 * @hide internal use only 621 */ 622 public static void logW(String message) { 623 log('W', message, null); 624 } 625 626 /** 627 * @hide internal use only 628 */ 629 public static void logW(String message, Throwable th) { 630 log('W', message, th); 631 } 632 633 private static native void log(char type, String message, Throwable th); 634 635 /** 636 * Provides a hint to the VM that it would be useful to attempt 637 * to perform any outstanding object finalization. 638 */ 639 public static void runFinalization() { 640 Runtime.getRuntime().runFinalization(); 641 } 642 643 /** 644 * Ensures that, when the VM is about to exit, all objects are 645 * finalized. Note that all finalization which occurs when the system is 646 * exiting is performed after all running threads have been terminated. 647 * 648 * @param flag 649 * the flag determines if finalization on exit is enabled. 650 * @deprecated This method is unsafe. 651 */ 652 @SuppressWarnings("deprecation") 653 @Deprecated 654 public static void runFinalizersOnExit(boolean flag) { 655 Runtime.runFinalizersOnExit(flag); 656 } 657 658 /** 659 * Attempts to set all system properties. Copies all properties from 660 * {@code p} and discards system properties that are read only and cannot 661 * be modified. See {@link #setProperty} for a list of such properties. 662 */ 663 public static void setProperties(Properties p) { 664 PropertiesWithNonOverrideableDefaults userProperties = 665 new PropertiesWithNonOverrideableDefaults(unchangeableSystemProperties); 666 if (p != null) { 667 userProperties.putAll(p); 668 } 669 670 systemProperties = userProperties; 671 } 672 673 /** 674 * Throws {@code SecurityException}. 675 * 676 * <p>Security managers do <i>not</i> provide a secure environment for 677 * executing untrusted code and are unsupported on Android. Untrusted code 678 * cannot be safely isolated within a single VM on Android, so this method 679 * <i>always</i> throws a {@code SecurityException}. 680 * 681 * @param sm a security manager 682 * @throws SecurityException always 683 */ 684 public static void setSecurityManager(SecurityManager sm) { 685 if (sm != null) { 686 throw new SecurityException(); 687 } 688 } 689 690 /** 691 * Returns the platform specific file name format for the shared library 692 * named by the argument. 693 * 694 * @param userLibName 695 * the name of the library to look up. 696 * @return the platform specific filename for the library. 697 */ 698 public static native String mapLibraryName(String userLibName); 699 700 /** 701 * Sets the value of the named static field in the receiver to the passed in 702 * argument. 703 * 704 * @param fieldName 705 * the name of the field to set, one of in, out, or err 706 * @param stream 707 * the new value of the field 708 */ 709 private static native void setFieldImpl(String fieldName, String signature, Object stream); 710 711 /** 712 * A properties class that prohibits changes to any of the properties 713 * contained in its defaults. 714 */ 715 static final class PropertiesWithNonOverrideableDefaults extends Properties { 716 PropertiesWithNonOverrideableDefaults(Properties defaults) { 717 super(defaults); 718 } 719 720 @Override 721 public Object put(Object key, Object value) { 722 if (defaults.containsKey(key)) { 723 logE("Ignoring attempt to set property \"" + key + 724 "\" to value \"" + value + "\"."); 725 return defaults.get(key); 726 } 727 728 return super.put(key, value); 729 } 730 731 @Override 732 public Object remove(Object key) { 733 if (defaults.containsKey(key)) { 734 logE("Ignoring attempt to remove property \"" + key + "\"."); 735 return null; 736 } 737 738 return super.remove(key); 739 } 740 } 741 742 /** 743 * The unmodifiable environment variables map. System.getenv() specifies 744 * that this map must throw when passed non-String keys. 745 */ 746 static class SystemEnvironment extends AbstractMap<String, String> { 747 private final Map<String, String> map; 748 749 public SystemEnvironment(Map<String, String> map) { 750 this.map = Collections.unmodifiableMap(map); 751 } 752 753 @Override public Set<Entry<String, String>> entrySet() { 754 return map.entrySet(); 755 } 756 757 @Override public String get(Object key) { 758 return map.get(toNonNullString(key)); 759 } 760 761 @Override public boolean containsKey(Object key) { 762 return map.containsKey(toNonNullString(key)); 763 } 764 765 @Override public boolean containsValue(Object value) { 766 return map.containsValue(toNonNullString(value)); 767 } 768 769 private String toNonNullString(Object o) { 770 if (o == null) { 771 throw new NullPointerException("o == null"); 772 } 773 return (String) o; 774 } 775 } 776} 777