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