Frames | No Frames |
1: /* ActivationGroup.java -- the RMI activation group. 2: Copyright (c) 1996, 1997, 1998, 1999, 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.rmi.activation; 40: 41: import gnu.java.rmi.activation.DefaultActivationGroup; 42: import gnu.java.rmi.activation.DefaultActivationSystem; 43: 44: import java.lang.reflect.Constructor; 45: import java.rmi.MarshalledObject; 46: import java.rmi.Remote; 47: import java.rmi.RemoteException; 48: import java.rmi.server.UnicastRemoteObject; 49: 50: /** 51: * The entity that receives the request to activate object and activates it. 52: * Frequently there is one activation group per virtual machine. 53: * 54: * @author Audrius Meskauskas (audriusa@Bioinformatics.org) (from stub) 55: */ 56: public abstract class ActivationGroup 57: extends UnicastRemoteObject 58: implements ActivationInstantiator 59: { 60: 61: /** 62: * Use the SVUID for interoperability. 63: */ 64: static final long serialVersionUID = - 7696947875314805420L; 65: 66: /** 67: * The Id of the current group on this VM (null if none). 68: */ 69: static ActivationGroupID currentGroupId = null; 70: 71: /** 72: * The groups identifier. 73: */ 74: final ActivationGroupID groupId; 75: 76: /** 77: * The groups activation monitor. 78: */ 79: ActivationMonitor monitor; 80: 81: /** 82: * The groups incarnation number. 83: */ 84: long incarnation; 85: 86: /** 87: * The groups activation system. 88: */ 89: static ActivationSystem system; 90: 91: /** 92: * Used during the group creation (required constructor). 93: */ 94: static final Class[] cConstructorTypes = new Class[] 95: { 96: ActivationGroupID.class, 97: MarshalledObject.class 98: }; 99: 100: /** 101: * Create the new activation group with the given group id. 102: * 103: * @param aGroupId the group Id. 104: * 105: * @throws RemoteException if the group export fails. 106: */ 107: protected ActivationGroup(ActivationGroupID aGroupId) throws RemoteException 108: { 109: groupId = aGroupId; 110: } 111: 112: /** 113: * The method is called when the object is exported. The group must notify 114: * the activation monitor, if this was not already done before. 115: * 116: * @param id the object activation id 117: * @param obj the remote object implementation 118: * 119: * @throws ActivationException if the group is inactive 120: * @throws UnknownObjectException if such object is not known 121: * @throws RemoteException if the call to monitor fails 122: */ 123: public abstract void activeObject(ActivationID id, Remote obj) 124: throws ActivationException, UnknownObjectException, RemoteException; 125: 126: /** 127: * Notifies the monitor about the object being inactivated. 128: * 129: * @param id the object being inactivated. 130: * @return true always (must be overridden to return other values). 131: * @throws ActivationException never 132: * @throws UnknownObjectException if the object is not known 133: * @throws RemoteException if the remote call to monitor fails 134: */ 135: public boolean inactiveObject(ActivationID id) throws ActivationException, 136: UnknownObjectException, RemoteException 137: { 138: if (monitor != null) 139: monitor.inactiveObject(id); 140: return true; 141: } 142: 143: /** 144: * Create the new instance of the activation group, using the class name and 145: * location information, stored in the passed descriptor. The method expects 146: * the group class to have the two parameter constructor, the first parameter 147: * being the {@link ActivationGroupID} and the second the 148: * {@link MarshalledObject}. The group must be first be registered with the 149: * ActivationSystem. Once a group is created, the currentGroupID method 150: * returns the identifier for this group until the group becomes inactive. 151: * 152: * @param id the activation group id 153: * @param desc the group descriptor, providing the information, necessary to 154: * create the group 155: * @param incarnation the incarnation number 156: * @return the created group instance 157: * @throws ActivationException if the activation fails due any reason 158: */ 159: public static ActivationGroup createGroup(ActivationGroupID id, 160: ActivationGroupDesc desc, 161: long incarnation) 162: throws ActivationException 163: { 164: // If the activation system is not yet set, set it to the system. 165: // passed in the group id. 166: if (system == null) 167: system = id.system; 168: 169: ActivationGroup group = null; 170: 171: // TODO at the moment all groups are created on the current jre and the 172: // group class must be reachable via thread context class loader. 173: Class groupClass; 174: 175: if (desc.className != null) 176: { 177: try 178: { 179: ClassLoader loader = Thread.currentThread().getContextClassLoader(); 180: groupClass = loader.loadClass(desc.className); 181: } 182: catch (ClassNotFoundException e) 183: { 184: ActivationException acex = new ActivationException( 185: "Cannot load " + desc.className); 186: acex.detail = e; 187: throw acex; 188: } 189: } 190: else 191: groupClass = DefaultActivationGroup.class; 192: 193: try 194: { 195: Constructor constructor = groupClass.getConstructor(cConstructorTypes); 196: group = (ActivationGroup) constructor.newInstance( 197: new Object[] { id, desc.data }); 198: } 199: catch (Exception e) 200: { 201: ActivationException acex = new ActivationException( 202: "Cannot instantiate " + desc.className); 203: acex.detail = e; 204: throw acex; 205: } 206: 207: currentGroupId = id; 208: try 209: { 210: group.monitor = getSystem().activeGroup(id, group, incarnation); 211: return group; 212: } 213: catch (RemoteException e) 214: { 215: ActivationException acex = new ActivationException("createGroup"); 216: acex.detail = e; 217: throw acex; 218: } 219: } 220: 221: /** 222: * Get the id of current activation group. 223: * 224: * @return the id of the current activation group or null if none exists. 225: */ 226: public static ActivationGroupID currentGroupID() 227: { 228: try 229: { 230: if (currentGroupId==null) 231: { 232: // This will also assing the currentGroupId to the current 233: // (default) group of the default system. 234: setSystem(DefaultActivationSystem.get()); 235: } 236: } 237: catch (ActivationException e) 238: { 239: InternalError ierr = new InternalError("Unable to activate AS"); 240: ierr.initCause(e); 241: throw ierr; 242: } 243: 244: return currentGroupId; 245: } 246: 247: /** 248: * Set the activation system for this virtual machine. The system can only 249: * be set if no group is active. 250: * 251: * @param aSystem the system to set 252: * 253: * @throws ActivationException if some group is active now. 254: */ 255: public static void setSystem(ActivationSystem aSystem) 256: throws ActivationException 257: { 258: if (currentGroupId!=null) 259: throw new ActivationException("Group active"); 260: else 261: { 262: try 263: { 264: // Register the default transient activation system and group. 265: system = aSystem; 266: ActivationGroupDesc def = new ActivationGroupDesc( 267: DefaultActivationGroup.class.getName(), 268: "", 269: null, 270: null, 271: null); 272: currentGroupId = system.registerGroup(def); 273: } 274: catch (Exception ex) 275: { 276: InternalError ierr = new InternalError("Unable to start default AG"); 277: ierr.initCause(ex); 278: throw ierr; 279: } 280: } 281: } 282: 283: /** 284: * Get the current activation system. If the system is not set via 285: * {@link #setSystem} method, the default system for this virtual machine is 286: * returned. The default system is first searched by name 287: * "java.rmi.activation.ActivationSystem" on the activation registry port. The 288: * default value of the activation registry port is 289: * {@link ActivationSystem#SYSTEM_PORT}, but it can be changed by putting the 290: * system property java.rmi.activation.port. Both activation system and 291: * activation registry are provided by the RMI daemon tool, RMID, if it is 292: * running on the local host. If the RMID is not running, the internal 293: * transient activation system will be created and returned. This internal 294: * system is highly limited in in capabilities and is not intended to be used 295: * anywhere apart automated testing. 296: * 297: * @return the activation system for this virtual machine 298: * @throws ActivationException 299: */ 300: public static ActivationSystem getSystem() throws ActivationException 301: { 302: if (system == null) 303: system = DefaultActivationSystem.get(); 304: return system; 305: } 306: 307: /** 308: * Makes the call back to the groups {@link ActivationMonitor}. 309: * 310: * @param id the id obj the object being activated 311: * @param mObject the marshalled object, contains the activated remote object 312: * stub. 313: * @throws ActivationException on activation error 314: * @throws UnknownObjectException if such object is not registered 315: * @throws RemoteException on remote call (to monitor) error 316: */ 317: protected void activeObject(ActivationID id, 318: MarshalledObject<? extends Remote> mObject) 319: throws ActivationException, UnknownObjectException, RemoteException 320: { 321: if (monitor!=null) 322: monitor.activeObject(id, mObject); 323: 324: id.group = this; 325: } 326: 327: /** 328: * Makes the call back to the groups {@link ActivationMonitor} and sets 329: * the current group to null. 330: */ 331: protected void inactiveGroup() throws UnknownGroupException, RemoteException 332: { 333: if (monitor!=null) 334: monitor.inactiveGroup(groupId, incarnation); 335: 336: if (currentGroupId!=null && currentGroupId.equals(groupId)) 337: currentGroupId = null; 338: } 339: 340: }