001: //
002: // This file is part of the midas package.
003: //
004: // The contents of this file are subject to the Mozilla Public License
005: // Version 1.1 (the "License"); you may not use this file except in
006: // compliance with the License. You may obtain a copy of the License at
007: // http://www.mozilla.org/MPL/
008: //
009: // Software distributed under the License is distributed on an "AS IS" basis,
010: // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011: // for the specific language governing rights and limitations under the
012: // License.
013: //
014: // The Original Code is midas.
015: //
016: // The Initial Developer of the Original Code is Andrei Popovici. Portions
017: // created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
018: // All Rights Reserved.
019: //
020: // Contributor(s):
021: // $Id: RemoteProseComponent.java,v 1.2 2003/08/26 19:59:18 anicoara Exp $
022: // =====================================================================
023: //
024: // (history at end)
025: //
026: package ch.ethz.prose.tools;
027:
028: // used packages
029: import java.rmi.NoSuchObjectException;
030: import java.rmi.Remote;
031: import java.rmi.RemoteException;
032: import java.rmi.server.UnicastRemoteObject;
033: import java.net.ServerSocket;
034: import java.net.Socket;
035: import java.io.ObjectOutputStream;
036: import java.io.ObjectInputStream;
037:
038: import ch.ethz.prose.SystemStartupException;
039: import ch.ethz.prose.SystemTeardownException;
040:
041: /**
042: * Class RemoteExtensionSystem starts up a remote service (a
043: * <code>RemoteExtensionManager</code>) for the insertion of
044: * extensions.
045: *
046: * <p>
047: *
048: * The current implementation uses a <code>RemoteExtensionManagerImpl</code>.
049: *
050: * <p>
051: *
052: * Note that for starting the remote extension system you will have to add
053: * a property like:
054: * <code>ch.ethz.prose.ESSystem.X=ch.ethz.prose.tools.RemoteExtensionSystem</code>
055: * to the System's properties.
056: *
057: * The property <code>prose.port</code> defines the port to start prose on.
058: *
059: * @version $Revision: 1.2 $
060: * @author Andrei Popovici
061: *
062: */
063: public class RemoteProseComponent {
064:
065: protected static String ACTIVE_INSTANCE = "activeInstance";
066: protected static String TEST_INSTANCE = "testInstance";
067: private static boolean systemUp = false;
068: private static RemoteAspectManager activeInstance = null;
069: private static RemoteAspectManager testInstance = null;
070: private static Remote activeInstanceRef = null;
071: private static Remote testInstanceRef = null;
072: private static ServerSocket listener = null;
073:
074: /**
075: * Create and export an instance of <code>RemoteExtnesionManager</code>
076: * <p>
077: * <em>Note: this method is idempotent. Succesive calls have the same
078: * effect as just one.</em>
079: *
080: * @exception SystemStartupException could not successfully start the
081: * remote extension manager.
082: */
083: public synchronized static void startup()
084: throws SystemStartupException {
085: if (systemUp)
086: return;
087: systemUp = true;
088:
089: System.setSecurityManager(new java.rmi.RMISecurityManager());
090:
091: // ATENTION!
092: // Comment because the JVM 1.4.1. blocks. To avoid this deadlock, now first starts "RemoteProseComponent" and then "ProseSystem".
093: // make sure that prose runs
094: // ProseSystem.startup();
095:
096: int portNumber = -1;
097: try {
098: portNumber = Integer.parseInt(System.getProperty(
099: "prose.port", "UNDEFINED"));
100: } catch (NumberFormatException noPortWasSpecified) {
101: throw new SystemStartupException(
102: "To use prose Remotely please specify the 'prose.port' property");
103: }
104:
105: try {
106: // create, and export the objects.
107: activeInstance = new RemoteAspectManagerImpl(true);
108: activeInstanceRef = UnicastRemoteObject
109: .exportObject(activeInstance);
110:
111: testInstance = new RemoteAspectManagerImpl(false);
112: testInstanceRef = UnicastRemoteObject
113: .exportObject(testInstance);
114:
115: listener = new ServerSocket(portNumber);
116:
117: Thread worker = new Thread() {
118: public void run() {
119: while (systemUp) {
120: try {
121: Socket s = listener.accept();
122: ObjectOutputStream objOut = new ObjectOutputStream(
123: s.getOutputStream());
124: objOut.writeObject(activeInstanceRef);
125: objOut.writeObject(testInstanceRef);
126: } catch (Exception e) {
127: e.printStackTrace();
128: }
129: }
130: }
131: };
132:
133: worker.start();
134:
135: } catch (RemoteException e) {
136: e.printStackTrace();
137: throw new SystemStartupException(
138: "Cannot export RemoteAspectManager");
139:
140: } catch (java.io.IOException e) {
141: e.printStackTrace();
142: throw new SystemStartupException(
143: "Cannot start a listener socket on the given port");
144: }
145:
146: }
147:
148: /**
149: * Unexport (without forcing)
150: * the current instance of <code>RemoteExtensionManager</code> server.
151: * <p>
152: * <em>Note: this method is idempotent. Succesive calls have the same
153: * effect as just one.</em>
154: */
155: public synchronized static void teardown()
156: throws SystemTeardownException {
157: if (!systemUp)
158: return;
159:
160: try {
161: UnicastRemoteObject.unexportObject(activeInstance, true);
162: UnicastRemoteObject.unexportObject(testInstance, true);
163: } catch (NoSuchObjectException noChance) {
164: // object HAS to be there
165: throw new Error(
166: "FIXME FOR PROSE DEVELOPER: why is the object not there?");
167: }
168:
169: systemUp = false;
170: }
171:
172: protected static RemoteAspectManager[] doGetRemoteAspectManagers(
173: String host, int connectTo)
174: throws java.net.UnknownHostException, java.io.IOException {
175: RemoteAspectManager[] result = new RemoteAspectManager[2];
176: Socket s = new Socket(host, connectTo);
177: ObjectInputStream objIn = new ObjectInputStream(s
178: .getInputStream());
179: try {
180: result[0] = (RemoteAspectManager) objIn.readObject();
181: result[1] = (RemoteAspectManager) objIn.readObject();
182: } catch (java.lang.ClassNotFoundException e) {
183: throw new Error(e.toString());
184: }
185: return result;
186: }
187:
188: }
189:
190: //======================================================================
191: //
192: // $Log: RemoteProseComponent.java,v $
193: // Revision 1.2 2003/08/26 19:59:18 anicoara
194: // Bug fix: JVM1.4.1 blocks. To avoid the deadlock first starts RemoteProseComponent and then ProseSystem (Comment the ProseSystem_startup line)
195: //
196: // Revision 1.1.1.1 2003/07/02 15:30:52 apopovic
197: // Imported from ETH Zurich
198: //
199: // Revision 1.4 2003/06/10 12:58:29 popovici
200: // Syntax bug fixed
201: //
202: // Revision 1.3 2003/06/06 12:37:37 popovici
203: // Naming.lookup replaced with a serversocket serving serialized objects; Changed:
204: // - CommandlineProseClient
205: // - RemoteProseComponent, which not opens a socket and has a utility method 'doGetAspe..'
206: // - other classes, due to different types of errors being thrown
207: //
208: // Revision 1.2 2003/05/26 17:49:45 popovici
209: // changes in the portnames; idempotent methods better implemented. ProseSystem now depends on the remote prose
210: //
211: // Revision 1.1 2003/05/25 13:25:21 popovici
212: // Refactoring
213: // inf.iks.tools is now prose.tools
214: // Stupid 'MyTableModel' renamed to 'WorksheetClientMode'
215: // - other renamings from bad names to reasonable names
216: //
217: // Revision 1.5 2003/05/25 11:48:52 popovici
218: // Major transformation of the prose tools:
219: // - GUI now stable and supports aspect insertion from another classpath than its own
220: // - CommandlineProseClient supports transactions test managers, independent classpath and has a better errhanling
221: //
222: // Revision 1.4 2003/05/05 14:03:13 popovici
223: // renaming from runes to prose
224: //
225: // Revision 1.3 2003/04/17 15:14:54 popovici
226: // Extension->Aspect renaming
227: //
228: // Revision 1.2 2003/03/04 18:35:56 popovici
229: // Organization of imprts
230: //
231: // Revision 1.1 2003/02/17 09:23:55 popovici
232: // RemoteAspectManager interface, implementation, and client added;
233: // Benchmark changed to work with the remote aspect manager;
234: // Benchmark changed to include aspect insertion;
235: //
236: // Revision 1.2 2002/07/25 08:55:40 popovici
237: // Mozilla Licensing
238: //
239: // Revision 1.1.1.1 2001/11/30 14:50:28 popovici
240: // Sources from runes
241: //
242: // Revision 1.1.2.1 2001/03/26 15:05:47 mrmuller
243: // adapted to new package structure
244: //
245: // Revision 1.1.2.4 2001/02/20 10:14:10 popovici
246: // Logger.messages added.
247: //
248: // Revision 1.1.2.3 2001/02/15 15:21:35 popovici
249: // - Thead for periodically recontacting the rmiregistry added
250: // - Startup enhanced with sequence for rebinding
251: // - Teardonw enahcned with sequence for unbinding
252: //
253: // Revision 1.1.2.2 2001/02/15 11:40:56 popovici
254: // Documentation Improvements
255: //
256: // Revision 1.1.2.1 2001/02/14 13:44:42 popovici
257: // Initial Revision
258: //
|