Source for java.lang.System

   1: /* System.java -- useful methods to interface with the system
   2:    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
   3:    Free Software Foundation, Inc.
   4: 
   5: This file is part of GNU Classpath.
   6: 
   7: GNU Classpath is free software; you can redistribute it and/or modify
   8: it under the terms of the GNU General Public License as published by
   9: the Free Software Foundation; either version 2, or (at your option)
  10: any later version.
  11: 
  12: GNU Classpath is distributed in the hope that it will be useful, but
  13: WITHOUT ANY WARRANTY; without even the implied warranty of
  14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15: General Public License for more details.
  16: 
  17: You should have received a copy of the GNU General Public License
  18: along with GNU Classpath; see the file COPYING.  If not, write to the
  19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20: 02110-1301 USA.
  21: 
  22: Linking this library statically or dynamically with other modules is
  23: making a combined work based on this library.  Thus, the terms and
  24: conditions of the GNU General Public License cover the whole
  25: combination.
  26: 
  27: As a special exception, the copyright holders of this library give you
  28: permission to link this library with independent modules to produce an
  29: executable, regardless of the license terms of these independent
  30: modules, and to copy and distribute the resulting executable under
  31: terms of your choice, provided that you also meet, for each linked
  32: independent module, the terms and conditions of the license of that
  33: module.  An independent module is a module which is not derived from
  34: or based on this library.  If you modify this library, you may extend
  35: this exception to your version of the library, but you are not
  36: obligated to do so.  If you do not wish to do so, delete this
  37: exception statement from your version. */
  38: 
  39: 
  40: package java.lang;
  41: 
  42: import gnu.classpath.SystemProperties;
  43: import gnu.classpath.VMStackWalker;
  44: 
  45: import java.io.IOException;
  46: import java.io.InputStream;
  47: import java.io.PrintStream;
  48: import java.nio.channels.Channel;
  49: import java.nio.channels.spi.SelectorProvider;
  50: import java.util.AbstractCollection;
  51: import java.util.Collection;
  52: import java.util.Collections;
  53: import java.util.HashMap;
  54: import java.util.Iterator;
  55: import java.util.List;
  56: import java.util.Map;
  57: import java.util.Set;
  58: import java.util.Properties;
  59: import java.util.PropertyPermission;
  60: 
  61: /**
  62:  * System represents system-wide resources; things that represent the
  63:  * general environment.  As such, all methods are static.
  64:  *
  65:  * @author John Keiser
  66:  * @author Eric Blake (ebb9@email.byu.edu)
  67:  * @since 1.0
  68:  * @status still missing 1.4 functionality
  69:  */
  70: public final class System
  71: {
  72:   // WARNING: System is a CORE class in the bootstrap cycle. See the comments
  73:   // in vm/reference/java/lang/Runtime for implications of this fact.
  74: 
  75:   /**
  76:    * The standard InputStream. This is assigned at startup and starts its
  77:    * life perfectly valid. Although it is marked final, you can change it
  78:    * using {@link #setIn(InputStream)} through some hefty VM magic.
  79:    *
  80:    * <p>This corresponds to the C stdin and C++ cin variables, which
  81:    * typically input from the keyboard, but may be used to pipe input from
  82:    * other processes or files.  That should all be transparent to you,
  83:    * however.
  84:    */
  85:   public static final InputStream in = VMSystem.makeStandardInputStream();
  86: 
  87:   /**
  88:    * The standard output PrintStream.  This is assigned at startup and
  89:    * starts its life perfectly valid. Although it is marked final, you can
  90:    * change it using {@link #setOut(PrintStream)} through some hefty VM magic.
  91:    *
  92:    * <p>This corresponds to the C stdout and C++ cout variables, which
  93:    * typically output normal messages to the screen, but may be used to pipe
  94:    * output to other processes or files.  That should all be transparent to
  95:    * you, however.
  96:    */
  97:   public static final PrintStream out = VMSystem.makeStandardOutputStream();
  98: 
  99:   /**
 100:    * The standard output PrintStream.  This is assigned at startup and
 101:    * starts its life perfectly valid. Although it is marked final, you can
 102:    * change it using {@link #setErr(PrintStream)} through some hefty VM magic.
 103:    *
 104:    * <p>This corresponds to the C stderr and C++ cerr variables, which
 105:    * typically output error messages to the screen, but may be used to pipe
 106:    * output to other processes or files.  That should all be transparent to
 107:    * you, however.
 108:    */
 109:   public static final PrintStream err = VMSystem.makeStandardErrorStream();
 110: 
 111:   /**
 112:    * A cached copy of the environment variable map.
 113:    */
 114:   private static Map<String,String> environmentMap;
 115: 
 116:   /**
 117:    * This class is uninstantiable.
 118:    */
 119:   private System()
 120:   {
 121:   }
 122: 
 123:   /**
 124:    * Set {@link #in} to a new InputStream. This uses some VM magic to change
 125:    * a "final" variable, so naturally there is a security check,
 126:    * <code>RuntimePermission("setIO")</code>.
 127:    *
 128:    * @param in the new InputStream
 129:    * @throws SecurityException if permission is denied
 130:    * @since 1.1
 131:    */
 132:   public static void setIn(InputStream in)
 133:   {
 134:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 135:     if (sm != null)
 136:       sm.checkPermission(new RuntimePermission("setIO"));
 137:     
 138:     VMSystem.setIn(in);
 139:   }
 140: 
 141:   /**
 142:    * Set {@link #out} to a new PrintStream. This uses some VM magic to change
 143:    * a "final" variable, so naturally there is a security check,
 144:    * <code>RuntimePermission("setIO")</code>.
 145:    *
 146:    * @param out the new PrintStream
 147:    * @throws SecurityException if permission is denied
 148:    * @since 1.1
 149:    */
 150:   public static void setOut(PrintStream out)
 151:   {
 152:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 153:     if (sm != null)
 154:       sm.checkPermission(new RuntimePermission("setIO"));    
 155:     VMSystem.setOut(out);
 156:   }
 157: 
 158:   /**
 159:    * Set {@link #err} to a new PrintStream. This uses some VM magic to change
 160:    * a "final" variable, so naturally there is a security check,
 161:    * <code>RuntimePermission("setIO")</code>.
 162:    *
 163:    * @param err the new PrintStream
 164:    * @throws SecurityException if permission is denied
 165:    * @since 1.1
 166:    */
 167:   public static void setErr(PrintStream err)
 168:   {
 169:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 170:     if (sm != null)
 171:       sm.checkPermission(new RuntimePermission("setIO"));
 172:     VMSystem.setErr(err);
 173:   }
 174: 
 175:   /**
 176:    * Set the current SecurityManager. If a security manager already exists,
 177:    * then <code>RuntimePermission("setSecurityManager")</code> is checked
 178:    * first. Since this permission is denied by the default security manager,
 179:    * setting the security manager is often an irreversible action.
 180:    *
 181:    * <STRONG>Spec Note:</STRONG> Don't ask me, I didn't write it.  It looks
 182:    * pretty vulnerable; whoever gets to the gate first gets to set the policy.
 183:    * There is probably some way to set the original security manager as a
 184:    * command line argument to the VM, but I don't know it.
 185:    *
 186:    * @param sm the new SecurityManager
 187:    * @throws SecurityException if permission is denied
 188:    */
 189:   public static synchronized void setSecurityManager(SecurityManager sm)
 190:   {
 191:     // Implementation note: the field lives in SecurityManager because of
 192:     // bootstrap initialization issues. This method is synchronized so that
 193:     // no other thread changes it to null before this thread makes the change.
 194:     if (SecurityManager.current != null)
 195:       SecurityManager.current.checkPermission
 196:         (new RuntimePermission("setSecurityManager"));
 197: 
 198:     // java.security.Security's class initialiser loads and parses the
 199:     // policy files.  If it hasn't been run already it will be run
 200:     // during the first permission check.  That initialisation will
 201:     // fail if a very restrictive security manager is in force, so we
 202:     // preload it here.
 203:     if (SecurityManager.current == null)
 204:       {
 205:     try
 206:       {
 207:         Class.forName("java.security.Security");
 208:       }
 209:     catch (ClassNotFoundException e)
 210:       {
 211:       }
 212:       }
 213:     
 214:     SecurityManager.current = sm;
 215:   }
 216: 
 217:   /**
 218:    * Get the current SecurityManager. If the SecurityManager has not been
 219:    * set yet, then this method returns null.
 220:    *
 221:    * @return the current SecurityManager, or null
 222:    */
 223:   public static SecurityManager getSecurityManager()
 224:   {
 225:     return SecurityManager.current;
 226:   }
 227: 
 228:   /**
 229:    * Get the current time, measured in the number of milliseconds from the
 230:    * beginning of Jan. 1, 1970. This is gathered from the system clock, with
 231:    * any attendant incorrectness (it may be timezone dependent).
 232:    *
 233:    * @return the current time
 234:    * @see java.util.Date
 235:    */
 236:   public static long currentTimeMillis()
 237:   {
 238:     return VMSystem.currentTimeMillis();
 239:   }
 240:   
 241:   /** 
 242:    * <p>
 243:    * Returns the current value of a nanosecond-precise system timer.
 244:    * The value of the timer is an offset relative to some arbitrary fixed
 245:    * time, which may be in the future (making the value negative).  This
 246:    * method is useful for timing events where nanosecond precision is
 247:    * required.  This is achieved by calling this method before and after the
 248:    * event, and taking the difference betweent the two times:
 249:    * </p>
 250:    * <p>
 251:    * <code>long startTime = System.nanoTime();</code><br />
 252:    * <code>... <emph>event code</emph> ...</code><br />
 253:    * <code>long endTime = System.nanoTime();</code><br />
 254:    * <code>long duration = endTime - startTime;</code><br />
 255:    * </p>
 256:    * <p>
 257:    * Note that the value is only nanosecond-precise, and not accurate; there
 258:    * is no guarantee that the difference between two values is really a
 259:    * nanosecond.  Also, the value is prone to overflow if the offset
 260:    * exceeds 2^63.
 261:    * </p>
 262:    *
 263:    * @return the time of a system timer in nanoseconds.
 264:    * @since 1.5 
 265:    */
 266:   public static long nanoTime()
 267:   {
 268:     return VMSystem.nanoTime();
 269:   }
 270: 
 271:   /**
 272:    * Copy one array onto another from <code>src[srcStart]</code> ...
 273:    * <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ...
 274:    * <code>dest[destStart+len-1]</code>. First, the arguments are validated:
 275:    * neither array may be null, they must be of compatible types, and the
 276:    * start and length must fit within both arrays. Then the copying starts,
 277:    * and proceeds through increasing slots.  If src and dest are the same
 278:    * array, this will appear to copy the data to a temporary location first.
 279:    * An ArrayStoreException in the middle of copying will leave earlier
 280:    * elements copied, but later elements unchanged.
 281:    *
 282:    * @param src the array to copy elements from
 283:    * @param srcStart the starting position in src
 284:    * @param dest the array to copy elements to
 285:    * @param destStart the starting position in dest
 286:    * @param len the number of elements to copy
 287:    * @throws NullPointerException if src or dest is null
 288:    * @throws ArrayStoreException if src or dest is not an array, if they are
 289:    *         not compatible array types, or if an incompatible runtime type
 290:    *         is stored in dest
 291:    * @throws IndexOutOfBoundsException if len is negative, or if the start or
 292:    *         end copy position in either array is out of bounds
 293:    */
 294:   public static void arraycopy(Object src, int srcStart,
 295:                                Object dest, int destStart, int len)
 296:   {
 297:     VMSystem.arraycopy(src, srcStart, dest, destStart, len);
 298:   }
 299: 
 300:   /**
 301:    * Get a hash code computed by the VM for the Object. This hash code will
 302:    * be the same as Object's hashCode() method.  It is usually some
 303:    * convolution of the pointer to the Object internal to the VM.  It
 304:    * follows standard hash code rules, in that it will remain the same for a
 305:    * given Object for the lifetime of that Object.
 306:    *
 307:    * @param o the Object to get the hash code for
 308:    * @return the VM-dependent hash code for this Object
 309:    * @since 1.1
 310:    */
 311:   public static int identityHashCode(Object o)
 312:   {
 313:     return VMSystem.identityHashCode(o);
 314:   }
 315: 
 316:   /**
 317:    * Get all the system properties at once. A security check may be performed,
 318:    * <code>checkPropertiesAccess</code>. Note that a security manager may
 319:    * allow getting a single property, but not the entire group.
 320:    *
 321:    * <p>The required properties include:
 322:    * <dl>
 323:    * <dt>java.version</dt>         <dd>Java version number</dd>
 324:    * <dt>java.vendor</dt>          <dd>Java vendor specific string</dd>
 325:    * <dt>java.vendor.url</dt>      <dd>Java vendor URL</dd>
 326:    * <dt>java.home</dt>            <dd>Java installation directory</dd>
 327:    * <dt>java.vm.specification.version</dt> <dd>VM Spec version</dd>
 328:    * <dt>java.vm.specification.vendor</dt>  <dd>VM Spec vendor</dd>
 329:    * <dt>java.vm.specification.name</dt>    <dd>VM Spec name</dd>
 330:    * <dt>java.vm.version</dt>      <dd>VM implementation version</dd>
 331:    * <dt>java.vm.vendor</dt>       <dd>VM implementation vendor</dd>
 332:    * <dt>java.vm.name</dt>         <dd>VM implementation name</dd>
 333:    * <dt>java.specification.version</dt>    <dd>Java Runtime Environment version</dd>
 334:    * <dt>java.specification.vendor</dt>     <dd>Java Runtime Environment vendor</dd>
 335:    * <dt>java.specification.name</dt>       <dd>Java Runtime Environment name</dd>
 336:    * <dt>java.class.version</dt>   <dd>Java class version number</dd>
 337:    * <dt>java.class.path</dt>      <dd>Java classpath</dd>
 338:    * <dt>java.library.path</dt>    <dd>Path for finding Java libraries</dd>
 339:    * <dt>java.io.tmpdir</dt>       <dd>Default temp file path</dd>
 340:    * <dt>java.compiler</dt>        <dd>Name of JIT to use</dd>
 341:    * <dt>java.ext.dirs</dt>        <dd>Java extension path</dd>
 342:    * <dt>os.name</dt>              <dd>Operating System Name</dd>
 343:    * <dt>os.arch</dt>              <dd>Operating System Architecture</dd>
 344:    * <dt>os.version</dt>           <dd>Operating System Version</dd>
 345:    * <dt>file.separator</dt>       <dd>File separator ("/" on Unix)</dd>
 346:    * <dt>path.separator</dt>       <dd>Path separator (":" on Unix)</dd>
 347:    * <dt>line.separator</dt>       <dd>Line separator ("\n" on Unix)</dd>
 348:    * <dt>user.name</dt>            <dd>User account name</dd>
 349:    * <dt>user.home</dt>            <dd>User home directory</dd>
 350:    * <dt>user.dir</dt>             <dd>User's current working directory</dd>
 351:    * </dl>
 352:    *
 353:    * In addition, gnu defines several other properties, where ? stands for
 354:    * each character in '0' through '9':
 355:    * <dl>
 356:    * <dt>gnu.classpath.home</dt>         <dd>Path to the classpath libraries.</dd>
 357:    * <dt>gnu.classpath.version</dt>      <dd>Version of the classpath libraries.</dd>
 358:    * <dt>gnu.classpath.vm.shortname</dt> <dd>Succinct version of the VM name;
 359:    *     used for finding property files in file system</dd>
 360:    * <dt>gnu.classpath.home.url</dt>     <dd> Base URL; used for finding
 361:    *     property files in file system</dd>
 362:    * <dt>gnu.cpu.endian</dt>             <dd>big or little</dd>
 363:    * <dt>gnu.java.io.encoding_scheme_alias.iso-8859-?</dt>   <dd>8859_?</dd>
 364:    * <dt>gnu.java.io.encoding_scheme_alias.iso8859_?</dt>    <dd>8859_?</dd>
 365:    * <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
 366:    * <dt>gnu.java.io.encoding_scheme_alias.latin?</dt>       <dd>8859_?</dd>
 367:    * <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt>        <dd>UTF8</dd>
 368:    * <dt>gnu.java.util.zoneinfo.dir</dt>    <dd>Root of zoneinfo tree</dd>
 369:    * <dt>gnu.javax.print.server</dt>     <dd>Hostname of external CUPS server.</dd>
 370:    * </dl>
 371:    *
 372:    * @return the system properties, will never be null
 373:    * @throws SecurityException if permission is denied
 374:    */
 375:   public static Properties getProperties()
 376:   {
 377:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 378:     if (sm != null)
 379:       sm.checkPropertiesAccess();
 380:     return SystemProperties.getProperties();
 381:   }
 382: 
 383:   /**
 384:    * Set all the system properties at once. A security check may be performed,
 385:    * <code>checkPropertiesAccess</code>. Note that a security manager may
 386:    * allow setting a single property, but not the entire group. An argument
 387:    * of null resets the properties to the startup default.
 388:    *
 389:    * @param properties the new set of system properties
 390:    * @throws SecurityException if permission is denied
 391:    */
 392:   public static void setProperties(Properties properties)
 393:   {
 394:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 395:     if (sm != null)
 396:       sm.checkPropertiesAccess();
 397:     SystemProperties.setProperties(properties);
 398:   }
 399: 
 400:   /**
 401:    * Get a single system property by name. A security check may be performed,
 402:    * <code>checkPropertyAccess(key)</code>.
 403:    *
 404:    * @param key the name of the system property to get
 405:    * @return the property, or null if not found
 406:    * @throws SecurityException if permission is denied
 407:    * @throws NullPointerException if key is null
 408:    * @throws IllegalArgumentException if key is ""
 409:    */
 410:   public static String getProperty(String key)
 411:   {
 412:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 413:     if (sm != null)
 414:       sm.checkPropertyAccess(key);
 415:     if (key.length() == 0)
 416:       throw new IllegalArgumentException("key can't be empty");
 417:     return SystemProperties.getProperty(key);
 418:   }
 419: 
 420:   /**
 421:    * Get a single system property by name. A security check may be performed,
 422:    * <code>checkPropertyAccess(key)</code>.
 423:    *
 424:    * @param key the name of the system property to get
 425:    * @param def the default
 426:    * @return the property, or def if not found
 427:    * @throws SecurityException if permission is denied
 428:    * @throws NullPointerException if key is null
 429:    * @throws IllegalArgumentException if key is ""
 430:    */
 431:   public static String getProperty(String key, String def)
 432:   {
 433:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 434:     if (sm != null)
 435:       sm.checkPropertyAccess(key);
 436:     // This handles both the null pointer exception and the illegal
 437:     // argument exception.
 438:     if (key.length() == 0)
 439:       throw new IllegalArgumentException("key can't be empty");
 440:     return SystemProperties.getProperty(key, def);
 441:   }
 442: 
 443:   /**
 444:    * Set a single system property by name. A security check may be performed,
 445:    * <code>checkPropertyAccess(key, "write")</code>.
 446:    *
 447:    * @param key the name of the system property to set
 448:    * @param value the new value
 449:    * @return the previous value, or null
 450:    * @throws SecurityException if permission is denied
 451:    * @throws NullPointerException if key is null
 452:    * @throws IllegalArgumentException if key is ""
 453:    * @since 1.2
 454:    */
 455:   public static String setProperty(String key, String value)
 456:   {
 457:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 458:     if (sm != null)
 459:       sm.checkPermission(new PropertyPermission(key, "write"));
 460:     // This handles both the null pointer exception and the illegal
 461:     // argument exception.
 462:     if (key.length() == 0)
 463:       throw new IllegalArgumentException("key can't be empty");
 464:     return SystemProperties.setProperty(key, value);
 465:   }
 466: 
 467:   /**
 468:    * Remove a single system property by name. A security check may be
 469:    * performed, <code>checkPropertyAccess(key, "write")</code>.
 470:    *
 471:    * @param key the name of the system property to remove
 472:    * @return the previous value, or null
 473:    * @throws SecurityException if permission is denied
 474:    * @throws NullPointerException if key is null
 475:    * @throws IllegalArgumentException if key is ""
 476:    * @since 1.5
 477:    */
 478:   public static String clearProperty(String key)
 479:   {
 480:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 481:     if (sm != null)
 482:       sm.checkPermission(new PropertyPermission(key, "write"));
 483:     // This handles both the null pointer exception and the illegal
 484:     // argument exception.
 485:     if (key.length() == 0)
 486:       throw new IllegalArgumentException("key can't be empty");
 487:     return SystemProperties.remove(key);
 488:   }
 489: 
 490:   /**
 491:    * Gets the value of an environment variable.
 492:    *
 493:    * @param name the name of the environment variable
 494:    * @return the string value of the variable or null when the
 495:    *         environment variable is not defined.
 496:    * @throws NullPointerException
 497:    * @throws SecurityException if permission is denied
 498:    * @since 1.5
 499:    * @specnote This method was deprecated in some JDK releases, but
 500:    *           was restored in 1.5.
 501:    */
 502:   public static String getenv(String name)
 503:   {
 504:     if (name == null)
 505:       throw new NullPointerException();
 506:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 507:     if (sm != null)
 508:       sm.checkPermission(new RuntimePermission("getenv." + name));
 509:     return VMSystem.getenv(name);
 510:   }
 511: 
 512:   /**
 513:    * <p>
 514:    * Returns an unmodifiable view of the system environment variables.
 515:    * If the underlying system does not support environment variables,
 516:    * an empty map is returned.
 517:    * </p>
 518:    * <p>
 519:    * The returned map is read-only and does not accept queries using
 520:    * null keys or values, or those of a type other than <code>String</code>.
 521:    * Attempts to modify the map will throw an
 522:    * <code>UnsupportedOperationException</code>, while attempts
 523:    * to pass in a null value will throw a
 524:    * <code>NullPointerException</code>.  Types other than <code>String</code>
 525:    * throw a <code>ClassCastException</code>.
 526:    * </p>
 527:    * <p>
 528:    * As the returned map is generated using data from the underlying
 529:    * platform, it may not comply with the <code>equals()</code>
 530:    * and <code>hashCode()</code> contracts.  It is also likely that
 531:    * the keys of this map will be case-sensitive.
 532:    * </p>
 533:    * <p>
 534:    * Use of this method may require a security check for the
 535:    * RuntimePermission "getenv.*".
 536:    * </p>
 537:    *
 538:    * @return a map of the system environment variables.
 539:    * @throws SecurityException if the checkPermission method of
 540:    *         an installed security manager prevents access to
 541:    *         the system environment variables.
 542:    * @since 1.5
 543:    */
 544:   public static Map<String, String> getenv()
 545:   {
 546:     SecurityManager sm = SecurityManager.current; // Be thread-safe.
 547:     if (sm != null)
 548:       sm.checkPermission(new RuntimePermission("getenv.*"));
 549: 
 550:     if (environmentMap == null)
 551:       {
 552:     Map<String,String> variables = new EnvironmentMap();
 553:         List<String> environ = (List<String>)VMSystem.environ();
 554:         for (String envEntry : environ)
 555:           {
 556:             // avoid broken and null entries
 557:             if (envEntry != null && !envEntry.endsWith("="))
 558:               {
 559:                 // it's perfectly legal that some entries may be in the form
 560:                 // key=value=value=value
 561:                 int equalSignIndex = envEntry.indexOf('=');            
 562:                 String key = envEntry.substring(0, equalSignIndex);
 563:                 String value = envEntry.substring(equalSignIndex + 1);
 564:                 variables.put(key, value);
 565:               }
 566:           }
 567:         
 568:         environmentMap = Collections.unmodifiableMap(variables);
 569:       }
 570:     
 571:     return environmentMap;
 572:   }
 573: 
 574:   /**
 575:    * Terminate the Virtual Machine. This just calls
 576:    * <code>Runtime.getRuntime().exit(status)</code>, and never returns.
 577:    * Obviously, a security check is in order, <code>checkExit</code>.
 578:    *
 579:    * @param status the exit status; by convention non-zero is abnormal
 580:    * @throws SecurityException if permission is denied
 581:    * @see Runtime#exit(int)
 582:    */
 583:   public static void exit(int status)
 584:   {
 585:     Runtime.getRuntime().exit(status);
 586:   }
 587: 
 588:   /**
 589:    * Calls the garbage collector. This is only a hint, and it is up to the
 590:    * implementation what this hint suggests, but it usually causes a
 591:    * best-effort attempt to reclaim unused memory from discarded objects.
 592:    * This calls <code>Runtime.getRuntime().gc()</code>.
 593:    *
 594:    * @see Runtime#gc()
 595:    */
 596:   public static void gc()
 597:   {
 598:     Runtime.getRuntime().gc();
 599:   }
 600: 
 601:   /**
 602:    * Runs object finalization on pending objects. This is only a hint, and
 603:    * it is up to the implementation what this hint suggests, but it usually
 604:    * causes a best-effort attempt to run finalizers on all objects ready
 605:    * to be reclaimed. This calls
 606:    * <code>Runtime.getRuntime().runFinalization()</code>.
 607:    *
 608:    * @see Runtime#runFinalization()
 609:    */
 610:   public static void runFinalization()
 611:   {
 612:     Runtime.getRuntime().runFinalization();
 613:   }
 614: 
 615:   /**
 616:    * Tell the Runtime whether to run finalization before exiting the
 617:    * JVM.  This is inherently unsafe in multi-threaded applications,
 618:    * since it can force initialization on objects which are still in use
 619:    * by live threads, leading to deadlock; therefore this is disabled by
 620:    * default. There may be a security check, <code>checkExit(0)</code>. This
 621:    * calls <code>Runtime.runFinalizersOnExit()</code>.
 622:    *
 623:    * @param finalizeOnExit whether to run finalizers on exit
 624:    * @throws SecurityException if permission is denied
 625:    * @see Runtime#runFinalizersOnExit(boolean)
 626:    * @since 1.1
 627:    * @deprecated never rely on finalizers to do a clean, thread-safe,
 628:    *             mop-up from your code
 629:    */
 630:   public static void runFinalizersOnExit(boolean finalizeOnExit)
 631:   {
 632:     Runtime.runFinalizersOnExit(finalizeOnExit);
 633:   }
 634: 
 635:   /**
 636:    * Load a code file using its explicit system-dependent filename. A security
 637:    * check may be performed, <code>checkLink</code>. This just calls
 638:    * <code>Runtime.getRuntime().load(filename)</code>.
 639:    *
 640:    * <p>
 641:    * The library is loaded using the class loader associated with the
 642:    * class associated with the invoking method.
 643:    *
 644:    * @param filename the code file to load
 645:    * @throws SecurityException if permission is denied
 646:    * @throws UnsatisfiedLinkError if the file cannot be loaded
 647:    * @see Runtime#load(String)
 648:    */
 649:   public static void load(String filename)
 650:   {
 651:     Runtime.getRuntime().load(filename, VMStackWalker.getCallingClassLoader());
 652:   }
 653: 
 654:   /**
 655:    * Load a library using its explicit system-dependent filename. A security
 656:    * check may be performed, <code>checkLink</code>. This just calls
 657:    * <code>Runtime.getRuntime().load(filename)</code>.
 658:    *
 659:    * <p>
 660:    * The library is loaded using the class loader associated with the
 661:    * class associated with the invoking method.
 662:    *
 663:    * @param libname the library file to load
 664:    * @throws SecurityException if permission is denied
 665:    * @throws UnsatisfiedLinkError if the file cannot be loaded
 666:    * @see Runtime#load(String)
 667:    */
 668:   public static void loadLibrary(String libname)
 669:   {
 670:     Runtime.getRuntime().loadLibrary(libname,
 671:       VMStackWalker.getCallingClassLoader());
 672:   }
 673: 
 674:   /**
 675:    * Convert a library name to its platform-specific variant.
 676:    *
 677:    * @param libname the library name, as used in <code>loadLibrary</code>
 678:    * @return the platform-specific mangling of the name
 679:    * @since 1.2
 680:    */
 681:   public static String mapLibraryName(String libname)
 682:   {
 683:     return VMRuntime.mapLibraryName(libname);
 684:   }
 685: 
 686:   /**
 687:    * Returns the inherited channel of the VM.
 688:    *
 689:    * This wraps the inheritedChannel() call of the system's default
 690:    * {@link SelectorProvider}.
 691:    *
 692:    * @return the inherited channel of the VM
 693:    *
 694:    * @throws IOException If an I/O error occurs
 695:    * @throws SecurityException If an installed security manager denies access
 696:    *         to RuntimePermission("inheritedChannel")
 697:    *
 698:    * @since 1.5
 699:    */
 700:   public static Channel inheritedChannel()
 701:     throws IOException
 702:   {
 703:     return SelectorProvider.provider().inheritedChannel();
 704:   }
 705: 
 706:   /**
 707:    * This is a specialised <code>Collection</code>, providing
 708:    * the necessary provisions for the collections used by the
 709:    * environment variable map.  Namely, it prevents
 710:    * querying anything but <code>String</code>s.
 711:    *
 712:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 713:    */
 714:   private static class EnvironmentCollection
 715:     extends AbstractCollection<String>
 716:   {
 717: 
 718:     /**
 719:      * The wrapped collection.
 720:      */
 721:     protected Collection<String> c;
 722: 
 723:     /**
 724:      * Constructs a new environment collection, which
 725:      * wraps the elements of the supplied collection.
 726:      *
 727:      * @param coll the collection to use as a base for
 728:      *             this collection.
 729:      */
 730:     public EnvironmentCollection(Collection<String> coll)
 731:     {
 732:       c = coll;
 733:     }
 734:         
 735:     /**
 736:      * Blocks queries containing a null object or an object which
 737:      * isn't of type <code>String</code>.  All other queries
 738:      * are forwarded to the underlying collection.
 739:      *
 740:      * @param obj the object to look for.
 741:      * @return true if the object exists in the collection.
 742:      * @throws NullPointerException if the specified object is null.
 743:      * @throws ClassCastException if the specified object is not a String.
 744:      */
 745:     public boolean contains(Object obj)
 746:     {
 747:       if (obj == null)
 748:       throw new
 749:         NullPointerException("This collection does not support " +
 750:                  "null values.");
 751:       if (!(obj instanceof String))
 752:       throw new
 753:         ClassCastException("This collection only supports Strings.");
 754:       return c.contains(obj);
 755:     }
 756:     
 757:     /**
 758:      * Blocks queries where the collection contains a null object or
 759:      * an object which isn't of type <code>String</code>.  All other
 760:      * queries are forwarded to the underlying collection.
 761:      *
 762:      * @param coll the collection of objects to look for.
 763:      * @return true if the collection contains all elements in the collection.
 764:      * @throws NullPointerException if the collection is null.
 765:      * @throws NullPointerException if any collection entry is null.
 766:      * @throws ClassCastException if any collection entry is not a String.
 767:      */
 768:     public boolean containsAll(Collection<?> coll)
 769:     {
 770:       for (Object o: coll)
 771:     {
 772:       if (o == null)
 773:           throw new
 774:         NullPointerException("This collection does not support " +
 775:                      "null values.");
 776:       if (!(o instanceof String))
 777:           throw new
 778:         ClassCastException("This collection only supports Strings.");
 779:     }
 780:       return c.containsAll(coll);
 781:     }
 782: 
 783:     /**
 784:      * This returns an iterator over the map elements, with the
 785:      * same provisions as for the collection and underlying map.
 786:      *
 787:      * @return an iterator over the map elements.
 788:      */
 789:     public Iterator<String> iterator()
 790:     {
 791:       return c.iterator();
 792:     }
 793:     
 794:     /**
 795:      * Blocks the removal of elements from the collection.
 796:      *
 797:      * @return true if the removal was sucessful.
 798:      * @throws NullPointerException if the collection is null.
 799:      * @throws NullPointerException if any collection entry is null.
 800:      * @throws ClassCastException if any collection entry is not a String.
 801:      */
 802:     public boolean remove(Object key)
 803:     {
 804:       if (key == null)
 805:       throw new
 806:         NullPointerException("This collection does not support " +
 807:                  "null values.");
 808:       if (!(key instanceof String))
 809:       throw new
 810:         ClassCastException("This collection only supports Strings.");
 811:       return c.contains(key);
 812:     }    
 813:         
 814:     /**
 815:      * Blocks the removal of all elements in the specified
 816:      * collection from the collection.
 817:      *
 818:      * @param coll the collection of elements to remove.
 819:      * @return true if the elements were removed.
 820:      * @throws NullPointerException if the collection is null.
 821:      * @throws NullPointerException if any collection entry is null.
 822:      * @throws ClassCastException if any collection entry is not a String.
 823:      */
 824:     public boolean removeAll(Collection<?> coll)
 825:     {
 826:       for (Object o: coll)
 827:     {
 828:       if (o == null)
 829:           throw new
 830:         NullPointerException("This collection does not support " +
 831:                      "null values.");
 832:       if (!(o instanceof String))
 833:         throw new
 834:           ClassCastException("This collection only supports Strings.");
 835:     }
 836:       return c.removeAll(coll);
 837:     }
 838:     
 839:     /**
 840:      * Blocks the retention of all elements in the specified
 841:      * collection from the collection.
 842:      *
 843:      * @param coll the collection of elements to retain.
 844:      * @return true if the other elements were removed.
 845:      * @throws NullPointerException if the collection is null.
 846:      * @throws NullPointerException if any collection entry is null.
 847:      * @throws ClassCastException if any collection entry is not a String.
 848:      */
 849:     public boolean retainAll(Collection<?> coll)
 850:     {
 851:       for (Object o: coll)
 852:     {
 853:       if (o == null)
 854:           throw new
 855:         NullPointerException("This collection does not support " +
 856:                      "null values.");
 857:       if (!(o instanceof String))
 858:         throw new
 859:           ClassCastException("This collection only supports Strings.");
 860:     }
 861:       return c.containsAll(coll);
 862:     }
 863: 
 864:     /**
 865:      * This simply calls the same method on the wrapped
 866:      * collection.
 867:      *
 868:      * @return the size of the underlying collection.
 869:      */
 870:     public int size()
 871:     {
 872:       return c.size();
 873:     }
 874: 
 875:   } // class EnvironmentCollection<String>
 876: 
 877:   /**
 878:    * This is a specialised <code>HashMap</code>, which
 879:    * prevents the addition or querying of anything other than
 880:    * <code>String</code> objects. 
 881:    *
 882:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 883:    */
 884:   static class EnvironmentMap
 885:     extends HashMap<String,String>
 886:   {
 887:     
 888:     /**
 889:      * Cache the entry set.
 890:      */
 891:     private transient Set<Map.Entry<String,String>> entries;
 892: 
 893:     /**
 894:      * Cache the key set.
 895:      */
 896:     private transient Set<String> keys;
 897: 
 898:     /**
 899:      * Cache the value collection.
 900:      */
 901:     private transient Collection<String> values;
 902: 
 903:     /**
 904:      * Constructs a new empty <code>EnvironmentMap</code>.
 905:      */
 906:     EnvironmentMap()
 907:     {
 908:       super();
 909:     }
 910: 
 911:     /**
 912:      * Constructs a new <code>EnvironmentMap</code> containing
 913:      * the contents of the specified map.
 914:      *
 915:      * @param m the map to be added to this.
 916:      * @throws NullPointerException if a key or value is null.
 917:      * @throws ClassCastException if a key or value is not a String.
 918:      */    
 919:     EnvironmentMap(Map<String,String> m)
 920:     {
 921:       super(m);
 922:     }
 923: 
 924:     /**
 925:      * Blocks queries containing a null key or one which is not
 926:      * of type <code>String</code>.  All other queries
 927:      * are forwarded to the superclass.
 928:      *
 929:      * @param key the key to look for in the map.
 930:      * @return true if the key exists in the map.
 931:      * @throws NullPointerException if the specified key is null.
 932:      */
 933:     public boolean containsKey(Object key)
 934:     {
 935:       if (key == null)
 936:     throw new
 937:       NullPointerException("This map does not support null keys.");
 938:       if (!(key instanceof String))
 939:     throw new
 940:       ClassCastException("This map only allows queries using Strings.");
 941:       return super.containsKey(key);
 942:     }
 943:     
 944:     /**
 945:      * Blocks queries using a null or non-<code>String</code> value.
 946:      * All other queries are forwarded to the superclass.
 947:      *
 948:      * @param value the value to look for in the map.
 949:      * @return true if the value exists in the map.
 950:      * @throws NullPointerException if the specified value is null.
 951:      */
 952:     public boolean containsValue(Object value)
 953:     {
 954:       if (value == null)
 955:       throw new
 956:         NullPointerException("This map does not support null values.");
 957:       if (!(value instanceof String))
 958:     throw new
 959:       ClassCastException("This map only allows queries using Strings.");
 960:       return super.containsValue(value);
 961:     }
 962: 
 963:     /**
 964:      * Returns a set view of the map entries, with the same
 965:      * provisions as for the underlying map.
 966:      *
 967:      * @return a set containing the map entries.
 968:      */
 969:     public Set<Map.Entry<String,String>> entrySet()
 970:     {
 971:       if (entries == null)
 972:         entries = super.entrySet();
 973:       return entries;
 974:     }
 975: 
 976:     /**
 977:      * Blocks queries containing a null or non-<code>String</code> key.
 978:      * All other queries are passed on to the superclass.
 979:      *
 980:      * @param key the key to retrieve the value for.
 981:      * @return the value associated with the given key.
 982:      * @throws NullPointerException if the specified key is null.
 983:      * @throws ClassCastException if the specified key is not a String.
 984:      */
 985:     public String get(Object key)
 986:     {
 987:       if (key == null)
 988:     throw new
 989:       NullPointerException("This map does not support null keys.");
 990:       if (!(key instanceof String))
 991:     throw new
 992:       ClassCastException("This map only allows queries using Strings.");
 993:       return super.get(key);
 994:     }
 995:     
 996:     /**
 997:      * Returns a set view of the keys, with the same
 998:      * provisions as for the underlying map.
 999:      *
1000:      * @return a set containing the keys.
1001:      */
1002:     public Set<String> keySet()
1003:     {
1004:       if (keys == null)
1005:         keys = new EnvironmentSet(super.keySet());
1006:       return keys;
1007:     }
1008: 
1009:     /**
1010:      * Associates the given key to the given value. If the
1011:      * map already contains the key, its value is replaced.
1012:      * The map does not accept null keys or values, or keys
1013:      * and values not of type {@link String}.
1014:      *
1015:      * @param key the key to map.
1016:      * @param value the value to be mapped.
1017:      * @return the previous value of the key, or null if there was no mapping
1018:      * @throws NullPointerException if a key or value is null.
1019:      * @throws ClassCastException if a key or value is not a String.
1020:      */
1021:     public String put(String key, String value)
1022:     {
1023:       if (key == null)
1024:     throw new NullPointerException("A new key is null.");
1025:       if (value == null)
1026:     throw new NullPointerException("A new value is null.");
1027:       if (!(key instanceof String))
1028:     throw new ClassCastException("A new key is not a String.");
1029:       if (!(value instanceof String))
1030:     throw new ClassCastException("A new value is not a String.");
1031:       return super.put(key, value);
1032:     }
1033: 
1034:     /**
1035:      * Removes a key-value pair from the map.  The queried key may not
1036:      * be null or of a type other than a <code>String</code>.
1037:      *
1038:      * @param key the key of the entry to remove.
1039:      * @return the removed value.
1040:      * @throws NullPointerException if the specified key is null.
1041:      * @throws ClassCastException if the specified key is not a String.
1042:      */
1043:     public String remove(Object key)
1044:     {
1045:       if (key == null)
1046:     throw new
1047:       NullPointerException("This map does not support null keys.");
1048:       if (!(key instanceof String))
1049:     throw new
1050:       ClassCastException("This map only allows queries using Strings.");
1051:       return super.remove(key);
1052:     }
1053:     
1054:     /**
1055:      * Returns a collection view of the values, with the same
1056:      * provisions as for the underlying map.
1057:      *
1058:      * @return a collection containing the values.
1059:      */
1060:     public Collection<String> values()
1061:     {
1062:       if (values == null)
1063:         values = new EnvironmentCollection(super.values());
1064:       return values;
1065:     }
1066:     
1067:   }
1068: 
1069:   /**
1070:    * This is a specialised <code>Set</code>, providing
1071:    * the necessary provisions for the collections used by the
1072:    * environment variable map.  Namely, it prevents
1073:    * modifications and the use of queries with null
1074:    * or non-<code>String</code> values.
1075:    *
1076:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1077:    */
1078:   private static class EnvironmentSet
1079:     extends EnvironmentCollection
1080:     implements Set<String>
1081:   {
1082: 
1083:     /**
1084:      * Constructs a new environment set, which
1085:      * wraps the elements of the supplied set.
1086:      *
1087:      * @param set the set to use as a base for
1088:      *             this set.
1089:      */
1090:     public EnvironmentSet(Set<String> set)
1091:     {
1092:       super(set);
1093:     }
1094: 
1095:     /**
1096:      * This simply calls the same method on the wrapped
1097:      * collection.
1098:      *
1099:      * @param obj the object to compare with.
1100:      * @return true if the two objects are equal.
1101:      */
1102:     public boolean equals(Object obj)
1103:     {
1104:       return c.equals(obj);
1105:     }
1106: 
1107:     /**
1108:      * This simply calls the same method on the wrapped
1109:      * collection.
1110:      *
1111:      * @return the hashcode of the collection.
1112:      */
1113:     public int hashCode()
1114:     {
1115:       return c.hashCode();
1116:     }
1117: 
1118:   } // class EnvironmentSet<String>
1119: 
1120: } // class System