• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 /*
18  * Copyright (C) 2008 The Android Open Source Project
19  *
20  * Licensed under the Apache License, Version 2.0 (the "License");
21  * you may not use this file except in compliance with the License.
22  * You may obtain a copy of the License at
23  *
24  *      http://www.apache.org/licenses/LICENSE-2.0
25  *
26  * Unless required by applicable law or agreed to in writing, software
27  * distributed under the License is distributed on an "AS IS" BASIS,
28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29  * See the License for the specific language governing permissions and
30  * limitations under the License.
31  */
32 
33 package java.lang;
34 
35 import dalvik.system.VMStack;
36 import java.io.Console;
37 import java.io.FileDescriptor;
38 import java.io.FileInputStream;
39 import java.io.FileOutputStream;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.PrintStream;
43 import java.nio.channels.Channel;
44 import java.nio.channels.spi.SelectorProvider;
45 import java.util.AbstractMap;
46 import java.util.Collections;
47 import java.util.HashMap;
48 import java.util.Map;
49 import java.util.Properties;
50 import java.util.PropertyPermission;
51 import java.util.Set;
52 
53 /**
54  * Provides access to system-related information and resources including
55  * standard input and output. Enables clients to dynamically load native
56  * libraries. All methods of this class are accessed in a static way and the
57  * class itself can not be instantiated.
58  *
59  * @see Runtime
60  */
61 public final class System {
62 
63     /**
64      * Default input stream.
65      */
66     public static final InputStream in;
67 
68     /**
69      * Default output stream.
70      */
71     public static final PrintStream out;
72 
73     /**
74      * Default error output stream.
75      */
76     public static final PrintStream err;
77 
78     /**
79      * The System Properties table.
80      */
81     private static Properties systemProperties;
82 
83     /**
84      * Initialize all the slots in System on first use.
85      */
86     static {
87         /*
88          * Set up standard in, out, and err. TODO err and out are
89          * String.ConsolePrintStream. All three are buffered in Harmony. Check
90          * and possibly change this later.
91          */
92         err = new PrintStream(new FileOutputStream(FileDescriptor.err));
93         out = new PrintStream(new FileOutputStream(FileDescriptor.out));
94         in = new FileInputStream(FileDescriptor.in);
95     }
96 
97     /**
98      * Sets the standard input stream to the given user defined input stream.
99      *
100      * @param newIn
101      *            the user defined input stream to set as the standard input
102      *            stream.
103      * @throws SecurityException
104      *             if a {@link SecurityManager} is installed and its {@code
105      *             checkPermission()} method does not allow the change of the
106      *             stream.
107      */
setIn(InputStream newIn)108     public static void setIn(InputStream newIn) {
109         SecurityManager secMgr = System.getSecurityManager();
110         if(secMgr != null) {
111             secMgr.checkPermission(RuntimePermission.permissionToSetIO);
112         }
113         setFieldImpl("in", "Ljava/io/InputStream;", newIn);
114     }
115 
116     /**
117      * Sets the standard output stream to the given user defined output stream.
118      *
119      * @param newOut
120      *            the user defined output stream to set as the standard output
121      *            stream.
122      * @throws SecurityException
123      *             if a {@link SecurityManager} is installed and its {@code
124      *             checkPermission()} method does not allow the change of the
125      *             stream.
126      */
setOut(java.io.PrintStream newOut)127     public static void setOut(java.io.PrintStream newOut) {
128         SecurityManager secMgr = System.getSecurityManager();
129         if(secMgr != null) {
130             secMgr.checkPermission(RuntimePermission.permissionToSetIO);
131         }
132         setFieldImpl("out", "Ljava/io/PrintStream;", newOut);
133     }
134 
135     /**
136      * Sets the standard error output stream to the given user defined output
137      * stream.
138      *
139      * @param newErr
140      *            the user defined output stream to set as the standard error
141      *            output stream.
142      * @throws SecurityException
143      *             if a {@link SecurityManager} is installed and its {@code
144      *             checkPermission()} method does not allow the change of the
145      *             stream.
146      */
setErr(java.io.PrintStream newErr)147     public static void setErr(java.io.PrintStream newErr) {
148         SecurityManager secMgr = System.getSecurityManager();
149         if(secMgr != null) {
150             secMgr.checkPermission(RuntimePermission.permissionToSetIO);
151         }
152         setFieldImpl("err", "Ljava/io/PrintStream;", newErr);
153     }
154 
155     /**
156      * Prevents this class from being instantiated.
157      */
System()158     private System() {
159     }
160 
161     /**
162      * Copies {@code length} elements from the array {@code src},
163      * starting at offset {@code srcPos}, into the array {@code dst},
164      * starting at offset {@code dstPos}.
165      *
166      * @param src
167      *            the source array to copy the content.
168      * @param srcPos
169      *            the starting index of the content in {@code src}.
170      * @param dst
171      *            the destination array to copy the data into.
172      * @param dstPos
173      *            the starting index for the copied content in {@code dst}.
174      * @param length
175      *            the number of elements to be copied.
176      */
arraycopy(Object src, int srcPos, Object dst, int dstPos, int length)177     public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length);
178 
179     /**
180      * Returns the current system time in milliseconds since January 1, 1970
181      * 00:00:00 UTC. This method shouldn't be used for measuring timeouts or
182      * other elapsed time measurements, as changing the system time can affect
183      * the results.
184      *
185      * @return the local system time in milliseconds.
186      */
currentTimeMillis()187     public static native long currentTimeMillis();
188 
189     /**
190      * Returns the current timestamp of the most precise timer available on the
191      * local system. This timestamp can only be used to measure an elapsed
192      * period by comparing it against another timestamp. It cannot be used as a
193      * very exact system time expression.
194      *
195      * @return the current timestamp in nanoseconds.
196      */
nanoTime()197     public static native long nanoTime();
198 
199     /**
200      * Causes the virtual machine to stop running and the program to exit. If
201      * {@link #runFinalizersOnExit(boolean)} has been previously invoked with a
202      * {@code true} argument, then all objects will be properly
203      * garbage-collected and finalized first.
204      *
205      * @param code
206      *            the return code.
207      * @throws SecurityException
208      *             if the running thread has not enough permission to exit the
209      *             virtual machine.
210      * @see SecurityManager#checkExit
211      */
exit(int code)212     public static void exit(int code) {
213         Runtime.getRuntime().exit(code);
214     }
215 
216     /**
217      * Indicates to the virtual machine that it would be a good time to run the
218      * garbage collector. Note that this is a hint only. There is no guarantee
219      * that the garbage collector will actually be run.
220      */
gc()221     public static void gc() {
222         Runtime.getRuntime().gc();
223     }
224 
225     /**
226      * Returns the value of the environment variable with the given name {@code
227      * var}.
228      *
229      * @param name
230      *            the name of the environment variable.
231      * @return the value of the specified environment variable or {@code null}
232      *         if no variable exists with the given name.
233      * @throws SecurityException
234      *             if a {@link SecurityManager} is installed and its {@code
235      *             checkPermission()} method does not allow the querying of
236      *             single environment variables.
237      */
getenv(String name)238     public static String getenv(String name) {
239         if (name == null) {
240             throw new NullPointerException();
241         }
242         SecurityManager secMgr = System.getSecurityManager();
243         if (secMgr != null) {
244             secMgr.checkPermission(new RuntimePermission("getenv." + name));
245         }
246 
247         return getEnvByName(name);
248     }
249 
250     /*
251      * Returns an environment variable. No security checks are performed.
252      * @param var the name of the environment variable
253      * @return the value of the specified environment variable
254      */
getEnvByName(String name)255     private static native String getEnvByName(String name);
256 
257     /**
258      * Returns an unmodifiable map of all available environment variables.
259      *
260      * @return the map representing all environment variables.
261      * @throws SecurityException
262      *             if a {@link SecurityManager} is installed and its {@code
263      *             checkPermission()} method does not allow the querying of
264      *             all environment variables.
265      */
getenv()266     public static Map<String, String> getenv() {
267         SecurityManager secMgr = System.getSecurityManager();
268         if (secMgr != null) {
269             secMgr.checkPermission(new RuntimePermission("getenv.*"));
270         }
271 
272         Map<String, String> map = new HashMap<String, String>();
273 
274         int index = 0;
275         String entry = getEnvByIndex(index++);
276         while (entry != null) {
277             int pos = entry.indexOf('=');
278             if (pos != -1) {
279                 map.put(entry.substring(0, pos), entry.substring(pos + 1));
280             }
281 
282             entry = getEnvByIndex(index++);
283         }
284 
285         return new SystemEnvironment(map);
286     }
287 
288     /*
289      * Returns an environment variable. No security checks are performed. The
290      * safe way of traversing the environment is to start at index zero and
291      * count upwards until a null pointer is encountered. This marks the end of
292      * the Unix environment.
293      * @param index the index of the environment variable
294      * @return the value of the specified environment variable
295      */
getEnvByIndex(int index)296     private static native String getEnvByIndex(int index);
297 
298     /**
299      * Returns the inherited channel from the creator of the current virtual
300      * machine.
301      *
302      * @return the inherited {@link Channel} or {@code null} if none exists.
303      * @throws IOException
304      *             if an I/O error occurred.
305      * @see SelectorProvider
306      * @see SelectorProvider#inheritedChannel()
307      */
inheritedChannel()308     public static Channel inheritedChannel() throws IOException {
309         return SelectorProvider.provider().inheritedChannel();
310     }
311 
312     /**
313      * Returns the system properties. Note that this is not a copy, so that
314      * changes made to the returned Properties object will be reflected in
315      * subsequent calls to getProperty and getProperties.
316      *
317      * @return the system properties.
318      * @throws SecurityException
319      *             if a {@link SecurityManager} is installed and its {@code
320      *             checkPropertiesAccess()} method does not allow the operation.
321      */
getProperties()322     public static Properties getProperties() {
323         SecurityManager secMgr = System.getSecurityManager();
324         if (secMgr != null) {
325             secMgr.checkPropertiesAccess();
326         }
327 
328         return internalGetProperties();
329     }
330 
331     /**
332      * Returns the system properties without any security checks. This is used
333      * for access from within java.lang.
334      *
335      * @return the system properties
336      */
internalGetProperties()337     static Properties internalGetProperties() {
338         if (System.systemProperties == null) {
339             SystemProperties props = new SystemProperties();
340             props.preInit();
341             props.postInit();
342             System.systemProperties = props;
343         }
344 
345         return systemProperties;
346     }
347 
348     /**
349      * Returns the value of a particular system property or {@code null} if no
350      * such property exists.
351      *
352      * <p>The following properties are always provided by the virtual machine:
353      * <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
354      * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
355      *     <td><b>Name</b></td>        <td><b>Meaning</b></td>                    <td><b>Example</b></td></tr>
356      * <tr><td>file.separator</td>     <td>{@link java.io.File#separator}</td>    <td>{@code /}</td></tr>
357      *
358      * <tr><td>java.class.path</td>    <td>System class path</td>                 <td>{@code .}</td></tr>
359      * <tr><td>java.class.version</td> <td>Maximum supported .class file version</td> <td>{@code 46.0}</td></tr>
360      * <tr><td>java.compiler</td>      <td>(Not useful on Android)</td>           <td>Empty</td></tr>
361      * <tr><td>java.ext.dirs</td>      <td>(Not useful on Android)</td>           <td>Empty</td></tr>
362      * <tr><td>java.home</td>          <td>Location of the VM on the file system</td> <td>{@code /system}</td></tr>
363      * <tr><td>java.io.tmpdir</td>     <td>See {@link java.io.File#createTempFile}</td> <td>{@code /sdcard}</td></tr>
364      * <tr><td>java.library.path</td>  <td>Search path for JNI libraries</td>     <td>{@code /system/lib}</td></tr>
365      * <tr><td>java.vendor</td>        <td>Human-readable VM vendor</td>          <td>{@code The Android Project}</td></tr>
366      * <tr><td>java.vendor.url</td>    <td>URL for VM vendor's web site</td>      <td>{@code http://www.android.com/}</td></tr>
367      * <tr><td>java.version</td>       <td>(Not useful on Android)</td>           <td>{@code 0}</td></tr>
368      *
369      * <tr><td>java.specification.version</td>    <td>VM libraries version</td>        <td>{@code 0.9}</td></tr>
370      * <tr><td>java.specification.vendor</td>     <td>VM libraries vendor</td>         <td>{@code The Android Project}</td></tr>
371      * <tr><td>java.specification.name</td>       <td>VM libraries name</td>           <td>{@code Dalvik Core Library}</td></tr>
372      * <tr><td>java.vm.version</td>               <td>VM implementation version</td>   <td>{@code 1.2.0}</td></tr>
373      * <tr><td>java.vm.vendor</td>                <td>VM implementation vendor</td>    <td>{@code The Android Project}</td></tr>
374      * <tr><td>java.vm.name</td>                  <td>VM implementation name</td>      <td>{@code Dalvik}</td></tr>
375      * <tr><td>java.vm.specification.version</td> <td>VM specification version</td>    <td>{@code 0.9}</td></tr>
376      * <tr><td>java.vm.specification.vendor</td>  <td>VM specification vendor</td>     <td>{@code The Android Project}</td></tr>
377      * <tr><td>java.vm.specification.name</td>    <td>VM specification name</td>       <td>{@code Dalvik Virtual Machine Specification}</td></tr>
378      *
379      * <tr><td>line.separator</td>     <td>Default line separator</td>            <td>{@code \n}</td></tr>
380      *
381      * <tr><td>os.arch</td>            <td>OS architecture</td>                   <td>{@code armv7l}</td></tr>
382      * <tr><td>os.name</td>            <td>OS (kernel) name</td>                  <td>{@code Linux}</td></tr>
383      * <tr><td>os.version</td>         <td>OS (kernel) version</td>               <td>{@code 2.6.32.9-g103d848}</td></tr>
384      *
385      * <tr><td>path.separator</td>     <td>{@link java.io.File#pathSeparator}</td> <td>{@code :}</td></tr>
386      *
387      * <tr><td>user.dir</td>           <td>Base of non-absolute paths</td>        <td>{@code /}</td></tr>
388      * <tr><td>user.home</td>          <td>(Not useful on Android)</td>           <td>Empty</td></tr>
389      * <tr><td>user.name</td>          <td>(Not useful on Android)</td>           <td>Empty</td></tr>
390      *
391      * </table>
392      *
393      * @param propertyName
394      *            the name of the system property to look up.
395      * @return the value of the specified system property or {@code null} if the
396      *         property doesn't exist.
397      * @throws SecurityException
398      *             if a {@link SecurityManager} is installed and its {@code
399      *             checkPropertyAccess()} method does not allow the operation.
400      */
getProperty(String propertyName)401     public static String getProperty(String propertyName) {
402         return getProperty(propertyName, null);
403     }
404 
405     /**
406      * Returns the value of a particular system property. The {@code
407      * defaultValue} will be returned if no such property has been found.
408      *
409      * @param prop
410      *            the name of the system property to look up.
411      * @param defaultValue
412      *            the return value if the system property with the given name
413      *            does not exist.
414      * @return the value of the specified system property or the {@code
415      *         defaultValue} if the property does not exist.
416      * @throws SecurityException
417      *             if a {@link SecurityManager} is installed and its {@code
418      *             checkPropertyAccess()} method does not allow the operation.
419      */
getProperty(String prop, String defaultValue)420     public static String getProperty(String prop, String defaultValue) {
421         if (prop.length() == 0) {
422             throw new IllegalArgumentException();
423         }
424         SecurityManager secMgr = System.getSecurityManager();
425         if (secMgr != null) {
426             secMgr.checkPropertyAccess(prop);
427         }
428 
429         return internalGetProperties().getProperty(prop, defaultValue);
430     }
431 
432     /**
433      * Sets the value of a particular system property.
434      *
435      * @param prop
436      *            the name of the system property to be changed.
437      * @param value
438      *            the value to associate with the given property {@code prop}.
439      * @return the old value of the property or {@code null} if the property
440      *         didn't exist.
441      * @throws SecurityException
442      *             if a security manager exists and write access to the
443      *             specified property is not allowed.
444      */
setProperty(String prop, String value)445     public static String setProperty(String prop, String value) {
446         if (prop.length() == 0) {
447             throw new IllegalArgumentException();
448         }
449         SecurityManager secMgr = System.getSecurityManager();
450         if (secMgr != null) {
451             secMgr.checkPermission(new PropertyPermission(prop, "write"));
452         }
453         return (String)internalGetProperties().setProperty(prop, value);
454     }
455 
456     /**
457      * Removes a specific system property.
458      *
459      * @param key
460      *            the name of the system property to be removed.
461      * @return the property value or {@code null} if the property didn't exist.
462      * @throws NullPointerException
463      *             if the argument {@code key} is {@code null}.
464      * @throws IllegalArgumentException
465      *             if the argument {@code key} is empty.
466      * @throws SecurityException
467      *             if a security manager exists and write access to the
468      *             specified property is not allowed.
469      */
clearProperty(String key)470     public static String clearProperty(String key) {
471         if (key == null) {
472             throw new NullPointerException();
473         }
474         if (key.length() == 0) {
475             throw new IllegalArgumentException();
476         }
477 
478         SecurityManager secMgr = System.getSecurityManager();
479         if (secMgr != null) {
480             secMgr.checkPermission(new PropertyPermission(key, "write"));
481         }
482         return (String)internalGetProperties().remove(key);
483     }
484 
485     /**
486      * Returns the {@link java.io.Console} associated with this VM, or null.
487      * Not all VMs will have an associated console. A console is typically only
488      * available for programs run from the command line.
489      * @since 1.6
490      */
console()491     public static Console console() {
492         return Console.getConsole();
493     }
494 
495     /**
496      * Returns null. Android does not use {@code SecurityManager}. This method
497      * is only provided for source compatibility.
498      *
499      * @return null
500      */
getSecurityManager()501     public static SecurityManager getSecurityManager() {
502         return null;
503     }
504 
505     /**
506      * Returns an integer hash code for the parameter. The hash code returned is
507      * the same one that would be returned by the method {@code
508      * java.lang.Object.hashCode()}, whether or not the object's class has
509      * overridden hashCode(). The hash code for {@code null} is {@code 0}.
510      *
511      * @param anObject
512      *            the object to calculate the hash code.
513      * @return the hash code for the given object.
514      * @see java.lang.Object#hashCode
515      */
identityHashCode(Object anObject)516     public static native int identityHashCode(Object anObject);
517 
518     /**
519      * Loads and links the dynamic library that is identified through the
520      * specified path. This method is similar to {@link #loadLibrary(String)},
521      * but it accepts a full path specification whereas {@code loadLibrary} just
522      * accepts the name of the library to load.
523      *
524      * @param pathName
525      *            the path of the file to be loaded.
526      * @throws SecurityException
527      *             if the library was not allowed to be loaded.
528      */
load(String pathName)529     public static void load(String pathName) {
530         SecurityManager smngr = System.getSecurityManager();
531         if (smngr != null) {
532             smngr.checkLink(pathName);
533         }
534         Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader());
535     }
536 
537     /**
538      * Loads and links the library with the specified name. The mapping of the
539      * specified library name to the full path for loading the library is
540      * implementation-dependent.
541      *
542      * @param libName
543      *            the name of the library to load.
544      * @throws UnsatisfiedLinkError
545      *             if the library could not be loaded.
546      * @throws SecurityException
547      *             if the library was not allowed to be loaded.
548      */
loadLibrary(String libName)549     public static void loadLibrary(String libName) {
550         SecurityManager smngr = System.getSecurityManager();
551         if (smngr != null) {
552             smngr.checkLink(libName);
553         }
554         Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
555     }
556 
557     /**
558      * Provides a hint to the virtual machine that it would be useful to attempt
559      * to perform any outstanding object finalization.
560      */
runFinalization()561     public static void runFinalization() {
562         Runtime.getRuntime().runFinalization();
563     }
564 
565     /**
566      * Ensures that, when the virtual machine is about to exit, all objects are
567      * finalized. Note that all finalization which occurs when the system is
568      * exiting is performed after all running threads have been terminated.
569      *
570      * @param flag
571      *            the flag determines if finalization on exit is enabled.
572      * @deprecated this method is unsafe.
573      */
574     @SuppressWarnings("deprecation")
575     @Deprecated
runFinalizersOnExit(boolean flag)576     public static void runFinalizersOnExit(boolean flag) {
577         Runtime.runFinalizersOnExit(flag);
578     }
579 
580     /**
581      * Sets all system properties.
582      *
583      * @param p
584      *            the new system property.
585      * @throws SecurityException
586      *             if a {@link SecurityManager} is installed and its {@code
587      *             checkPropertiesAccess()} method does not allow the operation.
588      */
setProperties(Properties p)589     public static void setProperties(Properties p) {
590         SecurityManager secMgr = System.getSecurityManager();
591         if (secMgr != null) {
592             secMgr.checkPropertiesAccess();
593         }
594 
595         systemProperties = p;
596     }
597 
598     /**
599      * Throws {@code SecurityException}.
600      *
601      * <p>Security managers do <i>not</i> provide a secure environment for
602      * executing untrusted code and are unsupported on Android. Untrusted code
603      * cannot be safely isolated within a single VM on Android.
604      *
605      * @param sm a security manager
606      * @throws SecurityException always
607      */
setSecurityManager(SecurityManager sm)608     public static void setSecurityManager(SecurityManager sm) {
609         if (sm != null) {
610             throw new SecurityException();
611         }
612     }
613 
614     /**
615      * Returns the platform specific file name format for the shared library
616      * named by the argument.
617      *
618      * @param userLibName
619      *            the name of the library to look up.
620      * @return the platform specific filename for the library.
621      */
mapLibraryName(String userLibName)622     public static native String mapLibraryName(String userLibName);
623 
624     /**
625      * Sets the value of the named static field in the receiver to the passed in
626      * argument.
627      *
628      * @param fieldName
629      *            the name of the field to set, one of in, out, or err
630      * @param stream
631      *            the new value of the field
632      */
setFieldImpl(String fieldName, String signature, Object stream)633     private static native void setFieldImpl(String fieldName, String signature, Object stream);
634 
635 
636     /**
637      * The unmodifiable environment variables map. The System.getenv() specifies
638      * that this map must throw when queried with non-String keys values.
639      */
640     static class SystemEnvironment extends AbstractMap<String, String> {
641         private final Map<String, String> map;
642 
SystemEnvironment(Map<String, String> map)643         public SystemEnvironment(Map<String, String> map) {
644             this.map = Collections.unmodifiableMap(map);
645         }
646 
entrySet()647         @Override public Set<Entry<String, String>> entrySet() {
648             return map.entrySet();
649         }
650 
get(Object key)651         @Override public String get(Object key) {
652             return map.get(toNonNullString(key));
653         }
654 
containsKey(Object key)655         @Override public boolean containsKey(Object key) {
656             return map.containsKey(toNonNullString(key));
657         }
658 
containsValue(Object value)659         @Override public boolean containsValue(Object value) {
660             return map.containsValue(toNonNullString(value));
661         }
662 
toNonNullString(Object o)663         private String toNonNullString(Object o) {
664             if (o == null) {
665                 throw new NullPointerException();
666             }
667             return (String) o;
668         }
669     }
670 }
671 
672 /**
673  * Internal class holding the System properties. Needed by the Dalvik VM for the
674  * two native methods. Must not be a local class, since we don't have a System
675  * instance.
676  */
677 class SystemProperties extends Properties {
678     // Dummy, just to make the compiler happy.
679 
preInit()680     native void preInit();
681 
postInit()682     native void postInit();
683 }
684