1 /* 2 * Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * 26 * @bug 4105043 27 * @summary cannot set java.rmi.server.hostname on children of rmid in time 28 * 29 * @bug 4097357 30 * @summary activation group should not overwrite system properties 31 * 32 * @bug 4107184 33 * @summary activation groups should be able to control their JVM properties 34 * 35 * @author Adrian Colley 36 * 37 * @library ../../testlibrary 38 * @build TestLibrary RMID JavaVM StreamPipe 39 * @build Eliza Retireable Doctor Doctor_Stub SetChildEnv 40 * @run main/othervm/timeout=240/policy=security.policy -Djava.compiler=NONE SetChildEnv 41 */ 42 import java.rmi.*; 43 import java.util.Properties; 44 import java.io.*; 45 import java.util.StringTokenizer; 46 import java.util.Set; 47 import java.util.HashSet; 48 import java.util.Arrays; 49 import java.rmi.activation.*; 50 51 public class SetChildEnv 52 { 53 public static void main(String argv[]) 54 throws Exception 55 { 56 System.out.println("java.compiler=" + System.getProperty("java.compiler")); 57 // don't embed spaces in any of the test args/props, because 58 // they won't be parsed properly 59 runwith (new String[0], new String[0]); 60 61 runwith ( 62 new String[] { "-verbosegc" }, 63 new String[] { "foo.bar=SetChildEnvTest", 64 "sun.rmi.server.doSomething=true" } 65 ); 66 67 runwith ( 68 new String[] { }, 69 new String[] { "parameter.count=zero" } 70 ); 71 72 runwith ( 73 new String[] { "-Xmx32m" }, 74 new String[] { } 75 ); 76 } 77 78 private static void runwith( 79 String[] params, // extra args 80 String[] props // extra system properties 81 ) 82 throws Exception 83 { 84 TestLibrary.suggestSecurityManager(TestParams.defaultSecurityManager); 85 86 // make a "watcher" which listens on a pipe and searches for 87 // the debugExec line while teeing to System.err 88 DebugExecWatcher watcher = DebugExecWatcher.makeWithPipe(); 89 90 RMID.removeLog(); 91 RMID rmid = RMID.createRMID(watcher.otherEnd(), watcher.otherEnd(), 92 true); // debugExec turned on 93 94 rmid.start(); 95 96 // compile props 97 Properties p = new Properties(); 98 p.put("java.security.policy", TestParams.defaultGroupPolicy); 99 p.put("java.security.manager", TestParams.defaultSecurityManager); 100 //p.put("java.rmi.server.logCalls", "true"); 101 int i; 102 for (i = 0; i < props.length; i++) { 103 p.put(props[i].substring(0, props[i].indexOf('=')), 104 props[i].substring(props[i].indexOf('=')+1)); 105 } 106 107 // create CommandEnvironment and ActivationGroupDesc 108 ActivationGroupDesc.CommandEnvironment cmdenv = 109 new ActivationGroupDesc.CommandEnvironment( 110 null, 111 params); 112 113 ActivationGroupDesc gdesc = new ActivationGroupDesc( 114 p, cmdenv); 115 116 // register group 117 ActivationSystem actsys = ActivationGroup.getSystem(); 118 ActivationGroupID gid = actsys.registerGroup(gdesc); 119 120 // create ActivationDesc 121 ActivationDesc odesc = new ActivationDesc(gid, // group 122 "Doctor", // class 123 null, // codesource 124 null); // closure data 125 126 // register activatable object 127 Eliza doctor = (Eliza)Activatable.register(odesc); 128 129 // invoke a call with oh-so-humorous sample text 130 System.out.println ("Invoking complain()..."); 131 String complaint = 132 "HELP ME, DOCTOR. I FEEL VIOLENT TOWARDS PEOPLE " + 133 "WHO INQUIRE ABOUT MY PARENTS."; 134 135 System.out.println(complaint); 136 //Runtime.getRuntime().traceMethodCalls(true); 137 String res = doctor.complain(complaint); 138 //Runtime.getRuntime().traceMethodCalls(false); 139 System.out.println (" => " + res); 140 141 // Get debugExec line, allowing 15 seconds for it to flush 142 // through the buffers and pipes. 143 String found = watcher.found; 144 if (found == null) { 145 int fudge = 15; 146 while (found == null && --fudge > 0) { 147 Thread.sleep(1000); 148 found = watcher.found; 149 } 150 if (found == null) { 151 TestLibrary.bomb("rmid subprocess produced no " + 152 "recognizable debugExec line"); 153 } 154 } 155 156 System.err.println("debugExec found: <<" + found + ">>"); 157 // q: first double-quote after debugExec 158 int q = found.indexOf('"', found.indexOf("rmid: debugExec")); 159 // qe: last double-quote on debugExec line 160 int qe = found.lastIndexOf('"'); 161 if (q <= 1 || qe <= q) { 162 TestLibrary.bomb("rmid subprocess produced " + 163 "mangled debugExec line"); 164 } 165 166 // split args by whitespace 167 StringTokenizer tk = new StringTokenizer(found.substring(q+1, qe)); 168 tk.nextToken(); // skip command path/name 169 170 // Now check off the requested args. Order isn't important, and 171 // any extra args are ignored, even if they're inconsistent or 172 // bargage, or duplicates. 173 174 Set argset = new HashSet(tk.countTokens()); 175 while (tk.hasMoreTokens()) { 176 argset.add(tk.nextToken()); 177 } 178 179 int m; 180 for (m = 0; m < params.length; m++) { 181 if(!argset.contains(params[m])) 182 TestLibrary.bomb("Parameter \"" + params[m] + "\" not set"); 183 } 184 185 for (m = 0; m < props.length; m++) { 186 if (!argset.contains("-D" + props[m])) { 187 TestLibrary.bomb("Property binding \"" + props[m] + 188 "\" not set"); 189 } 190 } 191 192 // End doctor 193 if (doctor instanceof Retireable) 194 ((Retireable)doctor).retire(); 195 actsys.unregisterGroup(gid); 196 197 Thread.sleep(5000); 198 rmid.destroy(); 199 } 200 201 public static class DebugExecWatcher 202 extends Thread 203 { 204 public String found; 205 private BufferedReader str; 206 private OutputStream otherEnd; 207 208 private DebugExecWatcher(InputStream readStream, OutputStream wrStream) 209 { 210 super("DebugExecWatcher"); 211 found = null; 212 str = new BufferedReader(new InputStreamReader(readStream)); 213 otherEnd = wrStream; 214 } 215 216 static public DebugExecWatcher makeWithPipe() 217 throws IOException 218 { 219 PipedOutputStream wr = new PipedOutputStream(); 220 PipedInputStream rd = new PipedInputStream(wr); 221 DebugExecWatcher embryo = new DebugExecWatcher(rd, wr); 222 embryo.start(); 223 return embryo; 224 } 225 226 public OutputStream otherEnd() 227 { 228 return otherEnd; 229 } 230 231 public synchronized void notifyLine(String s) 232 { 233 if (s != null && s.indexOf("rmid: debugExec") != -1) 234 found = s; 235 } 236 237 public void run() 238 { 239 try { 240 String line; 241 while ((line = str.readLine()) != null) { 242 this.notifyLine(line); 243 System.err.println(line); 244 } 245 } catch (IOException e) { 246 e.printStackTrace(); 247 } 248 } 249 } 250 } 251 252 /* 253 code graveyard 254 255 // activation should have proceeded by writing a wrapper.out 256 // when test.src/actgrpwrapper was run. 257 258 // Read and check wrapper.out 259 BufferedReader r = new BufferedReader(new FileReader(wrapout)); 260 String[] realArgs = null; 261 String line; 262 263 while ( (line = r.readLine()) != null) { 264 StringTokenizer tkz = new StringTokenizer(line); 265 if (!tkz.nextToken().equals("actgrpwrapper")) { 266 // could throw an exception, but let's benignly 267 // assume that something unrelated is spewing. 268 continue; 269 } 270 String x; // writer's block 271 x = tkz.nextToken(); 272 if (x.equals("argc")) { 273 if (realArgs != null) { 274 throw new RuntimeException( 275 "SetChildEnv: two argc lines in wrapper.out"); 276 } 277 realArgs = new String[Integer.parseInt(tkz.nextToken())]; 278 } else if (x.equals("argv")) { 279 if (realArgs == null) 280 throw new RuntimeException("SetChildEnv: missing argc"); 281 int n = Integer.parseInt(tkz.nextToken()); 282 if (n < 1 || n > realArgs.length) { 283 throw new RuntimeException("SetChildEnv: argc=" + 284 realArgs.length + "; argv[" + n + "]"); 285 } 286 // Hack: manually skip the "actgrpwrapper argv 5 " 287 String remainder = line.substring( 288 1 + line.indexOf(' ', 289 1 + line.indexOf(' ', 290 1 + line.indexOf(' ')))); 291 realArgs[n-1] = remainder; 292 } else { 293 throw new RuntimeException("SetChildEnv: bad token \"" + x + "\""); 294 } 295 } 296 r.close(); 297 298 private static void ensureLocalExecutable(String fname) 299 throws Exception 300 { 301 File target = new File(fname); 302 File source = new File(Dot, fname); 303 if (!target.exists()) { 304 // copy from source 305 System.err.println("Copying " + source.getPath() + 306 " to " + target.getPath()); 307 java.io.InputStream in = new java.io.FileInputStream(source); 308 java.io.OutputStream out = new java.io.FileOutputStream(target); 309 byte[] buf = new byte[512]; 310 int n; 311 while ((n = in.read(buf, 0, 512)) > 0) { 312 out.write(buf, 0, n); 313 } 314 out.close(); 315 in.close(); 316 } 317 // chmod 318 System.err.println("Doing: /bin/chmod 755 " + fname); 319 Runtime.getRuntime().exec("/bin/chmod 755 " + fname).waitFor(); 320 } 321 322 */