1 /* 2 * Copyright (c) 1998, 2012, 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 /** 25 * 26 */ 27 28 import java.io.File; 29 import java.rmi.Naming; 30 import java.rmi.NoSuchObjectException; 31 import java.rmi.NotBoundException; 32 import java.rmi.Remote; 33 import java.rmi.activation.Activatable; 34 import java.rmi.activation.ActivationID; 35 import java.rmi.activation.ActivationSystem; 36 import java.rmi.registry.LocateRegistry; 37 38 /** 39 * Class of test utility/library methods related to Activatable 40 * objects. 41 */ 42 public class ActivationLibrary { 43 /** time safeDestroy should wait before failing on shutdown rmid */ 44 private static final int SAFE_WAIT_TIME; 45 static { 46 int slopFactor = 1; 47 try { 48 slopFactor = Integer.valueOf( 49 TestLibrary.getExtraProperty("jcov.sleep.multiplier","1")); 50 } catch (NumberFormatException ignore) {} 51 SAFE_WAIT_TIME = 60000 * slopFactor; 52 } 53 54 private static final String SYSTEM_NAME = 55 ActivationSystem.class.getName(); 56 57 private static void mesg(Object mesg) { 58 System.err.println("ACTIVATION_LIBRARY: " + mesg.toString()); 59 } 60 61 /** 62 * Deactivate an activated Activatable 63 */ 64 public static void deactivate(Remote remote, 65 ActivationID id) { 66 // We do as much as 50 deactivation trials, each separated by 67 // at least 100 milliseconds sleep time (max sleep time of 5 secs). 68 final long deactivateSleepTime = 100; 69 long stopTime = System.currentTimeMillis() + deactivateSleepTime * 50; 70 while (System.currentTimeMillis() < stopTime) { 71 try { 72 if (Activatable.inactive(id) == true) { 73 mesg("inactive successful"); 74 return; 75 } else { 76 mesg("inactive trial failed. Sleeping " + 77 deactivateSleepTime + 78 " milliseconds before next trial"); 79 Thread.sleep(deactivateSleepTime); 80 } 81 } catch (InterruptedException e) { 82 Thread.currentThread().interrupt(); 83 mesg("Thread interrupted while trying to deactivate activatable. Exiting deactivation"); 84 return; 85 } catch (Exception e) { 86 try { 87 // forcibly unexport the object 88 mesg("Unexpected exception. Have to forcibly unexport the object." + 89 " Exception was :"); 90 e.printStackTrace(); 91 Activatable.unexportObject(remote, true); 92 } catch (NoSuchObjectException ex) { 93 } 94 return; 95 } 96 } 97 98 mesg("unable to inactivate after several attempts"); 99 mesg("unexporting object forcibly instead"); 100 101 try { 102 Activatable.unexportObject(remote, true); 103 } catch (NoSuchObjectException e) { 104 } 105 } 106 107 /** cleanup after rmid */ 108 public static void rmidCleanup(RMID rmid) { 109 if (rmid != null) { 110 if (!ActivationLibrary.safeDestroy(rmid, SAFE_WAIT_TIME)) { 111 TestLibrary.bomb("rmid not destroyed in: " + 112 SAFE_WAIT_TIME + 113 " milliseconds"); 114 } 115 } 116 RMID.removeLog(); 117 } 118 119 /** 120 * Invoke shutdown on rmid in a way that will not cause a test 121 * to hang. 122 * 123 * @return whether or not shutdown completed succesfully in the 124 * timeAllowed 125 */ 126 private static boolean safeDestroy(RMID rmid, long timeAllowed) { 127 DestroyThread destroyThread = new DestroyThread(rmid); 128 destroyThread.start(); 129 130 try { 131 destroyThread.join(timeAllowed); 132 } catch (InterruptedException ie) { 133 Thread.currentThread().interrupt(); 134 } 135 136 return destroyThread.shutdownSucceeded(); 137 } 138 139 /** 140 * Thread class to handle the destruction of rmid 141 */ 142 private static class DestroyThread extends Thread { 143 private final RMID rmid; 144 private final int port; 145 private boolean succeeded = false; 146 147 DestroyThread(RMID rmid) { 148 this.rmid = rmid; 149 this.port = rmid.getPort(); 150 this.setDaemon(true); 151 } 152 153 public void run() { 154 if (RMID.lookupSystem(port) != null) { 155 rmid.destroy(); 156 synchronized (this) { 157 // flag that the test was able to shutdown rmid 158 succeeded = true; 159 } 160 mesg("finished destroying rmid"); 161 } else { 162 mesg("tried to shutdown when rmid was not running"); 163 } 164 } 165 166 public synchronized boolean shutdownSucceeded() { 167 return succeeded; 168 } 169 } 170 }