GNU Classpath (0.95) | |
Frames | No Frames |
1: /* Runtime.java -- access to the VM process 2: Copyright (C) 1998, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 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: 39: package java.lang; 40: 41: import gnu.classpath.SystemProperties; 42: import gnu.classpath.VMStackWalker; 43: 44: import java.io.File; 45: import java.io.IOException; 46: import java.io.InputStream; 47: import java.io.OutputStream; 48: import java.util.HashSet; 49: import java.util.Iterator; 50: import java.util.Set; 51: import java.util.StringTokenizer; 52: 53: /** 54: * Runtime represents the Virtual Machine. 55: * 56: * @author John Keiser 57: * @author Eric Blake (ebb9@email.byu.edu) 58: * @author Jeroen Frijters 59: */ 60: // No idea why this class isn't final, since you can't build a subclass! 61: public class Runtime 62: { 63: /** 64: * The library path, to search when loading libraries. We can also safely use 65: * this as a lock for synchronization. 66: */ 67: private final String[] libpath; 68: 69: /** 70: * The thread that started the exit sequence. Access to this field must 71: * be thread-safe; lock on libpath to avoid deadlock with user code. 72: * <code>runFinalization()</code> may want to look at this to see if ALL 73: * finalizers should be run, because the virtual machine is about to halt. 74: */ 75: private Thread exitSequence; 76: 77: /** 78: * All shutdown hooks. This is initialized lazily, and set to null once all 79: * shutdown hooks have run. Access to this field must be thread-safe; lock 80: * on libpath to avoid deadlock with user code. 81: */ 82: private Set shutdownHooks; 83: 84: /** 85: * The one and only runtime instance. 86: */ 87: private static final Runtime current = new Runtime(); 88: 89: /** 90: * Not instantiable by a user, this should only create one instance. 91: */ 92: private Runtime() 93: { 94: if (current != null) 95: throw new InternalError("Attempt to recreate Runtime"); 96: 97: // If used by underlying VM this contains the directories where Classpath's own 98: // native libraries are located. 99: 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
GNU Classpath (0.95) |