1 /* Runtime.java -- access to the VM process 2 Copyright (C) 1998, 2002, 2003 Free Software Foundation 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package java.lang; 39 40 import java.io.File; 41 import java.io.InputStream; 42 import java.io.IOException; 43 import java.io.OutputStream; 44 import java.util.HashSet; 45 import java.util.Iterator; 46 import java.util.Properties; 47 import java.util.Set; 48 import java.util.StringTokenizer; 49 50 /** 51 * Runtime represents the Virtual Machine. 52 * 53 * @author John Keiser 54 * @author Eric Blake <ebb9@email.byu.edu> 55 * @status still missing 1.4 functionality 56 */ 57 // No idea why this class isn't final, since you can't build a subclass! 58 public class Runtime 59 { 60 /** 61 * The library path, to search when loading libraries. We can also safely use 62 * this as a lock for synchronization. 63 */ 64 private final String[] libpath; 65 66 /** 67 * The current security manager. This is located here instead of in 68 * System, to avoid security problems, as well as bootstrap issues. 69 * Make sure to access it in a thread-safe manner; it is package visible 70 * to avoid overhead in java.lang. 71 */ 72 static SecurityManager securityManager; 73 74 /** 75 * The default properties defined by the system. This is likewise located 76 * here instead of in Runtime, to avoid bootstrap issues; it is package 77 * visible to avoid overhead in java.lang. Note that System will add a 78 * few more properties to this collection, but that after that, it is 79 * treated as read-only. 80 * 81 * No matter what class you start initialization with, it defers to the 82 * superclass, therefore Object.<clinit> will be the first Java code 83 * executed. From there, the bootstrap sequence, up to the point that 84 * native libraries are loaded (as of March 24, when I traced this 85 * manually) is as follows: 86 * 87 * Object.<clinit> uses a String literal, possibly triggering initialization 88 * String.<clinit> calls WeakHashMap.<init>, triggering initialization 89 * AbstractMap, WeakHashMap, WeakHashMap$1 have no dependencies 90 * String.<clinit> calls CaseInsensitiveComparator.<init>, triggering 91 * initialization 92 * CaseInsensitiveComparator has no dependencies 93 * Object.<clinit> calls System.loadLibrary, triggering initialization 94 * System.<clinit> calls System.loadLibrary 95 * System.loadLibrary calls Runtime.getRuntime, triggering initialization 96 * Runtime.<clinit> calls Properties.<init>, triggering initialization 97 * Dictionary, Hashtable, and Properties have no dependencies 98 * Runtime.<clinit> calls insertSystemProperties; the VM must make sure 99 * that there are not any harmful dependencies 100 * Runtime.<clinit> calls Runtime.<init> 101 * Runtime.<init> calls StringTokenizer.<init>, triggering initialization 102 * StringTokenizer has no dependencies 103 * System.loadLibrary calls Runtime.loadLibrary 104 * Runtime.loadLibrary should be able to load the library, although it 105 * will probably set off another string of initializations from 106 * ClassLoader first 107 */ 108 static Properties defaultProperties = new Properties(); 109 static 110 { 111 insertSystemProperties(defaultProperties); 112 } 113 114 /** 115 * The thread that started the exit sequence. Access to this field must 116 * be thread-safe; lock on libpath to avoid deadlock with user code. 117 * <code>runFinalization()</code> may want to look at this to see if ALL 118 * finalizers should be run, because the virtual machine is about to halt. 119 */ 120 private Thread exitSequence; 121 122 /** 123 * All shutdown hooks. This is initialized lazily, and set to null once all 124 * shutdown hooks have run. Access to this field must be thread-safe; lock 125 * on libpath to avoid deadlock with user code. 126 */ 127 private Set shutdownHooks; 128 129 /** True if we should finalize on exit. */ 130 private boolean finalizeOnExit; 131 132 /** 133 * The one and only runtime instance. This must appear after the default 134 * properties have been initialized by the VM. 135 */ 136 private static final Runtime current = new Runtime(); 137 138 /** 139 * Not instantiable by a user, this should only create one instance. 140 */ Runtime()141 private Runtime() 142 { 143 if (current != null) 144 throw new InternalError("Attempt to recreate Runtime"); 145 146 // We don't use libpath in the libgcj implementation. We still 147 // set it to something to allow the various synchronizations to 148 // work. 149 libpath = new String[0]; 150 151 init (); 152 } 153 154 /** 155 * Get the current Runtime object for this JVM. This is necessary to access 156 * the many instance methods of this class. 157 * 158 * @return the current Runtime object 159 */ getRuntime()160 public static Runtime getRuntime() 161 { 162 return current; 163 } 164 165 /** 166 * Exit the Java runtime. This method will either throw a SecurityException 167 * or it will never return. The status code is returned to the system; often 168 * a non-zero status code indicates an abnormal exit. Of course, there is a 169 * security check, <code>checkExit(status)</code>. 170 * 171 * <p>First, all shutdown hooks are run, in unspecified order, and 172 * concurrently. Next, if finalization on exit has been enabled, all pending 173 * finalizers are run. Finally, the system calls <code>halt</code>. 174 * 175 * <p>If this is run a second time after shutdown has already started, there 176 * are two actions. If shutdown hooks are still executing, it blocks 177 * indefinitely. Otherwise, if the status is nonzero it halts immediately; 178 * if it is zero, it blocks indefinitely. This is typically called by 179 * <code>System.exit</code>. 180 * 181 * @param status the status to exit with 182 * @throws SecurityException if permission is denied 183 * @see #addShutdownHook(Thread) 184 * @see #runFinalizersOnExit(boolean) 185 * @see #runFinalization() 186 * @see #halt(int) 187 */ exit(int status)188 public void exit(int status) 189 { 190 SecurityManager sm = securityManager; // Be thread-safe! 191 if (sm != null) 192 sm.checkExit(status); 193 boolean first = false; 194 synchronized (libpath) // Synch on libpath, not this, to avoid deadlock. 195 { 196 if (exitSequence == null) 197 { 198 first = true; 199 exitSequence = Thread.currentThread(); 200 if (shutdownHooks != null) 201 { 202 Iterator i = shutdownHooks.iterator(); 203 while (i.hasNext()) // Start all shutdown hooks. 204 try 205 { 206 ((Thread) i.next()).start(); 207 } 208 catch (IllegalThreadStateException e) 209 { 210 i.remove(); 211 } 212 } 213 } 214 } 215 if (first) 216 { 217 if (shutdownHooks != null) 218 { 219 // Check progress of all shutdown hooks. As a hook completes, 220 // remove it from the set. If a hook calls exit, it removes 221 // itself from the set, then waits indefinitely on the 222 // exitSequence thread. Once the set is empty, set it to null to 223 // signal all finalizer threads that halt may be called. 224 while (! shutdownHooks.isEmpty()) 225 { 226 Thread[] hooks; 227 synchronized (libpath) 228 { 229 hooks = new Thread[shutdownHooks.size()]; 230 shutdownHooks.toArray(hooks); 231 } 232 for (int i = hooks.length; --i >= 0; ) 233 if (! hooks[i].isAlive()) 234 synchronized (libpath) 235 { 236 shutdownHooks.remove(hooks[i]); 237 } 238 try 239 { 240 exitSequence.sleep(1); // Give other threads a chance. 241 } 242 catch (InterruptedException e) 243 { 244 // Ignore, the next loop just starts sooner. 245 } 246 } 247 synchronized (libpath) 248 { 249 shutdownHooks = null; 250 } 251 } 252 // XXX Right now, it is the VM that knows whether runFinalizersOnExit 253 // is true; so the VM must look at exitSequence to decide whether 254 // this should be run on every object. 255 runFinalization(); 256 } 257 else 258 synchronized (libpath) 259 { 260 if (shutdownHooks != null) 261 { 262 shutdownHooks.remove(Thread.currentThread()); 263 status = 0; // Change status to enter indefinite wait. 264 } 265 } 266 267 if (first || status > 0) 268 halt(status); 269 while (true) 270 try 271 { 272 exitSequence.join(); 273 } 274 catch (InterruptedException e) 275 { 276 // Ignore, we've suspended indefinitely to let all shutdown 277 // hooks complete, and to let any non-zero exits through, because 278 // this is a duplicate call to exit(0). 279 } 280 } 281 282 /** 283 * Register a new shutdown hook. This is invoked when the program exits 284 * normally (because all non-daemon threads ended, or because 285 * <code>System.exit</code> was invoked), or when the user terminates 286 * the virtual machine (such as by typing ^C, or logging off). There is 287 * a security check to add hooks, 288 * <code>RuntimePermission("shutdownHooks")<code>. 289 * 290 * <p>The hook must be an initialized, but unstarted Thread. The threads 291 * are run concurrently, and started in an arbitrary order; and user 292 * threads or daemons may still be running. Once shutdown hooks have 293 * started, they must all complete, or else you must use <code>halt</code>, 294 * to actually finish the shutdown sequence. Attempts to modify hooks 295 * after shutdown has started result in IllegalStateExceptions. 296 * 297 * <p>It is imperative that you code shutdown hooks defensively, as you 298 * do not want to deadlock, and have no idea what other hooks will be 299 * running concurrently. It is also a good idea to finish quickly, as the 300 * virtual machine really wants to shut down! 301 * 302 * <p>There are no guarantees that such hooks will run, as there are ways 303 * to forcibly kill a process. But in such a drastic case, shutdown hooks 304 * would do little for you in the first place. 305 * 306 * @param hook an initialized, unstarted Thread 307 * @throws IllegalArgumentException if the hook is already registered or run 308 * @throws IllegalStateException if the virtual machine is already in 309 * the shutdown sequence 310 * @throws SecurityException if permission is denied 311 * @since 1.3 312 * @see #removeShutdownHook(Thread) 313 * @see #exit(int) 314 * @see #halt(int) 315 */ addShutdownHook(Thread hook)316 public void addShutdownHook(Thread hook) 317 { 318 SecurityManager sm = securityManager; // Be thread-safe! 319 if (sm != null) 320 sm.checkPermission(new RuntimePermission("shutdownHooks")); 321 if (hook.isAlive() || hook.getThreadGroup() == null) 322 throw new IllegalArgumentException(); 323 synchronized (libpath) 324 { 325 if (exitSequence != null) 326 throw new IllegalStateException(); 327 if (shutdownHooks == null) 328 shutdownHooks = new HashSet(); // Lazy initialization. 329 if (! shutdownHooks.add(hook)) 330 throw new IllegalArgumentException(); 331 } 332 } 333 334 /** 335 * De-register a shutdown hook. As when you registered it, there is a 336 * security check to remove hooks, 337 * <code>RuntimePermission("shutdownHooks")<code>. 338 * 339 * @param hook the hook to remove 340 * @return true if the hook was successfully removed, false if it was not 341 * registered in the first place 342 * @throws IllegalStateException if the virtual machine is already in 343 * the shutdown sequence 344 * @throws SecurityException if permission is denied 345 * @since 1.3 346 * @see #addShutdownHook(Thread) 347 * @see #exit(int) 348 * @see #halt(int) 349 */ removeShutdownHook(Thread hook)350 public boolean removeShutdownHook(Thread hook) 351 { 352 SecurityManager sm = securityManager; // Be thread-safe! 353 if (sm != null) 354 sm.checkPermission(new RuntimePermission("shutdownHooks")); 355 synchronized (libpath) 356 { 357 if (exitSequence != null) 358 throw new IllegalStateException(); 359 if (shutdownHooks != null) 360 return shutdownHooks.remove(hook); 361 } 362 return false; 363 } 364 365 /** 366 * Forcibly terminate the virtual machine. This call never returns. It is 367 * much more severe than <code>exit</code>, as it bypasses all shutdown 368 * hooks and initializers. Use caution in calling this! Of course, there is 369 * a security check, <code>checkExit(status)</code>. 370 * 371 * @param status the status to exit with 372 * @throws SecurityException if permission is denied 373 * @since 1.3 374 * @see #exit(int) 375 * @see #addShutdownHook(Thread) 376 */ halt(int status)377 public void halt(int status) 378 { 379 SecurityManager sm = securityManager; // Be thread-safe! 380 if (sm != null) 381 sm.checkExit(status); 382 exitInternal(status); 383 } 384 385 /** 386 * Tell the VM to run the finalize() method on every single Object before 387 * it exits. Note that the JVM may still exit abnormally and not perform 388 * this, so you still don't have a guarantee. And besides that, this is 389 * inherently unsafe in multi-threaded code, as it may result in deadlock 390 * as multiple threads compete to manipulate objects. This value defaults to 391 * <code>false</code>. There is a security check, <code>checkExit(0)</code>. 392 * 393 * @param finalizeOnExit whether to finalize all Objects on exit 394 * @throws SecurityException if permission is denied 395 * @see #exit(int) 396 * @see #gc() 397 * @since 1.1 398 * @deprecated never rely on finalizers to do a clean, thread-safe, 399 * mop-up from your code 400 */ runFinalizersOnExit(boolean finalizeOnExit)401 public static void runFinalizersOnExit(boolean finalizeOnExit) 402 { 403 SecurityManager sm = securityManager; // Be thread-safe! 404 if (sm != null) 405 sm.checkExit(0); 406 current.finalizeOnExit = finalizeOnExit; 407 } 408 409 /** 410 * Create a new subprocess with the specified command line. Calls 411 * <code>exec(cmdline, null, null)<code>. A security check is performed, 412 * <code>checkExec</code>. 413 * 414 * @param cmdline the command to call 415 * @return the Process object 416 * @throws SecurityException if permission is denied 417 * @throws IOException if an I/O error occurs 418 * @throws NullPointerException if cmdline is null 419 * @throws IndexOutOfBoundsException if cmdline is "" 420 */ exec(String cmdline)421 public Process exec(String cmdline) throws IOException 422 { 423 return exec(cmdline, null, null); 424 } 425 426 /** 427 * Create a new subprocess with the specified command line and environment. 428 * If the environment is null, the process inherits the environment of 429 * this process. Calls <code>exec(cmdline, env, null)</code>. A security 430 * check is performed, <code>checkExec</code>. 431 * 432 * @param cmdline the command to call 433 * @param env the environment to use, in the format name=value 434 * @return the Process object 435 * @throws SecurityException if permission is denied 436 * @throws IOException if an I/O error occurs 437 * @throws NullPointerException if cmdline is null, or env has null entries 438 * @throws IndexOutOfBoundsException if cmdline is "" 439 */ exec(String cmdline, String[] env)440 public Process exec(String cmdline, String[] env) throws IOException 441 { 442 return exec(cmdline, env, null); 443 } 444 445 /** 446 * Create a new subprocess with the specified command line, environment, and 447 * working directory. If the environment is null, the process inherits the 448 * environment of this process. If the directory is null, the process uses 449 * the current working directory. This splits cmdline into an array, using 450 * the default StringTokenizer, then calls 451 * <code>exec(cmdArray, env, dir)</code>. A security check is performed, 452 * <code>checkExec</code>. 453 * 454 * @param cmdline the command to call 455 * @param env the environment to use, in the format name=value 456 * @param dir the working directory to use 457 * @return the Process object 458 * @throws SecurityException if permission is denied 459 * @throws IOException if an I/O error occurs 460 * @throws NullPointerException if cmdline is null, or env has null entries 461 * @throws IndexOutOfBoundsException if cmdline is "" 462 * @since 1.3 463 */ exec(String cmdline, String[] env, File dir)464 public Process exec(String cmdline, String[] env, File dir) 465 throws IOException 466 { 467 StringTokenizer t = new StringTokenizer(cmdline); 468 String[] cmd = new String[t.countTokens()]; 469 for (int i = 0; i < cmd.length; i++) 470 cmd[i] = t.nextToken(); 471 return exec(cmd, env, dir); 472 } 473 474 /** 475 * Create a new subprocess with the specified command line, already 476 * tokenized. Calls <code>exec(cmd, null, null)</code>. A security check 477 * is performed, <code>checkExec</code>. 478 * 479 * @param cmd the command to call 480 * @return the Process object 481 * @throws SecurityException if permission is denied 482 * @throws IOException if an I/O error occurs 483 * @throws NullPointerException if cmd is null, or has null entries 484 * @throws IndexOutOfBoundsException if cmd is length 0 485 */ exec(String[] cmd)486 public Process exec(String[] cmd) throws IOException 487 { 488 return exec(cmd, null, null); 489 } 490 491 /** 492 * Create a new subprocess with the specified command line, already 493 * tokenized, and specified environment. If the environment is null, the 494 * process inherits the environment of this process. Calls 495 * <code>exec(cmd, env, null)</code>. A security check is performed, 496 * <code>checkExec</code>. 497 * 498 * @param cmd the command to call 499 * @param env the environment to use, in the format name=value 500 * @return the Process object 501 * @throws SecurityException if permission is denied 502 * @throws IOException if an I/O error occurs 503 * @throws NullPointerException if cmd is null, or cmd or env has null 504 * entries 505 * @throws IndexOutOfBoundsException if cmd is length 0 506 */ exec(String[] cmd, String[] env)507 public Process exec(String[] cmd, String[] env) throws IOException 508 { 509 return exec(cmd, env, null); 510 } 511 512 /** 513 * Create a new subprocess with the specified command line, already 514 * tokenized, and the specified environment and working directory. If the 515 * environment is null, the process inherits the environment of this 516 * process. If the directory is null, the process uses the current working 517 * directory. A security check is performed, <code>checkExec</code>. 518 * 519 * @param cmd the command to call 520 * @param env the environment to use, in the format name=value 521 * @param dir the working directory to use 522 * @return the Process object 523 * @throws SecurityException if permission is denied 524 * @throws IOException if an I/O error occurs 525 * @throws NullPointerException if cmd is null, or cmd or env has null 526 * entries 527 * @throws IndexOutOfBoundsException if cmd is length 0 528 * @since 1.3 529 */ exec(String[] cmd, String[] env, File dir)530 public Process exec(String[] cmd, String[] env, File dir) 531 throws IOException 532 { 533 SecurityManager sm = securityManager; // Be thread-safe! 534 if (sm != null) 535 sm.checkExec(cmd[0]); 536 return execInternal(cmd, env, dir); 537 } 538 539 /** 540 * Returns the number of available processors currently available to the 541 * virtual machine. This number may change over time; so a multi-processor 542 * program want to poll this to determine maximal resource usage. 543 * 544 * @return the number of processors available, at least 1 545 */ availableProcessors()546 public native int availableProcessors(); 547 548 /** 549 * Find out how much memory is still free for allocating Objects on the heap. 550 * 551 * @return the number of bytes of free memory for more Objects 552 */ freeMemory()553 public native long freeMemory(); 554 555 /** 556 * Find out how much memory total is available on the heap for allocating 557 * Objects. 558 * 559 * @return the total number of bytes of memory for Objects 560 */ totalMemory()561 public native long totalMemory(); 562 563 /** 564 * Returns the maximum amount of memory the virtual machine can attempt to 565 * use. This may be <code>Long.MAX_VALUE</code> if there is no inherent 566 * limit (or if you really do have a 8 exabyte memory!). 567 * 568 * @return the maximum number of bytes the virtual machine will attempt 569 * to allocate 570 */ maxMemory()571 public native long maxMemory(); 572 573 /** 574 * Run the garbage collector. This method is more of a suggestion than 575 * anything. All this method guarantees is that the garbage collector will 576 * have "done its best" by the time it returns. Notice that garbage 577 * collection takes place even without calling this method. 578 */ gc()579 public native void gc(); 580 581 /** 582 * Run finalization on all Objects that are waiting to be finalized. Again, 583 * a suggestion, though a stronger one than {@link #gc()}. This calls the 584 * <code>finalize</code> method of all objects waiting to be collected. 585 * 586 * @see #finalize() 587 */ runFinalization()588 public native void runFinalization(); 589 590 /** 591 * Tell the VM to trace every bytecode instruction that executes (print out 592 * a trace of it). No guarantees are made as to where it will be printed, 593 * and the VM is allowed to ignore this request. 594 * 595 * @param on whether to turn instruction tracing on 596 */ traceInstructions(boolean on)597 public native void traceInstructions(boolean on); 598 599 /** 600 * Tell the VM to trace every method call that executes (print out a trace 601 * of it). No guarantees are made as to where it will be printed, and the 602 * VM is allowed to ignore this request. 603 * 604 * @param on whether to turn method tracing on 605 */ traceMethodCalls(boolean on)606 public native void traceMethodCalls(boolean on); 607 608 /** 609 * Load a native library using the system-dependent filename. This is similar 610 * to loadLibrary, except the only name mangling done is inserting "_g" 611 * before the final ".so" if the VM was invoked by the name "java_g". There 612 * may be a security check, of <code>checkLink</code>. 613 * 614 * @param filename the file to load 615 * @throws SecurityException if permission is denied 616 * @throws UnsatisfiedLinkError if the library is not found 617 */ load(String filename)618 public void load(String filename) 619 { 620 SecurityManager sm = securityManager; // Be thread-safe! 621 if (sm != null) 622 sm.checkLink(filename); 623 _load(filename, false); 624 } 625 626 /** 627 * Load a native library using a system-independent "short name" for the 628 * library. It will be transformed to a correct filename in a 629 * system-dependent manner (for example, in Windows, "mylib" will be turned 630 * into "mylib.dll"). This is done as follows: if the context that called 631 * load has a ClassLoader cl, then <code>cl.findLibrary(libpath)</code> is 632 * used to convert the name. If that result was null, or there was no class 633 * loader, this searches each directory of the system property 634 * <code>java.library.path</code> for a file named 635 * <code>System.mapLibraryName(libname)</code>. There may be a security 636 * check, of <code>checkLink</code>. 637 * 638 * @param filename the file to load 639 * @throws SecurityException if permission is denied 640 * @throws UnsatisfiedLinkError if the library is not found 641 * @see System#mapLibraryName(String) 642 * @see ClassLoader#findLibrary(String) 643 */ loadLibrary(String libname)644 public void loadLibrary(String libname) 645 { 646 // This is different from the Classpath implementation, but I 647 // believe it is more correct. 648 SecurityManager sm = securityManager; // Be thread-safe! 649 if (sm != null) 650 sm.checkLink(libname); 651 _load(libname, true); 652 } 653 654 /** 655 * Return a localized version of this InputStream, meaning all characters 656 * are localized before they come out the other end. 657 * 658 * @param in the stream to localize 659 * @return the localized stream 660 * @deprecated <code>InputStreamReader</code> is the preferred way to read 661 * local encodings 662 */ getLocalizedInputStream(InputStream in)663 public InputStream getLocalizedInputStream(InputStream in) 664 { 665 return in; 666 } 667 668 /** 669 * Return a localized version of this OutputStream, meaning all characters 670 * are localized before they are sent to the other end. 671 * 672 * @param out the stream to localize 673 * @return the localized stream 674 * @deprecated <code>OutputStreamWriter</code> is the preferred way to write 675 * local encodings 676 */ getLocalizedOutputStream(OutputStream out)677 public OutputStream getLocalizedOutputStream(OutputStream out) 678 { 679 return out; 680 } 681 682 /** 683 * Native method that actually shuts down the virtual machine. 684 * 685 * @param status the status to end the process with 686 */ exitInternal(int status)687 native void exitInternal(int status); 688 689 /** 690 * Load a file. If it has already been loaded, do nothing. The name has 691 * already been mapped to a true filename. 692 * 693 * @param filename the file to load 694 * @param do_search True if we should search the load path for the file 695 */ _load(String filename, boolean do_search)696 native void _load(String filename, boolean do_search); 697 698 /** 699 *This is a helper function for the ClassLoader which can load 700 * compiled libraries. Returns true if library (which is just the 701 * base name -- path searching is done by this function) was loaded, 702 * false otherwise. 703 */ loadLibraryInternal(String libname)704 native boolean loadLibraryInternal(String libname); 705 706 /** 707 * A helper for the constructor which does some internal native 708 * initialization. 709 */ init()710 private native void init (); 711 712 /** 713 * Map a system-independent "short name" to the full file name, and append 714 * it to the path. 715 * XXX This method is being replaced by System.mapLibraryName. 716 * 717 * @param pathname the path 718 * @param libname the short version of the library name 719 * @return the full filename 720 */ nativeGetLibname(String pathname, String libname)721 static native String nativeGetLibname(String pathname, String libname); 722 723 /** 724 * Execute a process. The command line has already been tokenized, and 725 * the environment should contain name=value mappings. If directory is null, 726 * use the current working directory; otherwise start the process in that 727 * directory. 728 * 729 * @param cmd the non-null command tokens 730 * @param env the non-null environment setup 731 * @param dir the directory to use, may be null 732 * @return the newly created process 733 * @throws NullPointerException if cmd or env have null elements 734 */ execInternal(String[] cmd, String[] env, File dir)735 native Process execInternal(String[] cmd, String[] env, File dir); 736 737 /** 738 * Get the system properties. This is done here, instead of in System, 739 * because of the bootstrap sequence. Note that the native code should 740 * not try to use the Java I/O classes yet, as they rely on the properties 741 * already existing. The only safe method to use to insert these default 742 * system properties is {@link Properties#setProperty(String, String)}. 743 * 744 * <p>These properties MUST include: 745 * <dl> 746 * <dt>java.version <dd>Java version number 747 * <dt>java.vendor <dd>Java vendor specific string 748 * <dt>java.vendor.url <dd>Java vendor URL 749 * <dt>java.home <dd>Java installation directory 750 * <dt>java.vm.specification.version <dd>VM Spec version 751 * <dt>java.vm.specification.vendor <dd>VM Spec vendor 752 * <dt>java.vm.specification.name <dd>VM Spec name 753 * <dt>java.vm.version <dd>VM implementation version 754 * <dt>java.vm.vendor <dd>VM implementation vendor 755 * <dt>java.vm.name <dd>VM implementation name 756 * <dt>java.specification.version <dd>Java Runtime Environment version 757 * <dt>java.specification.vendor <dd>Java Runtime Environment vendor 758 * <dt>java.specification.name <dd>Java Runtime Environment name 759 * <dt>java.class.version <dd>Java class version number 760 * <dt>java.class.path <dd>Java classpath 761 * <dt>java.library.path <dd>Path for finding Java libraries 762 * <dt>java.io.tmpdir <dd>Default temp file path 763 * <dt>java.compiler <dd>Name of JIT to use 764 * <dt>java.ext.dirs <dd>Java extension path 765 * <dt>os.name <dd>Operating System Name 766 * <dt>os.arch <dd>Operating System Architecture 767 * <dt>os.version <dd>Operating System Version 768 * <dt>file.separator <dd>File separator ("/" on Unix) 769 * <dt>path.separator <dd>Path separator (":" on Unix) 770 * <dt>line.separator <dd>Line separator ("\n" on Unix) 771 * <dt>user.name <dd>User account name 772 * <dt>user.home <dd>User home directory 773 * <dt>user.dir <dd>User's current working directory 774 * </dl> 775 * 776 * @param p the Properties object to insert the system properties into 777 */ insertSystemProperties(Properties p)778 static native void insertSystemProperties(Properties p); 779 } // class Runtime 780