001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.harness.jvm
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.harness;
023:
024: import java.util.Enumeration;
025: import java.util.Properties;
026: import java.util.Vector;
027: import java.util.StringTokenizer;
028: import java.io.File;
029: import java.io.IOException;
030:
031: import org.apache.derby.impl.tools.sysinfo.ZipInfoProperties;
032: import org.apache.derbyTesting.junit.SecurityManagerSetup;
033:
034: /**
035: <p>This class provides the interface and mechanism
036: for plugging VMs into the system. Typically
037: you only need to add a new implementation if your
038: supported attributes or command line building are
039: different from those that exist.
040:
041: <p>this class has fields for all options that a JDK VM can take,
042: that is the reference point for all others. Note some VMs (like jview)
043: don't take all options and will ignore them (like -mx). Defining
044: the system property "verbose" to 1 will give you warnings for ignored
045: properties in a properly implemented subclass.
046:
047: <p> here is the canonical output from java -help for options we take:
048: <pre>
049: -noasyncgc don't allow asynchronous garbage collection
050: -verbosegc print a message when garbage collection occurs
051: -noclassgc disable class garbage collection
052: -ss<number> set the maximum native stack size for any thread
053: -oss<number> set the maximum Java stack size for any thread
054: -ms<number> set the initial Java heap size
055: -mx<number> set the maximum Java heap size
056: -classpath <directories separated by semicolons>
057: list directories in which to look for classes
058: -prof[:<file>] output profiling data to .\java.prof or .\<file>
059: -verify verify all classes when read in
060: -noverify do not verify any class
061: -nojit turn off the jit
062: -Dprop=name define property; can be specified more than once
063: </pre>
064:
065: @author ames
066: */
067:
068: public abstract class jvm {
069:
070: // they all take their defaults as the initial value.
071: // -1, null, and false all will mean we won't include them
072: // in the command line.
073:
074: // flags just take the whole string of flags as is
075: public String flags = null;
076: // -noasyncgc don't allow asynchronous garbage collection
077: public boolean noasyncgc = false;
078: // -verbosegc print a message when garbage collection occurs
079: public boolean verbosegc = false;
080: // -noclassgc disable class garbage collection
081: public boolean noclassgc = false;
082: // -ss<number> set the maximum native stack size for any thread
083: public long ss = -1;
084: // -oss<number> set the maximum Java stack size for any thread
085: public long oss = -1;
086: // -ms<number> set the initial Java heap size
087: public long ms = -1;
088: // -mx<number> set the maximum Java heap size
089: public long mx = -1;
090: // -classpath <directories separated by semicolons>
091: // list directories in which to look for classes
092: public String classpath = null;
093: // -prof[:<file>] output profiling data to .\java.prof or .\<file>
094: public String prof = null;
095: // -verify verify all classes when read in
096: // (remote verification is the default)
097: public boolean verify = false;
098: // -noverify do not verify any class
099: // (remote verification is the default)
100: public boolean noverify = false;
101: // -nojit turn off the jit
102: public boolean nojit = false;
103: // -Dprop=name define property; can be specified more than once
104: public Vector D = null;
105: // java cmd (java, java_g)
106: public String javaCmd = "java";
107: // major and minor version
108: public String majorVersion = "";
109: public String minorVersion = "";
110: public int imajor = 0;
111: public int iminor = 0;
112: String hostName;
113:
114: // security defaults relative to WS
115: // not used if jvmargs serverCodeBase are set
116: private static String DEFAULT_POLICY = "util/derby_tests.policy";
117: private static String DEFAULT_CODEBASE = "/classes";
118:
119: // constructors
120: public jvm() {
121: }
122:
123: public jvm(boolean noasyncgc, boolean verbosegc, boolean noclassgc,
124: long ss, long oss, long ms, long mx, String classpath,
125: String prof, boolean verify, boolean noverify,
126: boolean nojit, Vector D) {
127: this .noasyncgc = noasyncgc;
128: this .noclassgc = noclassgc;
129: this .verbosegc = verbosegc;
130: this .ss = ss;
131: this .oss = oss;
132: this .ms = ms;
133: this .mx = mx;
134: this .classpath = classpath;
135: this .prof = prof;
136: this .verify = verify;
137: this .noverify = noverify;
138: this .nojit = nojit;
139: this .D = D;
140: }
141:
142: // more typical use:
143: public jvm(String classpath, Vector D) {
144: this .classpath = classpath;
145: this .D = D;
146: }
147:
148: // more typical use:
149: public jvm(long ms, long mx, String classpath, Vector D) {
150: this .ms = ms;
151: this .mx = mx;
152: this .classpath = classpath;
153: this .D = D;
154: }
155:
156: /**
157: return the property definition introducer, with a space if a
158: separator is needed.
159: */
160: public abstract String getDintro();
161:
162: public abstract String getName();
163:
164: public void setNoasyncgc(boolean noasyncgc) {
165: this .noasyncgc = noasyncgc;
166: }
167:
168: public void setNoclassgc(boolean noclassgc) {
169: this .noclassgc = noclassgc;
170: }
171:
172: public void setVerbosegc(boolean verbosegc) {
173: this .verbosegc = verbosegc;
174: }
175:
176: public void setSs(long ss) {
177: this .ss = ss;
178: }
179:
180: public void setOss(long oss) {
181: this .oss = oss;
182: }
183:
184: public void setMs(long ms) {
185: this .ms = ms;
186: }
187:
188: public void setMx(long mx) {
189: this .mx = mx;
190: }
191:
192: public void setClasspath(String classpath) {
193: this .classpath = classpath;
194: }
195:
196: public void setProf(String prof) {
197: this .prof = prof;
198: }
199:
200: public void setVerify(boolean verify) {
201: this .verify = verify;
202: }
203:
204: public void setNoverify(boolean noverify) {
205: this .noverify = noverify;
206: }
207:
208: public void setNojit(boolean nojit) {
209: this .nojit = nojit;
210: }
211:
212: public void setD(Vector D) {
213: this .D = D;
214: }
215:
216: public void setFlags(String flags) {
217: this .flags = flags;
218: }
219:
220: public void setJavaCmd(String jcmd) {
221: this .javaCmd = jcmd;
222: }
223:
224: public Vector getCommandLine() {
225: Vector v = new Vector();
226: v.addElement(javaCmd);
227: v.addElement("-Duser.language=en");
228: v.addElement("-Duser.country=US");
229: if ((flags != null) && (flags.length() > 0)) {
230: StringTokenizer st = new StringTokenizer(flags);
231: while (st.hasMoreTokens()) {
232: v.addElement(st.nextToken());
233: }
234: }
235: return v;
236: }
237:
238: // implementation, used by subclasses only
239: int verboselevel = -1;
240:
241: public void warn(String msg) {
242: if (verboselevel == -1) {
243: try {
244: verboselevel = Integer.parseInt((String) (System
245: .getProperty("verbose")));
246: } catch (Exception e) {
247: verboselevel = 0;
248: }
249: }
250: if (verboselevel > 0)
251: System.out.println("jvm: " + msg);
252: }
253:
254: // utility for locating a jvm.
255: /**
256: pass in class name for JVM. If we can't find it, try
257: also org.apache.derbyTesting.functionTests.harness.<jvmName>
258: */
259: public static jvm getJvm(String jvmName)
260: throws ClassNotFoundException, InstantiationException,
261: IllegalAccessException {
262: jvm result = null;
263: try {
264: result = (jvm) Class.forName(jvmName).newInstance();
265: } catch (ClassNotFoundException e) {
266: result = (jvm) Class.forName(
267: "org.apache.derbyTesting.functionTests.harness."
268: + jvmName).newInstance();
269: }
270: return result;
271: }
272:
273: /**
274: Get the current JVM using the normal test harness rules for finding
275: a JVM.
276: <OL>
277: <LI> If the sytem property 'jvm' use this name.
278: <LI> else if the java version starts with 1.2 use
279: "jdk12".
280: <LI> else use "currentjvm".
281: */
282: public static jvm getCurrentJvm() throws Exception {
283: String jvmName = System.getProperty("jvm");
284: if ((jvmName == null) || (jvmName.length() == 0)) {
285: String javaVersion = System.getProperty("java.version");
286: if (javaVersion.startsWith("1.2"))
287: jvmName = "jdk12";
288: else
289: jvmName = "currentjvm";
290: }
291: return getJvm(jvmName);
292: }
293:
294: /**
295: Return the major version number
296: */
297: public int getMajorVersion() {
298: return imajor;
299: }
300:
301: /**
302: Return the major version number
303: */
304: public int getMinorVersion() {
305: return iminor;
306: }
307:
308: /**
309: Get the current JVM using the normal test harness rules for finding
310: a JVM.
311: */
312: public void setVersion() throws Exception {
313: // check for jdk12 or higher
314: String javaVersion = System.getProperty("java.version");
315: int i = javaVersion.indexOf('.');
316: int j = javaVersion.indexOf('.', i + 1);
317: majorVersion = javaVersion.substring(0, i);
318: minorVersion = javaVersion.substring(i + 1, j);
319: Integer minor = new Integer(minorVersion);
320: iminor = minor.intValue();
321: Integer major = new Integer(majorVersion);
322: imajor = major.intValue();
323:
324: String jvmName = System.getProperty("jvm");
325:
326: if ((jvmName == null) || (jvmName.length() == 0)) {
327: if (iminor < 2)
328: jvmName = "currentjvm";
329: else
330: jvmName = "jdk" + majorVersion + minorVersion;
331: }
332: }
333:
334: /** Find $WS based on the assumption that JAVA_HOME is $WS/<jvm_name>
335: * or $WS/<jvm_name>/jre
336: * @return path of $WS
337: */
338: protected static String guessWSHome() {
339: String wshome = "";
340: String jhome = System.getProperty("java.home");
341: String sep = System.getProperty("file.separator");
342: // need to strip off the java directory assuming it's something
343: // like ibm14/jre or ibm14
344: wshome = jhome.substring(0, jhome.indexOf(sep + "jre"));
345: wshome = wshome.substring(0, wshome.lastIndexOf(sep));
346: return wshome;
347: }
348:
349: public static String findCodeBase(boolean[] isJar) {
350: String classpath = System.getProperty("java.class.path");
351: char sep = '/';
352: ZipInfoProperties zip[] = org.apache.derby.impl.tools.sysinfo.Main
353: .getAllInfo(classpath);
354: for (int i = 0; i < zip.length; i++) {
355: // it's a url so should just have forward slashes
356: String location = zip[i].getLocation().replace('\\', '/');
357: if (location.indexOf("derbynet.jar") != -1) {
358: isJar[0] = true;
359: return location.substring(0, location.lastIndexOf(sep));
360: } else if ((location.indexOf("classes") != -1)
361: && location.indexOf(".jar") == -1) {
362: isJar[0] = false;
363: return location;
364: }
365: }
366: return null;
367: }
368:
369: /**
370: * set up security properties for server command line.
371: */
372: protected void setSecurityProps() throws java.io.IOException,
373: ClassNotFoundException {
374: D = jvm.getSecurityProps(D);
375:
376: }
377:
378: static Vector getSecurityProps(Vector D)
379: throws ClassNotFoundException, IOException {
380: if (D == null)
381: D = new Vector();
382:
383: String userDir = System.getProperty("user.dir");
384: String policyFile = userDir + baseName(DEFAULT_POLICY);
385:
386: String serverCodeBase = System.getProperty("serverCodeBase");
387: boolean[] isJar = new boolean[1];
388: if (serverCodeBase == null)
389: serverCodeBase = findCodeBase(isJar);
390:
391: if (serverCodeBase == null) {
392: String ws = guessWSHome();
393: serverCodeBase = ws + DEFAULT_CODEBASE;
394:
395: }
396:
397: File pf = new File(policyFile);
398: File cb = new File(serverCodeBase);
399:
400: if (!pf.exists()) {
401: System.out
402: .println("WARNING: Running without Security manager."
403: + "policy File ("
404: + policyFile
405: + ") or serverCodeBase("
406: + serverCodeBase
407: + ") not available");
408: return D;
409: }
410:
411: D.addElement("java.security.manager");
412: D.addElement("java.security.policy=" + pf.getAbsolutePath());
413:
414: Properties jusetup = SecurityManagerSetup
415: .getPolicyFilePropertiesForOldHarness();
416: // Take the definitions from the way JUnit tests
417: // set them up. This then supports the jar files being
418: // in different locations.
419: for (Enumeration p = jusetup.keys(); p.hasMoreElements();) {
420: String key = (String) p.nextElement();
421: D.addElement(key + "=" + jusetup.getProperty(key));
422: }
423:
424: // file path to the codebase
425: D.addElement("derbyTesting.codedir=" + cb.getAbsolutePath());
426: String hostName = (System.getProperty("hostName"));
427: if (hostName == null)
428: hostName = "localhost";
429: D.addElement("derbyTesting.serverhost=" + hostName);
430: // in the case of testing with a remote host, this is irrelevant,
431: // when testing 'normal' it is also localhost:
432: D.addElement("derbyTesting.clienthost=" + hostName);
433:
434: return D;
435:
436: }
437:
438: /** Get the base file name from a resource name string
439: * @param resourceName (e.g. /org/apache/derbyTesting/functionTests/util/derby_tests.policy)
440: * @return short name (e.g. derby_tests.policy)
441: */
442: private static String baseName(String resourceName) {
443:
444: return resourceName.substring(resourceName.lastIndexOf("/"),
445: resourceName.length());
446: }
447: }
|