1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang; 28 29 import dalvik.annotation.optimization.FastNative; 30 import java.io.*; 31 import java.util.StringTokenizer; 32 33 import dalvik.system.BlockGuard; 34 import sun.reflect.CallerSensitive; 35 import java.lang.ref.FinalizerReference; 36 import java.util.ArrayList; 37 import java.util.List; 38 import dalvik.system.BaseDexClassLoader; 39 import dalvik.system.VMDebug; 40 import dalvik.system.VMRuntime; 41 import sun.reflect.Reflection; 42 43 import libcore.io.IoUtils; 44 import libcore.io.Libcore; 45 import libcore.util.EmptyArray; 46 import static android.system.OsConstants._SC_NPROCESSORS_CONF; 47 48 /** 49 * Every Java application has a single instance of class 50 * <code>Runtime</code> that allows the application to interface with 51 * the environment in which the application is running. The current 52 * runtime can be obtained from the <code>getRuntime</code> method. 53 * <p> 54 * An application cannot create its own instance of this class. 55 * 56 * @author unascribed 57 * @see java.lang.Runtime#getRuntime() 58 * @since JDK1.0 59 */ 60 61 public class Runtime { 62 private static Runtime currentRuntime = new Runtime(); 63 64 /** 65 * Holds the list of threads to run when the VM terminates 66 */ 67 private List<Thread> shutdownHooks = new ArrayList<Thread>(); 68 69 /** 70 * Reflects whether finalization should be run for all objects 71 * when the VM terminates. 72 */ 73 private static boolean finalizeOnExit; 74 75 /** 76 * Reflects whether we are already shutting down the VM. 77 */ 78 private boolean shuttingDown; 79 80 /** 81 * Reflects whether we are tracing method calls. 82 */ 83 private boolean tracingMethods; 84 nativeExit(int code)85 private static native void nativeExit(int code); 86 87 /** 88 * Returns the runtime object associated with the current Java application. 89 * Most of the methods of class <code>Runtime</code> are instance 90 * methods and must be invoked with respect to the current runtime object. 91 * 92 * @return the <code>Runtime</code> object associated with the current 93 * Java application. 94 */ getRuntime()95 public static Runtime getRuntime() { 96 return currentRuntime; 97 } 98 99 /** Don't let anyone else instantiate this class */ Runtime()100 private Runtime() {} 101 102 /** 103 * Terminates the currently running Java virtual machine by initiating its 104 * shutdown sequence. This method never returns normally. The argument 105 * serves as a status code; by convention, a nonzero status code indicates 106 * abnormal termination. 107 * 108 * <p> The virtual machine's shutdown sequence consists of two phases. In 109 * the first phase all registered {@link #addShutdownHook shutdown hooks}, 110 * if any, are started in some unspecified order and allowed to run 111 * concurrently until they finish. In the second phase all uninvoked 112 * finalizers are run if {@link #runFinalizersOnExit finalization-on-exit} 113 * has been enabled. Once this is done the virtual machine {@link #halt 114 * halts}. 115 * 116 * <p> If this method is invoked after the virtual machine has begun its 117 * shutdown sequence then if shutdown hooks are being run this method will 118 * block indefinitely. If shutdown hooks have already been run and on-exit 119 * finalization has been enabled then this method halts the virtual machine 120 * with the given status code if the status is nonzero; otherwise, it 121 * blocks indefinitely. 122 * 123 * <p> The <tt>{@link System#exit(int) System.exit}</tt> method is the 124 * conventional and convenient means of invoking this method. <p> 125 * 126 * @param status 127 * Termination status. By convention, a nonzero status code 128 * indicates abnormal termination. 129 * 130 * @throws SecurityException 131 * If a security manager is present and its <tt>{@link 132 * SecurityManager#checkExit checkExit}</tt> method does not permit 133 * exiting with the specified status 134 * 135 * @see java.lang.SecurityException 136 * @see java.lang.SecurityManager#checkExit(int) 137 * @see #addShutdownHook 138 * @see #removeShutdownHook 139 * @see #runFinalizersOnExit 140 * @see #halt(int) 141 */ exit(int status)142 public void exit(int status) { 143 // Make sure we don't try this several times 144 synchronized(this) { 145 if (!shuttingDown) { 146 shuttingDown = true; 147 148 Thread[] hooks; 149 synchronized (shutdownHooks) { 150 // create a copy of the hooks 151 hooks = new Thread[shutdownHooks.size()]; 152 shutdownHooks.toArray(hooks); 153 } 154 155 // Start all shutdown hooks concurrently 156 for (Thread hook : hooks) { 157 hook.start(); 158 } 159 160 // Wait for all shutdown hooks to finish 161 for (Thread hook : hooks) { 162 try { 163 hook.join(); 164 } catch (InterruptedException ex) { 165 // Ignore, since we are at VM shutdown. 166 } 167 } 168 169 // Ensure finalization on exit, if requested 170 if (finalizeOnExit) { 171 runFinalization(); 172 } 173 174 // Get out of here finally... 175 nativeExit(status); 176 } 177 } 178 } 179 180 /** 181 * Registers a new virtual-machine shutdown hook. 182 * 183 * <p> The Java virtual machine <i>shuts down</i> in response to two kinds 184 * of events: 185 * 186 * <ul> 187 * 188 * <li> The program <i>exits</i> normally, when the last non-daemon 189 * thread exits or when the <tt>{@link #exit exit}</tt> (equivalently, 190 * {@link System#exit(int) System.exit}) method is invoked, or 191 * 192 * <li> The virtual machine is <i>terminated</i> in response to a 193 * user interrupt, such as typing <tt>^C</tt>, or a system-wide event, 194 * such as user logoff or system shutdown. 195 * 196 * </ul> 197 * 198 * <p> A <i>shutdown hook</i> is simply an initialized but unstarted 199 * thread. When the virtual machine begins its shutdown sequence it will 200 * start all registered shutdown hooks in some unspecified order and let 201 * them run concurrently. When all the hooks have finished it will then 202 * run all uninvoked finalizers if finalization-on-exit has been enabled. 203 * Finally, the virtual machine will halt. Note that daemon threads will 204 * continue to run during the shutdown sequence, as will non-daemon threads 205 * if shutdown was initiated by invoking the <tt>{@link #exit exit}</tt> 206 * method. 207 * 208 * <p> Once the shutdown sequence has begun it can be stopped only by 209 * invoking the <tt>{@link #halt halt}</tt> method, which forcibly 210 * terminates the virtual machine. 211 * 212 * <p> Once the shutdown sequence has begun it is impossible to register a 213 * new shutdown hook or de-register a previously-registered hook. 214 * Attempting either of these operations will cause an 215 * <tt>{@link IllegalStateException}</tt> to be thrown. 216 * 217 * <p> Shutdown hooks run at a delicate time in the life cycle of a virtual 218 * machine and should therefore be coded defensively. They should, in 219 * particular, be written to be thread-safe and to avoid deadlocks insofar 220 * as possible. They should also not rely blindly upon services that may 221 * have registered their own shutdown hooks and therefore may themselves in 222 * the process of shutting down. Attempts to use other thread-based 223 * services such as the AWT event-dispatch thread, for example, may lead to 224 * deadlocks. 225 * 226 * <p> Shutdown hooks should also finish their work quickly. When a 227 * program invokes <tt>{@link #exit exit}</tt> the expectation is 228 * that the virtual machine will promptly shut down and exit. When the 229 * virtual machine is terminated due to user logoff or system shutdown the 230 * underlying operating system may only allow a fixed amount of time in 231 * which to shut down and exit. It is therefore inadvisable to attempt any 232 * user interaction or to perform a long-running computation in a shutdown 233 * hook. 234 * 235 * <p> Uncaught exceptions are handled in shutdown hooks just as in any 236 * other thread, by invoking the <tt>{@link ThreadGroup#uncaughtException 237 * uncaughtException}</tt> method of the thread's <tt>{@link 238 * ThreadGroup}</tt> object. The default implementation of this method 239 * prints the exception's stack trace to <tt>{@link System#err}</tt> and 240 * terminates the thread; it does not cause the virtual machine to exit or 241 * halt. 242 * 243 * <p> In rare circumstances the virtual machine may <i>abort</i>, that is, 244 * stop running without shutting down cleanly. This occurs when the 245 * virtual machine is terminated externally, for example with the 246 * <tt>SIGKILL</tt> signal on Unix or the <tt>TerminateProcess</tt> call on 247 * Microsoft Windows. The virtual machine may also abort if a native 248 * method goes awry by, for example, corrupting internal data structures or 249 * attempting to access nonexistent memory. If the virtual machine aborts 250 * then no guarantee can be made about whether or not any shutdown hooks 251 * will be run. <p> 252 * 253 * @param hook 254 * An initialized but unstarted <tt>{@link Thread}</tt> object 255 * 256 * @throws IllegalArgumentException 257 * If the specified hook has already been registered, 258 * or if it can be determined that the hook is already running or 259 * has already been run 260 * 261 * @throws IllegalStateException 262 * If the virtual machine is already in the process 263 * of shutting down 264 * 265 * @throws SecurityException 266 * If a security manager is present and it denies 267 * <tt>{@link RuntimePermission}("shutdownHooks")</tt> 268 * 269 * @see #removeShutdownHook 270 * @see #halt(int) 271 * @see #exit(int) 272 * @since 1.3 273 */ addShutdownHook(Thread hook)274 public void addShutdownHook(Thread hook) { 275 // Sanity checks 276 if (hook == null) { 277 throw new NullPointerException("hook == null"); 278 } 279 280 if (shuttingDown) { 281 throw new IllegalStateException("VM already shutting down"); 282 } 283 284 if (hook.started) { 285 throw new IllegalArgumentException("Hook has already been started"); 286 } 287 288 synchronized (shutdownHooks) { 289 if (shutdownHooks.contains(hook)) { 290 throw new IllegalArgumentException("Hook already registered."); 291 } 292 293 shutdownHooks.add(hook); 294 } 295 } 296 297 /** 298 * De-registers a previously-registered virtual-machine shutdown hook. <p> 299 * 300 * @param hook the hook to remove 301 * @return <tt>true</tt> if the specified hook had previously been 302 * registered and was successfully de-registered, <tt>false</tt> 303 * otherwise. 304 * 305 * @throws IllegalStateException 306 * If the virtual machine is already in the process of shutting 307 * down 308 * 309 * @throws SecurityException 310 * If a security manager is present and it denies 311 * <tt>{@link RuntimePermission}("shutdownHooks")</tt> 312 * 313 * @see #addShutdownHook 314 * @see #exit(int) 315 * @since 1.3 316 */ removeShutdownHook(Thread hook)317 public boolean removeShutdownHook(Thread hook) { 318 // Sanity checks 319 if (hook == null) { 320 throw new NullPointerException("hook == null"); 321 } 322 323 if (shuttingDown) { 324 throw new IllegalStateException("VM already shutting down"); 325 } 326 327 synchronized (shutdownHooks) { 328 return shutdownHooks.remove(hook); 329 } 330 } 331 332 /** 333 * Forcibly terminates the currently running Java virtual machine. This 334 * method never returns normally. 335 * 336 * <p> This method should be used with extreme caution. Unlike the 337 * <tt>{@link #exit exit}</tt> method, this method does not cause shutdown 338 * hooks to be started and does not run uninvoked finalizers if 339 * finalization-on-exit has been enabled. If the shutdown sequence has 340 * already been initiated then this method does not wait for any running 341 * shutdown hooks or finalizers to finish their work. <p> 342 * 343 * @param status 344 * Termination status. By convention, a nonzero status code 345 * indicates abnormal termination. If the <tt>{@link Runtime#exit 346 * exit}</tt> (equivalently, <tt>{@link System#exit(int) 347 * System.exit}</tt>) method has already been invoked then this 348 * status code will override the status code passed to that method. 349 * 350 * @throws SecurityException 351 * If a security manager is present and its <tt>{@link 352 * SecurityManager#checkExit checkExit}</tt> method does not permit 353 * an exit with the specified status 354 * 355 * @see #exit 356 * @see #addShutdownHook 357 * @see #removeShutdownHook 358 * @since 1.3 359 */ halt(int status)360 public void halt(int status) { 361 nativeExit(status); 362 } 363 364 /** 365 * Enable or disable finalization on exit; doing so specifies that the 366 * finalizers of all objects that have finalizers that have not yet been 367 * automatically invoked are to be run before the Java runtime exits. 368 * By default, finalization on exit is disabled. 369 * 370 * <p>If there is a security manager, 371 * its <code>checkExit</code> method is first called 372 * with 0 as its argument to ensure the exit is allowed. 373 * This could result in a SecurityException. 374 * 375 * @param value true to enable finalization on exit, false to disable 376 * @deprecated This method is inherently unsafe. It may result in 377 * finalizers being called on live objects while other threads are 378 * concurrently manipulating those objects, resulting in erratic 379 * behavior or deadlock. 380 * 381 * @throws SecurityException 382 * if a security manager exists and its <code>checkExit</code> 383 * method doesn't allow the exit. 384 * 385 * @see java.lang.Runtime#exit(int) 386 * @see java.lang.Runtime#gc() 387 * @see java.lang.SecurityManager#checkExit(int) 388 * @since JDK1.1 389 */ 390 @Deprecated runFinalizersOnExit(boolean value)391 public static void runFinalizersOnExit(boolean value) { 392 finalizeOnExit = value; 393 } 394 395 /** 396 * Executes the specified string command in a separate process. 397 * 398 * <p>This is a convenience method. An invocation of the form 399 * <tt>exec(command)</tt> 400 * behaves in exactly the same way as the invocation 401 * <tt>{@link #exec(String, String[], File) exec}(command, null, null)</tt>. 402 * 403 * @param command a specified system command. 404 * 405 * @return A new {@link Process} object for managing the subprocess 406 * 407 * @throws SecurityException 408 * If a security manager exists and its 409 * {@link SecurityManager#checkExec checkExec} 410 * method doesn't allow creation of the subprocess 411 * 412 * @throws IOException 413 * If an I/O error occurs 414 * 415 * @throws NullPointerException 416 * If <code>command</code> is <code>null</code> 417 * 418 * @throws IllegalArgumentException 419 * If <code>command</code> is empty 420 * 421 * @see #exec(String[], String[], File) 422 * @see ProcessBuilder 423 */ exec(String command)424 public Process exec(String command) throws IOException { 425 return exec(command, null, null); 426 } 427 428 /** 429 * Executes the specified string command in a separate process with the 430 * specified environment. 431 * 432 * <p>This is a convenience method. An invocation of the form 433 * <tt>exec(command, envp)</tt> 434 * behaves in exactly the same way as the invocation 435 * <tt>{@link #exec(String, String[], File) exec}(command, envp, null)</tt>. 436 * 437 * @param command a specified system command. 438 * 439 * @param envp array of strings, each element of which 440 * has environment variable settings in the format 441 * <i>name</i>=<i>value</i>, or 442 * <tt>null</tt> if the subprocess should inherit 443 * the environment of the current process. 444 * 445 * @return A new {@link Process} object for managing the subprocess 446 * 447 * @throws SecurityException 448 * If a security manager exists and its 449 * {@link SecurityManager#checkExec checkExec} 450 * method doesn't allow creation of the subprocess 451 * 452 * @throws IOException 453 * If an I/O error occurs 454 * 455 * @throws NullPointerException 456 * If <code>command</code> is <code>null</code>, 457 * or one of the elements of <code>envp</code> is <code>null</code> 458 * 459 * @throws IllegalArgumentException 460 * If <code>command</code> is empty 461 * 462 * @see #exec(String[], String[], File) 463 * @see ProcessBuilder 464 */ exec(String command, String[] envp)465 public Process exec(String command, String[] envp) throws IOException { 466 return exec(command, envp, null); 467 } 468 469 /** 470 * Executes the specified string command in a separate process with the 471 * specified environment and working directory. 472 * 473 * <p>This is a convenience method. An invocation of the form 474 * <tt>exec(command, envp, dir)</tt> 475 * behaves in exactly the same way as the invocation 476 * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, envp, dir)</tt>, 477 * where <code>cmdarray</code> is an array of all the tokens in 478 * <code>command</code>. 479 * 480 * <p>More precisely, the <code>command</code> string is broken 481 * into tokens using a {@link StringTokenizer} created by the call 482 * <code>new {@link StringTokenizer}(command)</code> with no 483 * further modification of the character categories. The tokens 484 * produced by the tokenizer are then placed in the new string 485 * array <code>cmdarray</code>, in the same order. 486 * 487 * @param command a specified system command. 488 * 489 * @param envp array of strings, each element of which 490 * has environment variable settings in the format 491 * <i>name</i>=<i>value</i>, or 492 * <tt>null</tt> if the subprocess should inherit 493 * the environment of the current process. 494 * 495 * @param dir the working directory of the subprocess, or 496 * <tt>null</tt> if the subprocess should inherit 497 * the working directory of the current process. 498 * 499 * @return A new {@link Process} object for managing the subprocess 500 * 501 * @throws SecurityException 502 * If a security manager exists and its 503 * {@link SecurityManager#checkExec checkExec} 504 * method doesn't allow creation of the subprocess 505 * 506 * @throws IOException 507 * If an I/O error occurs 508 * 509 * @throws NullPointerException 510 * If <code>command</code> is <code>null</code>, 511 * or one of the elements of <code>envp</code> is <code>null</code> 512 * 513 * @throws IllegalArgumentException 514 * If <code>command</code> is empty 515 * 516 * @see ProcessBuilder 517 * @since 1.3 518 */ exec(String command, String[] envp, File dir)519 public Process exec(String command, String[] envp, File dir) 520 throws IOException { 521 if (command.length() == 0) 522 throw new IllegalArgumentException("Empty command"); 523 524 StringTokenizer st = new StringTokenizer(command); 525 String[] cmdarray = new String[st.countTokens()]; 526 for (int i = 0; st.hasMoreTokens(); i++) 527 cmdarray[i] = st.nextToken(); 528 return exec(cmdarray, envp, dir); 529 } 530 531 /** 532 * Executes the specified command and arguments in a separate process. 533 * 534 * <p>This is a convenience method. An invocation of the form 535 * <tt>exec(cmdarray)</tt> 536 * behaves in exactly the same way as the invocation 537 * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, null, null)</tt>. 538 * 539 * @param cmdarray array containing the command to call and 540 * its arguments. 541 * 542 * @return A new {@link Process} object for managing the subprocess 543 * 544 * @throws SecurityException 545 * If a security manager exists and its 546 * {@link SecurityManager#checkExec checkExec} 547 * method doesn't allow creation of the subprocess 548 * 549 * @throws IOException 550 * If an I/O error occurs 551 * 552 * @throws NullPointerException 553 * If <code>cmdarray</code> is <code>null</code>, 554 * or one of the elements of <code>cmdarray</code> is <code>null</code> 555 * 556 * @throws IndexOutOfBoundsException 557 * If <code>cmdarray</code> is an empty array 558 * (has length <code>0</code>) 559 * 560 * @see ProcessBuilder 561 */ exec(String cmdarray[])562 public Process exec(String cmdarray[]) throws IOException { 563 return exec(cmdarray, null, null); 564 } 565 566 /** 567 * Executes the specified command and arguments in a separate process 568 * with the specified environment. 569 * 570 * <p>This is a convenience method. An invocation of the form 571 * <tt>exec(cmdarray, envp)</tt> 572 * behaves in exactly the same way as the invocation 573 * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, envp, null)</tt>. 574 * 575 * @param cmdarray array containing the command to call and 576 * its arguments. 577 * 578 * @param envp array of strings, each element of which 579 * has environment variable settings in the format 580 * <i>name</i>=<i>value</i>, or 581 * <tt>null</tt> if the subprocess should inherit 582 * the environment of the current process. 583 * 584 * @return A new {@link Process} object for managing the subprocess 585 * 586 * @throws SecurityException 587 * If a security manager exists and its 588 * {@link SecurityManager#checkExec checkExec} 589 * method doesn't allow creation of the subprocess 590 * 591 * @throws IOException 592 * If an I/O error occurs 593 * 594 * @throws NullPointerException 595 * If <code>cmdarray</code> is <code>null</code>, 596 * or one of the elements of <code>cmdarray</code> is <code>null</code>, 597 * or one of the elements of <code>envp</code> is <code>null</code> 598 * 599 * @throws IndexOutOfBoundsException 600 * If <code>cmdarray</code> is an empty array 601 * (has length <code>0</code>) 602 * 603 * @see ProcessBuilder 604 */ exec(String[] cmdarray, String[] envp)605 public Process exec(String[] cmdarray, String[] envp) throws IOException { 606 return exec(cmdarray, envp, null); 607 } 608 609 610 /** 611 * Executes the specified command and arguments in a separate process with 612 * the specified environment and working directory. 613 * 614 * <p>Given an array of strings <code>cmdarray</code>, representing the 615 * tokens of a command line, and an array of strings <code>envp</code>, 616 * representing "environment" variable settings, this method creates 617 * a new process in which to execute the specified command. 618 * 619 * <p>This method checks that <code>cmdarray</code> is a valid operating 620 * system command. Which commands are valid is system-dependent, 621 * but at the very least the command must be a non-empty list of 622 * non-null strings. 623 * 624 * <p>If <tt>envp</tt> is <tt>null</tt>, the subprocess inherits the 625 * environment settings of the current process. 626 * 627 * <p>A minimal set of system dependent environment variables may 628 * be required to start a process on some operating systems. 629 * As a result, the subprocess may inherit additional environment variable 630 * settings beyond those in the specified environment. 631 * 632 * <p>{@link ProcessBuilder#start()} is now the preferred way to 633 * start a process with a modified environment. 634 * 635 * <p>The working directory of the new subprocess is specified by <tt>dir</tt>. 636 * If <tt>dir</tt> is <tt>null</tt>, the subprocess inherits the 637 * current working directory of the current process. 638 * 639 * <p>If a security manager exists, its 640 * {@link SecurityManager#checkExec checkExec} 641 * method is invoked with the first component of the array 642 * <code>cmdarray</code> as its argument. This may result in a 643 * {@link SecurityException} being thrown. 644 * 645 * <p>Starting an operating system process is highly system-dependent. 646 * Among the many things that can go wrong are: 647 * <ul> 648 * <li>The operating system program file was not found. 649 * <li>Access to the program file was denied. 650 * <li>The working directory does not exist. 651 * </ul> 652 * 653 * <p>In such cases an exception will be thrown. The exact nature 654 * of the exception is system-dependent, but it will always be a 655 * subclass of {@link IOException}. 656 * 657 * 658 * @param cmdarray array containing the command to call and 659 * its arguments. 660 * 661 * @param envp array of strings, each element of which 662 * has environment variable settings in the format 663 * <i>name</i>=<i>value</i>, or 664 * <tt>null</tt> if the subprocess should inherit 665 * the environment of the current process. 666 * 667 * @param dir the working directory of the subprocess, or 668 * <tt>null</tt> if the subprocess should inherit 669 * the working directory of the current process. 670 * 671 * @return A new {@link Process} object for managing the subprocess 672 * 673 * @throws SecurityException 674 * If a security manager exists and its 675 * {@link SecurityManager#checkExec checkExec} 676 * method doesn't allow creation of the subprocess 677 * 678 * @throws IOException 679 * If an I/O error occurs 680 * 681 * @throws NullPointerException 682 * If <code>cmdarray</code> is <code>null</code>, 683 * or one of the elements of <code>cmdarray</code> is <code>null</code>, 684 * or one of the elements of <code>envp</code> is <code>null</code> 685 * 686 * @throws IndexOutOfBoundsException 687 * If <code>cmdarray</code> is an empty array 688 * (has length <code>0</code>) 689 * 690 * @see ProcessBuilder 691 * @since 1.3 692 */ exec(String[] cmdarray, String[] envp, File dir)693 public Process exec(String[] cmdarray, String[] envp, File dir) 694 throws IOException { 695 return new ProcessBuilder(cmdarray) 696 .environment(envp) 697 .directory(dir) 698 .start(); 699 } 700 701 /** 702 * Returns the number of processors available to the Java virtual machine. 703 * 704 * <p> This value may change during a particular invocation of the virtual 705 * machine. Applications that are sensitive to the number of available 706 * processors should therefore occasionally poll this property and adjust 707 * their resource usage appropriately. </p> 708 * 709 * @return the maximum number of processors available to the virtual 710 * machine; never smaller than one 711 * @since 1.4 712 */ availableProcessors()713 public int availableProcessors() { 714 return (int) Libcore.os.sysconf(_SC_NPROCESSORS_CONF); 715 } 716 717 /** 718 * Returns the amount of free memory in the Java Virtual Machine. 719 * Calling the 720 * <code>gc</code> method may result in increasing the value returned 721 * by <code>freeMemory.</code> 722 * 723 * @return an approximation to the total amount of memory currently 724 * available for future allocated objects, measured in bytes. 725 */ 726 @FastNative freeMemory()727 public native long freeMemory(); 728 729 /** 730 * Returns the total amount of memory in the Java virtual machine. 731 * The value returned by this method may vary over time, depending on 732 * the host environment. 733 * <p> 734 * Note that the amount of memory required to hold an object of any 735 * given type may be implementation-dependent. 736 * 737 * @return the total amount of memory currently available for current 738 * and future objects, measured in bytes. 739 */ 740 @FastNative totalMemory()741 public native long totalMemory(); 742 743 /** 744 * Returns the maximum amount of memory that the Java virtual machine will 745 * attempt to use. If there is no inherent limit then the value {@link 746 * java.lang.Long#MAX_VALUE} will be returned. 747 * 748 * @return the maximum amount of memory that the virtual machine will 749 * attempt to use, measured in bytes 750 * @since 1.4 751 */ 752 @FastNative maxMemory()753 public native long maxMemory(); 754 755 /** 756 * Runs the garbage collector. 757 * Calling this method suggests that the Java virtual machine expend 758 * effort toward recycling unused objects in order to make the memory 759 * they currently occupy available for quick reuse. When control 760 * returns from the method call, the virtual machine has made 761 * its best effort to recycle all discarded objects. 762 * <p> 763 * The name <code>gc</code> stands for "garbage 764 * collector". The virtual machine performs this recycling 765 * process automatically as needed, in a separate thread, even if the 766 * <code>gc</code> method is not invoked explicitly. 767 * <p> 768 * The method {@link System#gc()} is the conventional and convenient 769 * means of invoking this method. 770 */ 771 // Android-changed: Added BlockGuard check to gc() 772 // public native void gc(); gc()773 public void gc() { 774 BlockGuard.getThreadPolicy().onExplicitGc(); 775 nativeGc(); 776 } 777 nativeGc()778 private native void nativeGc(); 779 780 /* Wormhole for calling java.lang.ref.Finalizer.runFinalization */ runFinalization0()781 private static native void runFinalization0(); 782 783 /** 784 * Runs the finalization methods of any objects pending finalization. 785 * Calling this method suggests that the Java virtual machine expend 786 * effort toward running the <code>finalize</code> methods of objects 787 * that have been found to be discarded but whose <code>finalize</code> 788 * methods have not yet been run. When control returns from the 789 * method call, the virtual machine has made a best effort to 790 * complete all outstanding finalizations. 791 * <p> 792 * The virtual machine performs the finalization process 793 * automatically as needed, in a separate thread, if the 794 * <code>runFinalization</code> method is not invoked explicitly. 795 * <p> 796 * The method {@link System#runFinalization()} is the conventional 797 * and convenient means of invoking this method. 798 * 799 * @see java.lang.Object#finalize() 800 */ runFinalization()801 public void runFinalization() { 802 VMRuntime.runFinalization(0); 803 } 804 805 /** 806 * Enables/Disables tracing of instructions. 807 * If the <code>boolean</code> argument is <code>true</code>, this 808 * method suggests that the Java virtual machine emit debugging 809 * information for each instruction in the virtual machine as it 810 * is executed. The format of this information, and the file or other 811 * output stream to which it is emitted, depends on the host environment. 812 * The virtual machine may ignore this request if it does not support 813 * this feature. The destination of the trace output is system 814 * dependent. 815 * <p> 816 * If the <code>boolean</code> argument is <code>false</code>, this 817 * method causes the virtual machine to stop performing the 818 * detailed instruction trace it is performing. 819 * 820 * @param on <code>true</code> to enable instruction tracing; 821 * <code>false</code> to disable this feature. 822 */ traceInstructions(boolean on)823 public void traceInstructions(boolean on) { 824 } 825 826 /** 827 * Enables/Disables tracing of method calls. 828 * If the <code>boolean</code> argument is <code>true</code>, this 829 * method suggests that the Java virtual machine emit debugging 830 * information for each method in the virtual machine as it is 831 * called. The format of this information, and the file or other output 832 * stream to which it is emitted, depends on the host environment. The 833 * virtual machine may ignore this request if it does not support 834 * this feature. 835 * <p> 836 * Calling this method with argument false suggests that the 837 * virtual machine cease emitting per-call debugging information. 838 * <p> 839 * Calling this method on Android Lollipop or later (API level >= 21) 840 * with {@code true} argument will cause it to throw an 841 * {@code UnsupportedOperationException}. 842 * 843 * @param on <code>true</code> to enable instruction tracing; 844 * <code>false</code> to disable this feature. 845 */ traceMethodCalls(boolean on)846 public void traceMethodCalls(boolean on) { 847 if (on != tracingMethods) { 848 if (on) { 849 VMDebug.startMethodTracing(); 850 } else { 851 VMDebug.stopMethodTracing(); 852 } 853 tracingMethods = on; 854 } 855 } 856 857 /** 858 * Loads the native library specified by the filename argument. The filename 859 * argument must be an absolute path name. 860 * (for example 861 * <code>Runtime.getRuntime().load("/home/avh/lib/libX11.so");</code>). 862 * 863 * If the filename argument, when stripped of any platform-specific library 864 * prefix, path, and file extension, indicates a library whose name is, 865 * for example, L, and a native library called L is statically linked 866 * with the VM, then the JNI_OnLoad_L function exported by the library 867 * is invoked rather than attempting to load a dynamic library. 868 * A filename matching the argument does not have to exist in the file 869 * system. See the JNI Specification for more details. 870 * 871 * Otherwise, the filename argument is mapped to a native library image in 872 * an implementation-dependent manner. 873 * <p> 874 * First, if there is a security manager, its <code>checkLink</code> 875 * method is called with the <code>filename</code> as its argument. 876 * This may result in a security exception. 877 * <p> 878 * This is similar to the method {@link #loadLibrary(String)}, but it 879 * accepts a general file name as an argument rather than just a library 880 * name, allowing any file of native code to be loaded. 881 * <p> 882 * The method {@link System#load(String)} is the conventional and 883 * convenient means of invoking this method. 884 * 885 * @param filename the file to load. 886 * @exception SecurityException if a security manager exists and its 887 * <code>checkLink</code> method doesn't allow 888 * loading of the specified dynamic library 889 * @exception UnsatisfiedLinkError if either the filename is not an 890 * absolute path name, the native library is not statically 891 * linked with the VM, or the library cannot be mapped to 892 * a native library image by the host system. 893 * @exception NullPointerException if <code>filename</code> is 894 * <code>null</code> 895 * @see java.lang.Runtime#getRuntime() 896 * @see java.lang.SecurityException 897 * @see java.lang.SecurityManager#checkLink(java.lang.String) 898 */ 899 @CallerSensitive load(String filename)900 public void load(String filename) { 901 load0(Reflection.getCallerClass(), filename); 902 } 903 904 /** Check target sdk, if it's higher than N, we throw an UnsupportedOperationException */ checkTargetSdkVersionForLoad(String methodName)905 private void checkTargetSdkVersionForLoad(String methodName) { 906 final int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion(); 907 if (targetSdkVersion > 24) { 908 throw new UnsupportedOperationException(methodName + " is not supported on SDK " + 909 targetSdkVersion); 910 } 911 } 912 913 // Fixes b/25859957 regression. Depending on private methods is bad, mkay. load(String absolutePath, ClassLoader loader)914 void load(String absolutePath, ClassLoader loader) { 915 checkTargetSdkVersionForLoad("java.lang.Runtime#load(String, ClassLoader)"); 916 917 java.lang.System.logE("java.lang.Runtime#load(String, ClassLoader)" + 918 " is private and will be removed in a future Android release"); 919 if (absolutePath == null) { 920 throw new NullPointerException("absolutePath == null"); 921 } 922 String error = nativeLoad(absolutePath, loader); 923 if (error != null) { 924 throw new UnsatisfiedLinkError(error); 925 } 926 } 927 load0(Class<?> fromClass, String filename)928 synchronized void load0(Class<?> fromClass, String filename) { 929 if (!(new File(filename).isAbsolute())) { 930 throw new UnsatisfiedLinkError( 931 "Expecting an absolute path of the library: " + filename); 932 } 933 if (filename == null) { 934 throw new NullPointerException("filename == null"); 935 } 936 String error = nativeLoad(filename, fromClass.getClassLoader()); 937 if (error != null) { 938 throw new UnsatisfiedLinkError(error); 939 } 940 } 941 942 /** 943 * Loads the native library specified by the <code>libname</code> 944 * argument. The <code>libname</code> argument must not contain any platform 945 * specific prefix, file extension or path. If a native library 946 * called <code>libname</code> is statically linked with the VM, then the 947 * JNI_OnLoad_<code>libname</code> function exported by the library is invoked. 948 * See the JNI Specification for more details. 949 * 950 * Otherwise, the libname argument is loaded from a system library 951 * location and mapped to a native library image in an implementation- 952 * dependent manner. 953 * <p> 954 * First, if there is a security manager, its <code>checkLink</code> 955 * method is called with the <code>libname</code> as its argument. 956 * This may result in a security exception. 957 * <p> 958 * The method {@link System#loadLibrary(String)} is the conventional 959 * and convenient means of invoking this method. If native 960 * methods are to be used in the implementation of a class, a standard 961 * strategy is to put the native code in a library file (call it 962 * <code>LibFile</code>) and then to put a static initializer: 963 * <blockquote><pre> 964 * static { System.loadLibrary("LibFile"); } 965 * </pre></blockquote> 966 * within the class declaration. When the class is loaded and 967 * initialized, the necessary native code implementation for the native 968 * methods will then be loaded as well. 969 * <p> 970 * If this method is called more than once with the same library 971 * name, the second and subsequent calls are ignored. 972 * 973 * @param libname the name of the library. 974 * @exception SecurityException if a security manager exists and its 975 * <code>checkLink</code> method doesn't allow 976 * loading of the specified dynamic library 977 * @exception UnsatisfiedLinkError if either the libname argument 978 * contains a file path, the native library is not statically 979 * linked with the VM, or the library cannot be mapped to a 980 * native library image by the host system. 981 * @exception NullPointerException if <code>libname</code> is 982 * <code>null</code> 983 * @see java.lang.SecurityException 984 * @see java.lang.SecurityManager#checkLink(java.lang.String) 985 */ 986 @CallerSensitive loadLibrary(String libname)987 public void loadLibrary(String libname) { 988 loadLibrary0(Reflection.getCallerClass(), libname); 989 } 990 991 // BEGIN Android-changed: Different implementation of loadLibrary0(Class, String). 992 /* 993 synchronized void loadLibrary0(Class<?> fromClass, String libname) { 994 SecurityManager security = System.getSecurityManager(); 995 if (security != null) { 996 security.checkLink(libname); 997 } 998 if (libname.indexOf((int)File.separatorChar) != -1) { 999 throw new UnsatisfiedLinkError( 1000 "Directory separator should not appear in library name: " + libname); 1001 } 1002 ClassLoader.loadLibrary(fromClass, libname, false); 1003 } 1004 */ loadLibrary0(Class<?> fromClass, String libname)1005 void loadLibrary0(Class<?> fromClass, String libname) { 1006 ClassLoader classLoader = ClassLoader.getClassLoader(fromClass); 1007 loadLibrary0(classLoader, fromClass, libname); 1008 } 1009 1010 /** 1011 * Temporarily preserved for backward compatibility. Applications call this 1012 * method using reflection. 1013 * 1014 * **** THIS METHOD WILL BE REMOVED IN A FUTURE ANDROID VERSION **** 1015 * 1016 * http://b/26217329 1017 * 1018 * @hide 1019 */ loadLibrary(String libname, ClassLoader classLoader)1020 public void loadLibrary(String libname, ClassLoader classLoader) { 1021 checkTargetSdkVersionForLoad("java.lang.Runtime#loadLibrary(String, ClassLoader)"); 1022 java.lang.System.logE("java.lang.Runtime#loadLibrary(String, ClassLoader)" + 1023 " is private and will be removed in a future Android release"); 1024 // Pass null for callerClass, we don't know it at this point. Passing null preserved 1025 // the behavior when we used to not pass the class. 1026 loadLibrary0(classLoader, null, libname); 1027 } 1028 1029 // This overload exists for @UnsupportedAppUsage loadLibrary0(ClassLoader loader, String libname)1030 void loadLibrary0(ClassLoader loader, String libname) { 1031 // Pass null for callerClass, we don't know it at this point. Passing null preserved 1032 // the behavior when we used to not pass the class. 1033 loadLibrary0(loader, null, libname); 1034 } 1035 1036 /** 1037 * Loads the shared library {@code libname} in the context of {@code loader} and 1038 * {@code callerClass}. 1039 * 1040 * @param loader the class loader that initiated the loading. Used by the 1041 * underlying linker to determine linker namespace. A {@code null} 1042 * value represents the boot class loader. 1043 * @param fromClass the class that initiated the loading. Used when loader is 1044 * {@code null} and ignored in all other cases. When used, it 1045 * determines the linker namespace from the class's .dex location. 1046 * {@code null} indicates the default namespace for the boot 1047 * class loader. 1048 * @param libname the name of the library. 1049 */ loadLibrary0(ClassLoader loader, Class<?> callerClass, String libname)1050 private synchronized void loadLibrary0(ClassLoader loader, Class<?> callerClass, String libname) { 1051 if (libname.indexOf((int)File.separatorChar) != -1) { 1052 throw new UnsatisfiedLinkError( 1053 "Directory separator should not appear in library name: " + libname); 1054 } 1055 String libraryName = libname; 1056 // Android-note: BootClassLoader doesn't implement findLibrary(). http://b/111850480 1057 // Android's class.getClassLoader() can return BootClassLoader where the RI would 1058 // have returned null; therefore we treat BootClassLoader the same as null here. 1059 if (loader != null && !(loader instanceof BootClassLoader)) { 1060 String filename = loader.findLibrary(libraryName); 1061 if (filename == null) { 1062 // It's not necessarily true that the ClassLoader used 1063 // System.mapLibraryName, but the default setup does, and it's 1064 // misleading to say we didn't find "libMyLibrary.so" when we 1065 // actually searched for "liblibMyLibrary.so.so". 1066 throw new UnsatisfiedLinkError(loader + " couldn't find \"" + 1067 System.mapLibraryName(libraryName) + "\""); 1068 } 1069 String error = nativeLoad(filename, loader); 1070 if (error != null) { 1071 throw new UnsatisfiedLinkError(error); 1072 } 1073 return; 1074 } 1075 1076 // We know some apps use mLibPaths directly, potentially assuming it's not null. 1077 // Initialize it here to make sure apps see a non-null value. 1078 getLibPaths(); 1079 String filename = System.mapLibraryName(libraryName); 1080 String error = nativeLoad(filename, loader, callerClass); 1081 if (error != null) { 1082 throw new UnsatisfiedLinkError(error); 1083 } 1084 } 1085 1086 private volatile String[] mLibPaths = null; 1087 getLibPaths()1088 private String[] getLibPaths() { 1089 if (mLibPaths == null) { 1090 synchronized(this) { 1091 if (mLibPaths == null) { 1092 mLibPaths = initLibPaths(); 1093 } 1094 } 1095 } 1096 return mLibPaths; 1097 } 1098 initLibPaths()1099 private static String[] initLibPaths() { 1100 String javaLibraryPath = System.getProperty("java.library.path"); 1101 if (javaLibraryPath == null) { 1102 return EmptyArray.STRING; 1103 } 1104 String[] paths = javaLibraryPath.split(":"); 1105 // Add a '/' to the end of each directory so we don't have to do it every time. 1106 for (int i = 0; i < paths.length; ++i) { 1107 if (!paths[i].endsWith("/")) { 1108 paths[i] += "/"; 1109 } 1110 } 1111 return paths; 1112 } 1113 nativeLoad(String filename, ClassLoader loader)1114 private static String nativeLoad(String filename, ClassLoader loader) { 1115 return nativeLoad(filename, loader, null); 1116 } 1117 nativeLoad(String filename, ClassLoader loader, Class<?> caller)1118 private static native String nativeLoad(String filename, ClassLoader loader, Class<?> caller); 1119 // END Android-changed: Different implementation of loadLibrary0(Class, String). 1120 1121 /** 1122 * Creates a localized version of an input stream. This method takes 1123 * an <code>InputStream</code> and returns an <code>InputStream</code> 1124 * equivalent to the argument in all respects except that it is 1125 * localized: as characters in the local character set are read from 1126 * the stream, they are automatically converted from the local 1127 * character set to Unicode. 1128 * <p> 1129 * If the argument is already a localized stream, it may be returned 1130 * as the result. 1131 * 1132 * @param in InputStream to localize 1133 * @return a localized input stream 1134 * @see java.io.InputStream 1135 * @see java.io.BufferedReader#BufferedReader(java.io.Reader) 1136 * @see java.io.InputStreamReader#InputStreamReader(java.io.InputStream) 1137 * @deprecated As of JDK 1.1, the preferred way to translate a byte 1138 * stream in the local encoding into a character stream in Unicode is via 1139 * the <code>InputStreamReader</code> and <code>BufferedReader</code> 1140 * classes. 1141 */ 1142 @Deprecated getLocalizedInputStream(InputStream in)1143 public InputStream getLocalizedInputStream(InputStream in) { 1144 return in; 1145 } 1146 1147 /** 1148 * Creates a localized version of an output stream. This method 1149 * takes an <code>OutputStream</code> and returns an 1150 * <code>OutputStream</code> equivalent to the argument in all respects 1151 * except that it is localized: as Unicode characters are written to 1152 * the stream, they are automatically converted to the local 1153 * character set. 1154 * <p> 1155 * If the argument is already a localized stream, it may be returned 1156 * as the result. 1157 * 1158 * @deprecated As of JDK 1.1, the preferred way to translate a 1159 * Unicode character stream into a byte stream in the local encoding is via 1160 * the <code>OutputStreamWriter</code>, <code>BufferedWriter</code>, and 1161 * <code>PrintWriter</code> classes. 1162 * 1163 * @param out OutputStream to localize 1164 * @return a localized output stream 1165 * @see java.io.OutputStream 1166 * @see java.io.BufferedWriter#BufferedWriter(java.io.Writer) 1167 * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) 1168 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream) 1169 */ 1170 @Deprecated getLocalizedOutputStream(OutputStream out)1171 public OutputStream getLocalizedOutputStream(OutputStream out) { 1172 return out; 1173 } 1174 1175 } 1176