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