001/* Runtime.java -- access to the VM process 002 Copyright (C) 1998, 2002, 2003, 2004, 2005 Free Software Foundation 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package java.lang; 040 041import gnu.classpath.SystemProperties; 042import gnu.classpath.VMStackWalker; 043 044import java.io.File; 045import java.io.IOException; 046import java.io.InputStream; 047import java.io.OutputStream; 048import java.util.HashSet; 049import java.util.Iterator; 050import java.util.Set; 051import java.util.StringTokenizer; 052 053/** 054 * Runtime represents the Virtual Machine. 055 * 056 * @author John Keiser 057 * @author Eric Blake (ebb9@email.byu.edu) 058 * @author Jeroen Frijters 059 */ 060// No idea why this class isn't final, since you can't build a subclass! 061public class Runtime 062{ 063 /** 064 * The library path, to search when loading libraries. We can also safely use 065 * this as a lock for synchronization. 066 */ 067 private final String[] libpath; 068 069 /** 070 * The thread that started the exit sequence. Access to this field must 071 * be thread-safe; lock on libpath to avoid deadlock with user code. 072 * <code>runFinalization()</code> may want to look at this to see if ALL 073 * finalizers should be run, because the virtual machine is about to halt. 074 */ 075 private Thread exitSequence; 076 077 /** 078 * All shutdown hooks. This is initialized lazily, and set to null once all 079 * shutdown hooks have run. Access to this field must be thread-safe; lock 080 * on libpath to avoid deadlock with user code. 081 */ 082 private Set shutdownHooks; 083 084 /** 085 * The one and only runtime instance. 086 */ 087 private static final Runtime current = new Runtime(); 088 089 /** 090 * Not instantiable by a user, this should only create one instance. 091 */ 092 private Runtime() 093 { 094 if (current != null) 095 throw new InternalError("Attempt to recreate Runtime"); 096 097 // If used by underlying VM this contains the directories where Classpath's own 098 // native libraries are located. 099 String bootPath = SystemProperties.getProperty("gnu.classpath.boot.library.path", ""); 100 101 // If properly set by the user this contains the directories where the application's 102 // native libraries are located. On operating systems where a LD_LIBRARY_PATH environment 103 // variable is available a VM should preset java.library.path with value of this 104 // variable. 105 String path = SystemProperties.getProperty("java.library.path", "."); 106 String pathSep = SystemProperties.getProperty("path.separator", ":"); 107 String fileSep = SystemProperties.getProperty("file.separator", "/"); 108 109 StringTokenizer t1 = new StringTokenizer(bootPath, pathSep); 110 StringTokenizer t2 = new StringTokenizer(path, pathSep); 111 libpath = new String[t1.countTokens() + t2.countTokens()]; 112 113 int i = 0; 114 while(t1.hasMoreTokens()) { 115 String prefix = t1.nextToken(); 116 if (! prefix.endsWith(fileSep)) 117 prefix += fileSep; 118 119 libpath[i] = prefix; 120 i++; 121 } 122 123 while(t2.hasMoreTokens()) { 124 String prefix = t2.nextToken(); 125 if (! prefix.endsWith(fileSep)) 126 prefix += fileSep; 127 128 libpath[i] = prefix; 129 i++; 130 } 131 } 132 133 /** 134 * Get the current Runtime object for this JVM. This is necessary to access 135 * the many instance methods of this class. 136 * 137 * @return the current Runtime object 138 */ 139 public static Runtime getRuntime() 140 { 141 return current; 142 } 143 144 /** 145 * Exit the Java runtime. This method will either throw a SecurityException 146 * or it will never return. The status code is returned to the system; often 147 * a non-zero status code indicates an abnormal exit. Of course, there is a 148 * security check, <code>checkExit(status)</code>. 149 * 150 * <p>First, all shutdown hooks are run, in unspecified order, and 151 * concurrently. Next, if finalization on exit has been enabled, all pending 152 * finalizers are run. Finally, the system calls <code>halt</code>.</p> 153 * 154 * <p>If this is run a second time after shutdown has already started, there 155 * are two actions. If shutdown hooks are still executing, it blocks 156 * indefinitely. Otherwise, if the status is nonzero it halts immediately; 157 * if it is zero, it blocks indefinitely. This is typically called by 158 * <code>System.exit</code>.</p> 159 * 160 * @param status the status to exit with 161 * @throws SecurityException if permission is denied 162 * @see #addShutdownHook(Thread) 163 * @see #runFinalizersOnExit(boolean) 164 * @see #runFinalization() 165 * @see #halt(int) 166 */ 167 public void exit(int status) 168 { 169 SecurityManager sm = SecurityManager.current; // Be thread-safe! 170 if (sm != null) 171 sm.checkExit(status); 172 173 if (runShutdownHooks()) 174 halt(status); 175 176 // Someone else already called runShutdownHooks(). 177 // Make sure we are not/no longer in the shutdownHooks set. 178 // And wait till the thread that is calling runShutdownHooks() finishes. 179 synchronized (libpath) 180 { 181 if (shutdownHooks != null) 182 { 183 shutdownHooks.remove(Thread.currentThread()); 184 // Interrupt the exit sequence thread, in case it was waiting 185 // inside a join on our thread. 186 exitSequence.interrupt(); 187 // Shutdown hooks are still running, so we clear status to 188 // make sure we don't halt. 189 status = 0; 190 } 191 } 192 193 // If exit() is called again after the shutdown hooks have run, but 194 // while finalization for exit is going on and the status is non-zero 195 // we halt immediately. 196 if (status != 0) 197 halt(status); 198 199 while (true) 200 try 201 { 202 exitSequence.join(); 203 } 204 catch (InterruptedException e) 205 { 206 // Ignore, we've suspended indefinitely to let all shutdown 207 // hooks complete, and to let any non-zero exits through, because 208 // this is a duplicate call to exit(0). 209 } 210 } 211 212 /** 213 * On first invocation, run all the shutdown hooks and return true. 214 * Any subsequent invocations will simply return false. 215 * Note that it is package accessible so that VMRuntime can call it 216 * when VM exit is not triggered by a call to Runtime.exit(). 217 * 218 * @return was the current thread the first one to call this method? 219 */ 220 boolean runShutdownHooks() 221 { 222 boolean first = false; 223 synchronized (libpath) // Synch on libpath, not this, to avoid deadlock. 224 { 225 if (exitSequence == null) 226 { 227 first = true; 228 exitSequence = Thread.currentThread(); 229 if (shutdownHooks != null) 230 { 231 Iterator i = shutdownHooks.iterator(); 232 while (i.hasNext()) // Start all shutdown hooks. 233 try 234 { 235 ((Thread) i.next()).start(); 236 } 237 catch (IllegalThreadStateException e) 238 { 239 i.remove(); 240 } 241 } 242 } 243 } 244 if (first) 245 { 246 if (shutdownHooks != null) 247 { 248 // Check progress of all shutdown hooks. As a hook completes, 249 // remove it from the set. If a hook calls exit, it removes 250 // itself from the set, then waits indefinitely on the 251 // exitSequence thread. Once the set is empty, set it to null to 252 // signal all finalizer threads that halt may be called. 253 while (true) 254 { 255 Thread[] hooks; 256 synchronized (libpath) 257 { 258 hooks = new Thread[shutdownHooks.size()]; 259 shutdownHooks.toArray(hooks); 260 } 261 if (hooks.length == 0) 262 break; 263 for (int i = 0; i < hooks.length; i++) 264 { 265 try 266 { 267 synchronized (libpath) 268 { 269 if (!shutdownHooks.contains(hooks[i])) 270 continue; 271 } 272 hooks[i].join(); 273 synchronized (libpath) 274 { 275 shutdownHooks.remove(hooks[i]); 276 } 277 } 278 catch (InterruptedException x) 279 { 280 // continue waiting on the next thread 281 } 282 } 283 } 284 synchronized (libpath) 285 { 286 shutdownHooks = null; 287 } 288 } 289 // Run finalization on all finalizable objects (even if they are 290 // still reachable). 291 VMRuntime.runFinalizationForExit(); 292 } 293 return first; 294 } 295 296 /** 297 * Register a new shutdown hook. This is invoked when the program exits 298 * normally (because all non-daemon threads ended, or because 299 * <code>System.exit</code> was invoked), or when the user terminates 300 * the virtual machine (such as by typing ^C, or logging off). There is 301 * a security check to add hooks, 302 * <code>RuntimePermission("shutdownHooks")</code>. 303 * 304 * <p>The hook must be an initialized, but unstarted Thread. The threads 305 * are run concurrently, and started in an arbitrary order; and user 306 * threads or daemons may still be running. Once shutdown hooks have 307 * started, they must all complete, or else you must use <code>halt</code>, 308 * to actually finish the shutdown sequence. Attempts to modify hooks 309 * after shutdown has started result in IllegalStateExceptions.</p> 310 * 311 * <p>It is imperative that you code shutdown hooks defensively, as you 312 * do not want to deadlock, and have no idea what other hooks will be 313 * running concurrently. It is also a good idea to finish quickly, as the 314 * virtual machine really wants to shut down!</p> 315 * 316 * <p>There are no guarantees that such hooks will run, as there are ways 317 * to forcibly kill a process. But in such a drastic case, shutdown hooks 318 * would do little for you in the first place.</p> 319 * 320 * @param hook an initialized, unstarted Thread 321 * @throws IllegalArgumentException if the hook is already registered or run 322 * @throws IllegalStateException if the virtual machine is already in 323 * the shutdown sequence 324 * @throws SecurityException if permission is denied 325 * @since 1.3 326 * @see #removeShutdownHook(Thread) 327 * @see #exit(int) 328 * @see #halt(int) 329 */ 330 public void addShutdownHook(Thread hook) 331 { 332 SecurityManager sm = SecurityManager.current; // Be thread-safe! 333 if (sm != null) 334 sm.checkPermission(new RuntimePermission("shutdownHooks")); 335 if (hook.isAlive() || hook.getThreadGroup() == null) 336 throw new IllegalArgumentException("The hook thread " + hook + " must not have been already run or started"); 337 synchronized (libpath) 338 { 339 if (exitSequence != null) 340 throw new IllegalStateException("The Virtual Machine is exiting. It is not possible anymore to add any hooks"); 341 if (shutdownHooks == null) 342 { 343 VMRuntime.enableShutdownHooks(); 344 shutdownHooks = new HashSet(); // Lazy initialization. 345 } 346 if (! shutdownHooks.add(hook)) 347 throw new IllegalArgumentException(hook.toString() + " had already been inserted"); 348 } 349 } 350 351 /** 352 * De-register a shutdown hook. As when you registered it, there is a 353 * security check to remove hooks, 354 * <code>RuntimePermission("shutdownHooks")</code>. 355 * 356 * @param hook the hook to remove 357 * @return true if the hook was successfully removed, false if it was not 358 * registered in the first place 359 * @throws IllegalStateException if the virtual machine is already in 360 * the shutdown sequence 361 * @throws SecurityException if permission is denied 362 * @since 1.3 363 * @see #addShutdownHook(Thread) 364 * @see #exit(int) 365 * @see #halt(int) 366 */ 367 public boolean removeShutdownHook(Thread hook) 368 { 369 SecurityManager sm = SecurityManager.current; // Be thread-safe! 370 if (sm != null) 371 sm.checkPermission(new RuntimePermission("shutdownHooks")); 372 synchronized (libpath) 373 { 374 if (exitSequence != null) 375 throw new IllegalStateException(); 376 if (shutdownHooks != null) 377 return shutdownHooks.remove(hook); 378 } 379 return false; 380 } 381 382 /** 383 * Forcibly terminate the virtual machine. This call never returns. It is 384 * much more severe than <code>exit</code>, as it bypasses all shutdown 385 * hooks and initializers. Use caution in calling this! Of course, there is 386 * a security check, <code>checkExit(status)</code>. 387 * 388 * @param status the status to exit with 389 * @throws SecurityException if permission is denied 390 * @since 1.3 391 * @see #exit(int) 392 * @see #addShutdownHook(Thread) 393 */ 394 public void halt(int status) 395 { 396 SecurityManager sm = SecurityManager.current; // Be thread-safe! 397 if (sm != null) 398 sm.checkExit(status); 399 VMRuntime.exit(status); 400 } 401 402 /** 403 * Tell the VM to run the finalize() method on every single Object before 404 * it exits. Note that the JVM may still exit abnormally and not perform 405 * this, so you still don't have a guarantee. And besides that, this is 406 * inherently unsafe in multi-threaded code, as it may result in deadlock 407 * as multiple threads compete to manipulate objects. This value defaults to 408 * <code>false</code>. There is a security check, <code>checkExit(0)</code>. 409 * 410 * @param finalizeOnExit whether to finalize all Objects on exit 411 * @throws SecurityException if permission is denied 412 * @see #exit(int) 413 * @see #gc() 414 * @since 1.1 415 * @deprecated never rely on finalizers to do a clean, thread-safe, 416 * mop-up from your code 417 */ 418 public static void runFinalizersOnExit(boolean finalizeOnExit) 419 { 420 SecurityManager sm = SecurityManager.current; // Be thread-safe! 421 if (sm != null) 422 sm.checkExit(0); 423 VMRuntime.runFinalizersOnExit(finalizeOnExit); 424 } 425 426 /** 427 * Create a new subprocess with the specified command line. Calls 428 * <code>exec(cmdline, null, null)</code>. A security check is performed, 429 * <code>checkExec</code>. 430 * 431 * @param cmdline the command to call 432 * @return the Process object 433 * @throws SecurityException if permission is denied 434 * @throws IOException if an I/O error occurs 435 * @throws NullPointerException if cmdline is null 436 * @throws IndexOutOfBoundsException if cmdline is "" 437 */ 438 public Process exec(String cmdline) throws IOException 439 { 440 return exec(cmdline, null, null); 441 } 442 443 /** 444 * Create a new subprocess with the specified command line and environment. 445 * If the environment is null, the process inherits the environment of 446 * this process. Calls <code>exec(cmdline, env, null)</code>. A security 447 * check is performed, <code>checkExec</code>. 448 * 449 * @param cmdline the command to call 450 * @param env the environment to use, in the format name=value 451 * @return the Process object 452 * @throws SecurityException if permission is denied 453 * @throws IOException if an I/O error occurs 454 * @throws NullPointerException if cmdline is null, or env has null entries 455 * @throws IndexOutOfBoundsException if cmdline is "" 456 */ 457 public Process exec(String cmdline, String[] env) throws IOException 458 { 459 return exec(cmdline, env, null); 460 } 461 462 /** 463 * Create a new subprocess with the specified command line, environment, and 464 * working directory. If the environment is null, the process inherits the 465 * environment of this process. If the directory is null, the process uses 466 * the current working directory. This splits cmdline into an array, using 467 * the default StringTokenizer, then calls 468 * <code>exec(cmdArray, env, dir)</code>. A security check is performed, 469 * <code>checkExec</code>. 470 * 471 * @param cmdline the command to call 472 * @param env the environment to use, in the format name=value 473 * @param dir the working directory to use 474 * @return the Process object 475 * @throws SecurityException if permission is denied 476 * @throws IOException if an I/O error occurs 477 * @throws NullPointerException if cmdline is null, or env has null entries 478 * @throws IndexOutOfBoundsException if cmdline is "" 479 * @since 1.3 480 */ 481 public Process exec(String cmdline, String[] env, File dir) 482 throws IOException 483 { 484 StringTokenizer t = new StringTokenizer(cmdline); 485 String[] cmd = new String[t.countTokens()]; 486 for (int i = 0; i < cmd.length; i++) 487 cmd[i] = t.nextToken(); 488 return exec(cmd, env, dir); 489 } 490 491 /** 492 * Create a new subprocess with the specified command line, already 493 * tokenized. Calls <code>exec(cmd, null, null)</code>. A security check 494 * is performed, <code>checkExec</code>. 495 * 496 * @param cmd the command to call 497 * @return the Process object 498 * @throws SecurityException if permission is denied 499 * @throws IOException if an I/O error occurs 500 * @throws NullPointerException if cmd is null, or has null entries 501 * @throws IndexOutOfBoundsException if cmd is length 0 502 */ 503 public Process exec(String[] cmd) throws IOException 504 { 505 return exec(cmd, null, null); 506 } 507 508 /** 509 * Create a new subprocess with the specified command line, already 510 * tokenized, and specified environment. If the environment is null, the 511 * process inherits the environment of this process. Calls 512 * <code>exec(cmd, env, null)</code>. A security check is performed, 513 * <code>checkExec</code>. 514 * 515 * @param cmd the command to call 516 * @param env the environment to use, in the format name=value 517 * @return the Process object 518 * @throws SecurityException if permission is denied 519 * @throws IOException if an I/O error occurs 520 * @throws NullPointerException if cmd is null, or cmd or env has null 521 * entries 522 * @throws IndexOutOfBoundsException if cmd is length 0 523 */ 524 public Process exec(String[] cmd, String[] env) throws IOException 525 { 526 return exec(cmd, env, null); 527 } 528 529 /** 530 * Create a new subprocess with the specified command line, already 531 * tokenized, and the specified environment and working directory. If the 532 * environment is null, the process inherits the environment of this 533 * process. If the directory is null, the process uses the current working 534 * directory. A security check is performed, <code>checkExec</code>. 535 * 536 * @param cmd the command to call 537 * @param env the environment to use, in the format name=value 538 * @param dir the working directory to use 539 * @return the Process object 540 * @throws SecurityException if permission is denied 541 * @throws IOException if an I/O error occurs 542 * @throws NullPointerException if cmd is null, or cmd or env has null 543 * entries 544 * @throws IndexOutOfBoundsException if cmd is length 0 545 * @since 1.3 546 */ 547 public Process exec(String[] cmd, String[] env, File dir) 548 throws IOException 549 { 550 SecurityManager sm = SecurityManager.current; // Be thread-safe! 551 if (sm != null) 552 sm.checkExec(cmd[0]); 553 return VMRuntime.exec(cmd, env, dir); 554 } 555 556 /** 557 * Returns the number of available processors currently available to the 558 * virtual machine. This number may change over time; so a multi-processor 559 * program want to poll this to determine maximal resource usage. 560 * 561 * @return the number of processors available, at least 1 562 */ 563 public int availableProcessors() 564 { 565 return VMRuntime.availableProcessors(); 566 } 567 568 /** 569 * Find out how much memory is still free for allocating Objects on the heap. 570 * 571 * @return the number of bytes of free memory for more Objects 572 */ 573 public long freeMemory() 574 { 575 return VMRuntime.freeMemory(); 576 } 577 578 /** 579 * Find out how much memory total is available on the heap for allocating 580 * Objects. 581 * 582 * @return the total number of bytes of memory for Objects 583 */ 584 public long totalMemory() 585 { 586 return VMRuntime.totalMemory(); 587 } 588 589 /** 590 * Returns the maximum amount of memory the virtual machine can attempt to 591 * use. This may be <code>Long.MAX_VALUE</code> if there is no inherent 592 * limit (or if you really do have a 8 exabyte memory!). 593 * 594 * @return the maximum number of bytes the virtual machine will attempt 595 * to allocate 596 */ 597 public long maxMemory() 598 { 599 return VMRuntime.maxMemory(); 600 } 601 602 /** 603 * Run the garbage collector. This method is more of a suggestion than 604 * anything. All this method guarantees is that the garbage collector will 605 * have "done its best" by the time it returns. Notice that garbage 606 * collection takes place even without calling this method. 607 */ 608 public void gc() 609 { 610 VMRuntime.gc(); 611 } 612 613 /** 614 * Run finalization on all Objects that are waiting to be finalized. Again, 615 * a suggestion, though a stronger one than {@link #gc()}. This calls the 616 * <code>finalize</code> method of all objects waiting to be collected. 617 * 618 * @see #finalize() 619 */ 620 public void runFinalization() 621 { 622 VMRuntime.runFinalization(); 623 } 624 625 /** 626 * Tell the VM to trace every bytecode instruction that executes (print out 627 * a trace of it). No guarantees are made as to where it will be printed, 628 * and the VM is allowed to ignore this request. 629 * 630 * @param on whether to turn instruction tracing on 631 */ 632 public void traceInstructions(boolean on) 633 { 634 VMRuntime.traceInstructions(on); 635 } 636 637 /** 638 * Tell the VM to trace every method call that executes (print out a trace 639 * of it). No guarantees are made as to where it will be printed, and the 640 * VM is allowed to ignore this request. 641 * 642 * @param on whether to turn method tracing on 643 */ 644 public void traceMethodCalls(boolean on) 645 { 646 VMRuntime.traceMethodCalls(on); 647 } 648 649 /** 650 * Load a native library using the system-dependent filename. This is similar 651 * to loadLibrary, except the only name mangling done is inserting "_g" 652 * before the final ".so" if the VM was invoked by the name "java_g". There 653 * may be a security check, of <code>checkLink</code>. 654 * 655 * <p> 656 * The library is loaded using the class loader associated with the 657 * class associated with the invoking method. 658 * 659 * @param filename the file to load 660 * @throws SecurityException if permission is denied 661 * @throws UnsatisfiedLinkError if the library is not found 662 */ 663 public void load(String filename) 664 { 665 load(filename, VMStackWalker.getCallingClassLoader()); 666 } 667 668 /** 669 * Same as <code>load(String)</code> but using the given loader. 670 * 671 * @param filename the file to load 672 * @param loader class loader, or <code>null</code> for the boot loader 673 * @throws SecurityException if permission is denied 674 * @throws UnsatisfiedLinkError if the library is not found 675 */ 676 void load(String filename, ClassLoader loader) 677 { 678 SecurityManager sm = SecurityManager.current; // Be thread-safe! 679 if (sm != null) 680 sm.checkLink(filename); 681 if (loadLib(filename, loader) == 0) 682 throw new UnsatisfiedLinkError("Could not load library " + filename); 683 } 684 685 /** 686 * Do a security check on the filename and then load the native library. 687 * 688 * @param filename the file to load 689 * @param loader class loader, or <code>null</code> for the boot loader 690 * @return 0 on failure, nonzero on success 691 * @throws SecurityException if file read permission is denied 692 */ 693 private static int loadLib(String filename, ClassLoader loader) 694 { 695 SecurityManager sm = SecurityManager.current; // Be thread-safe! 696 if (sm != null) 697 sm.checkRead(filename); 698 return VMRuntime.nativeLoad(filename, loader); 699 } 700 701 /** 702 * Load a native library using a system-independent "short name" for the 703 * library. It will be transformed to a correct filename in a 704 * system-dependent manner (for example, in Windows, "mylib" will be turned 705 * into "mylib.dll"). This is done as follows: if the context that called 706 * load has a ClassLoader cl, then <code>cl.findLibrary(libpath)</code> is 707 * used to convert the name. If that result was null, or there was no class 708 * loader, this searches each directory of the system property 709 * <code>java.library.path</code> for a file named 710 * <code>System.mapLibraryName(libname)</code>. There may be a security 711 * check, of <code>checkLink</code>. 712 * 713 * <p>Note: Besides <code>java.library.path</code> a VM may chose to search 714 * for native libraries in a path that is specified by the 715 * <code>gnu.classpath.boot.library.path</code> system property. However 716 * this is for internal usage or development of GNU Classpath only. 717 * <b>A Java application must not load a non-system library by changing 718 * this property otherwise it will break compatibility.</b></p> 719 * 720 * <p> 721 * The library is loaded using the class loader associated with the 722 * class associated with the invoking method. 723 * 724 * @param libname the library to load 725 * 726 * @throws SecurityException if permission is denied 727 * @throws UnsatisfiedLinkError if the library is not found 728 * 729 * @see System#mapLibraryName(String) 730 * @see ClassLoader#findLibrary(String) 731 */ 732 public void loadLibrary(String libname) 733 { 734 loadLibrary(libname, VMStackWalker.getCallingClassLoader()); 735 } 736 737 /** 738 * Same as <code>loadLibrary(String)</code> but using the given loader. 739 * 740 * @param libname the library to load 741 * @param loader class loader, or <code>null</code> for the boot loader 742 * @throws SecurityException if permission is denied 743 * @throws UnsatisfiedLinkError if the library is not found 744 */ 745 void loadLibrary(String libname, ClassLoader loader) 746 { 747 SecurityManager sm = SecurityManager.current; // Be thread-safe! 748 if (sm != null) 749 sm.checkLink(libname); 750 String filename; 751 if (loader != null && (filename = loader.findLibrary(libname)) != null) 752 { 753 if (loadLib(filename, loader) != 0) 754 return; 755 } 756 else 757 { 758 filename = VMRuntime.mapLibraryName(libname); 759 for (int i = 0; i < libpath.length; i++) 760 if (loadLib(libpath[i] + filename, loader) != 0) 761 return; 762 } 763 throw new UnsatisfiedLinkError("Native library `" + libname 764 + "' not found (as file `" + filename + "') in gnu.classpath.boot.library.path and java.library.path"); 765 } 766 767 /** 768 * Return a localized version of this InputStream, meaning all characters 769 * are localized before they come out the other end. 770 * 771 * @param in the stream to localize 772 * @return the localized stream 773 * @deprecated <code>InputStreamReader</code> is the preferred way to read 774 * local encodings 775 * @XXX This implementation does not localize, yet. 776 */ 777 public InputStream getLocalizedInputStream(InputStream in) 778 { 779 return in; 780 } 781 782 /** 783 * Return a localized version of this OutputStream, meaning all characters 784 * are localized before they are sent to the other end. 785 * 786 * @param out the stream to localize 787 * @return the localized stream 788 * @deprecated <code>OutputStreamWriter</code> is the preferred way to write 789 * local encodings 790 * @XXX This implementation does not localize, yet. 791 */ 792 public OutputStream getLocalizedOutputStream(OutputStream out) 793 { 794 return out; 795 } 796} // class Runtime