001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package gnu.classpath;
014    
015    import java.util.Properties;
016    import org.jikesrvm.VM;     // for VM.sysWrite()
017    import org.jikesrvm.CommandLineArgs;
018    import org.jikesrvm.Configuration;
019    
020    import org.jikesrvm.classloader.RVMClassLoader;
021    import org.jikesrvm.classloader.BootstrapClassLoader;
022    
023    /**
024     * Jikes RVM implementation of GNU Classpath's gnu.classpath.VMSystemProperties.
025     * <P>
026     * Library support interface of Jikes RVM.  See the Javadoc documentation for
027     * GNU Classpath's reference implementation of VMSystemProperties -- for
028     * copyright reasons, we cannot duplicate it here.
029     */
030    
031    public class VMSystemProperties {
032      /** VMRuntime.insertSystemProperties is used by Classpath versions through
033       *  Classpath  0.12.   Starting with Classpath 0.13, we use
034       *  gnu.classpath.VMSystemProperties.preInit and
035       *  gnu.classpath.VMSystemProperties.postInit.
036     */
037      public static void preInit(Properties p) {
038        p.put("java.version", "1.6.0"); /* This is a lie, of course -- we don't
039                                           really support all 1.6 features, such
040                                           as assertions.  However, it is a
041                                           necessary lie, since Eclipse 3.0
042                                           explicitly tests java.version and
043                                           insists upon at least 1.4.1 to run. */
044        p.put("java.vendor", "Jikes RVM Project");
045        p.put("java.vm.vendor", "Jikes RVM Project");
046        p.put("java.vendor.url", "http://jikesrvm.org");
047    
048        p.put("java.specification.name", "Java Platform API Specification");
049        p.put("java.specification.vendor", "Sun Microsystems Inc.");
050        p.put("java.specification.version", "1.6");
051    
052        p.put("java.vm.specification.name", "Java Virtual Machine Specification");
053        p.put("java.vm.specification.vendor", "Sun Microsystems Inc.");
054        p.put("java.vm.specification.version", "1.0");
055    
056        /* 50.0 brings us through Java version 1.6. */
057        p.put("java.class.version", "50.0");
058    
059        p.put("file.separator", "/");
060        p.put("path.separator", ":");
061        p.put("line.separator", "\n");
062    
063        p.put("java.compiler", "JikesRVM");
064        p.put("java.vm.version", "1.6.0");
065        p.put("java.vm.name", "JikesRVM");
066        p.put("file.encoding", "8859_1");
067        p.put("java.io.tmpdir", "/tmp");
068        p.put("gnu.cpu.endian", Configuration.LittleEndian ? "little" : "big");
069    
070    
071        String s;
072        s = BootstrapClassLoader.getBootstrapRepositories();
073        p.put("java.boot.class.path", s);
074        /* sun.boot.class.path is not necessary, yes, but possibly useful; Steve
075         * Augart has seen at least one piece of code on the web that reads
076         * this. */
077        p.put("sun.boot.class.path", s);
078    
079    
080        /* user.timezone
081    
082           I (Steve Augart) started a discussion about this on classpath@gnu.org
083           on 23 March 2003.  Summary: we define user.timezone specifically in
084           order to pass that information to GNU Classpath's implementation of
085           java.util.TimeZone, which initializes
086           later on in the boot process.  It does not seem to be required by the
087           spec, and it's the empty string in Blackdown 1.4.2.
088    
089           We have to do this here, because otherwise it wouldn't be set until
090           CommandLineArgs.lateProcessCommandLineArguments().  That won't occur
091           until the VM is fully booted; too late for java.util.TimeZone, which
092           reads this value when it runs its initializer.
093        */
094        s = CommandLineArgs.getEnvironmentArg("user.timezone");
095        s = (s == null) ? "" : s;   // Maybe it's silly to set it to the empty
096                                    // string.  Well, this should never succeed
097                                    // anyway, since we're always called by
098                                    // runrvm, which explicitly sets the value.
099        p.put("user.timezone", s);
100    
101        /* java.library.path
102           Now the library path.  This is the path used for system
103           dynamically-loaded libraries, the things that end in ".so" on Linux. */
104        insertLibraryPath(p);
105    
106        /* What should we do about java.ext.dirs?
107           XXX TODO
108    
109           java.ext.dirs is allegedly mandatory, according to the API docs shipped
110           with the Sun 1.4.2 JDK.
111    
112           Ridiculous, since we don't search it for anything, and since if the
113           user were to set it it wouldn't do anything anyway.   We keep all of
114           the extensions stored with the other bits of the JDK.   So, this would
115           really need to be prepended to the list of VM classes, wouldn't it?  Or
116           appended, perhaps? */
117        s = CommandLineArgs.getEnvironmentArg("java.ext.dirs");
118        if (s == null) {
119          s = "";
120        } else {
121          VM.sysWrite("Jikes RVM: Warning: You have explicitly set java.ext.dirs; that will not do anything under Jikes RVM");
122        }
123        p.put("java.ext.dirs", s);
124    
125    
126        /* We also set java.class.path in setApplicationRepositories().
127         *  We'll treat setting the java.class.path property as essentially
128         * equivalent to using the -classpath argument. */
129        s = CommandLineArgs.getEnvironmentArg("java.class.path");
130        if (s != null) {
131          p.put("java.class.path", s);
132          RVMClassLoader.stashApplicationRepositories(s);
133        } else {
134          p.put("java.class.path", RVMClassLoader.getApplicationRepositories());
135        }
136    
137        if (VM.PortableNativeSync) {
138          /* Enable portable native sync to support M-to-N threading with gtk peers */
139          p.put("gnu.classpath.awt.gtk.portable.native.sync", "true");
140        }
141    
142        /* Now the rest of the special ones that we set on the command line.   Do
143         * this just in case later revisions of GNU Classpath start to require
144         * some of them in the boot process; otherwise, we could wait for them to
145         * be set in CommandLineArgs.lateProcessCommandLineArguments() */
146        final String[] clProps = new String[] {"os.name", "os.arch", "os.version", "user.name", "user.home", "user.dir", "gnu.classpath.vm.shortname", "gnu.classpath.home.url", "java.home"};
147    
148        for (final String prop : clProps) {
149          s = CommandLineArgs.getEnvironmentArg(prop);
150          if (s != null) {
151            p.put(prop, s);
152          }
153        }
154      }
155    
156      /** Set java.library.path.<p>
157       *
158       * I wish I knew where to check in the source code to confirm that this
159       * is, in fact, the process we actually follow.  I do not understand this
160       * code.  I do not understand why we are adding something to
161       * java.library.path.  --Steve Augart, 3/23/2004 XXX
162       */
163      private static void insertLibraryPath(Properties p) {
164        String jlp = CommandLineArgs.getEnvironmentArg("java.library.path");
165        String snp = CommandLineArgs.getEnvironmentArg("java.home");
166        if (jlp == null) jlp = ".";
167        p.put("java.library.path", snp + p.get("path.separator") +jlp);
168      }
169    
170    
171      /** Override the default SystemProperties code; insert the command-line
172       * arguments.
173       * <p>
174       * The following are set by the "runrvm" script before we go into the C
175       * boot image runner, by passing them as command-line args with the -D flag:
176       * <p>
177       * os.name, os.arch, os.version
178       * user.name, user.home, user.dir
179       * gnu.classpath.vm.shortname, gnu.classpath.home.url,
180       * java.home,
181       * <p>
182       * We can look at them here via CommandLineArgs.getEnvironmentArg().
183       * <p>
184       * They will be automatically set for us by
185       * CommandLineArgs.lateProcessCommandLineArguments() if we do not handle
186       * them here.  That won't occur until the VM is fully booted.  That's too
187       * late for some classes, such as java.util.TimeZone, which will already be
188       * initialized.
189       * <p>
190       * In any case, this function isn't used in Jikes RVM.  Our boot sequence
191       * is already handling this OK.
192       */
193      public static void postInit(Properties properties) {
194      }
195    }