KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mx4j > tools > naming > CosNamingService


1 /*
2  * Copyright (C) The MX4J Contributors.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the MX4J License version 1.0.
6  * See the terms of the MX4J License in the documentation provided with this software.
7  */

8
9 package mx4j.tools.naming;
10
11 import java.io.BufferedInputStream JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.io.InputStream JavaDoc;
15 import java.io.InterruptedIOException JavaDoc;
16 import java.security.AccessController JavaDoc;
17 import java.security.PrivilegedAction JavaDoc;
18
19 import mx4j.log.Log;
20 import mx4j.log.Logger;
21
22 /**
23  * An MBean that wraps tnameserv. <p>
24  * Calling {@link #start} will start tnameserv in a separate process via
25  * {@link java.lang.Runtime#exec(String) Runtime.exec(String command)}.
26  *
27  * @version $Revision: 1.13 $
28  */

29 public class CosNamingService implements CosNamingServiceMBean
30 {
31    private int m_port;
32    private volatile boolean m_running;
33    private Process JavaDoc m_process;
34    private InputStreamConsumer m_output;
35    private InputStreamConsumer m_error;
36    private volatile Exception JavaDoc exception;
37
38    /**
39     * Creates a new instance of CosNamingService with the default port (900).
40     */

41    public CosNamingService()
42    {
43       this(900);
44    }
45
46    /**
47     * Creates a new instance of CosNamingService with the specified port.
48     */

49    public CosNamingService(int port)
50    {
51       m_port = port;
52    }
53
54    /**
55     * Sets the port on which tnameserv listens for incoming connections.
56     *
57     * @see #getPort
58     */

59    public void setPort(int port)
60    {
61       m_port = port;
62    }
63
64    /**
65     * Returns the port on which tnameserv listens for incoming connections
66     *
67     * @see #setPort
68     */

69    public int getPort()
70    {
71       return m_port;
72    }
73
74    /**
75     * Returns whether this MBean has been started and not yet stopped.
76     *
77     * @see #start
78     */

79    public boolean isRunning()
80    {
81       return m_running;
82    }
83
84    /**
85     * Starts this MBean: tnameserv can now accept incoming calls
86     *
87     * @see #stop
88     * @see #isRunning
89     */

90    public synchronized void start() throws Exception JavaDoc
91    {
92       if (isRunning()) return;
93
94       final Logger logger = getLogger();
95
96       // We start another thread because Process.waitFor() blocks until the process is destroyed.
97
Thread JavaDoc thread = new Thread JavaDoc(new Runnable JavaDoc()
98       {
99          public void run()
100          {
101             String JavaDoc home = getJavaHomeBin();
102
103             String JavaDoc command = (home == null ? "" : home) + "tnameserv -ORBInitialPort " + getPort();
104             try
105             {
106                m_process = Runtime.getRuntime().exec(command);
107                if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Process created: " + m_process);
108             }
109             catch (IOException JavaDoc x)
110             {
111                if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Could not create process", x);
112                exception = x;
113                return;
114             }
115
116             m_output = new InputStreamConsumer(m_process.getInputStream());
117             m_error = new InputStreamConsumer(m_process.getErrorStream());
118             m_output.start();
119             m_error.start();
120
121             m_running = true;
122
123             try
124             {
125                // Blocks until the process is destroyed
126
int result = m_process.waitFor();
127                if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Exit value for tnameserv is: " + result);
128
129                // If we're still running after waitFor() returns, means stop() has not been called
130
// so the process has returned unexpectedly, we signal this by setting the exception
131
if (isRunning())
132                {
133                   stop();
134                   if (logger.isEnabledFor(Logger.INFO)) logger.info("Unexpected death of tnameserv process (maybe the port " + getPort() + " is already in use)");
135                   exception = new IOException JavaDoc("Unexpected death of tnameserv process " + m_process);
136                }
137             }
138             catch (InterruptedException JavaDoc x)
139             {
140                if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Process tnameserv has been interrupted", x);
141                stop();
142             }
143          }
144       }, "CosNamingService Thread");
145
146       thread.setDaemon(true);
147       thread.start();
148
149       // Nothing better than wait for a while for the process to check if it is really started
150
Thread.sleep(500);
151
152       // Check if the process is still alive; it is not fool proof since
153
// the sleep above may not have been enough.
154
try
155       {
156          m_process.exitValue();
157          // The process exited unexpectedly
158
throw new IOException JavaDoc("Unexpected death of tnameserv process " + m_process);
159       }
160       catch (IllegalThreadStateException JavaDoc ignored)
161       {
162          // There are good chances that the process is still running, go on
163
if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Process tnameserv is alive");
164       }
165
166       // Double check that the process is still running, since we're not fool proof
167
if (!isRunning() && exception != null) throw exception;
168
169       if (logger.isEnabledFor(Logger.TRACE)) logger.trace("CosNamingService started");
170    }
171
172    private String JavaDoc getJavaHomeBin()
173    {
174       String JavaDoc home = (String JavaDoc)AccessController.doPrivileged(new PrivilegedAction JavaDoc()
175       {
176          public Object JavaDoc run()
177          {
178             return System.getProperty("java.home");
179          }
180       });
181       if (home != null && !home.endsWith(File.separator)) home += File.separator;
182       if (home != null) home += "bin" + File.separator;
183       return home;
184    }
185
186    /**
187     * Stops this MBean: tnameserv cannot accept anymore incoming calls
188     *
189     * @see #start
190     */

191    public synchronized void stop()
192    {
193       if (!isRunning()) return;
194
195       m_running = false;
196       m_output.interrupt();
197       m_error.interrupt();
198       m_process.destroy();
199    }
200
201    private Logger getLogger()
202    {
203       return Log.getLogger(getClass().getName());
204    }
205
206    private class InputStreamConsumer extends Thread JavaDoc
207    {
208       private final InputStream JavaDoc m_stream;
209       private final byte[] m_buffer = new byte[128];
210
211       public InputStreamConsumer(InputStream JavaDoc stream)
212       {
213          super("Stream Consumer Thread");
214          m_stream = new BufferedInputStream JavaDoc(stream);
215          setDaemon(true);
216       }
217
218       public void run()
219       {
220          Logger logger = getLogger();
221          while (!isInterrupted())
222          {
223             try
224             {
225                int read = -1;
226                while ((read = m_stream.read(m_buffer)) >= 0)
227                {
228                   if (logger.isEnabledFor(Logger.INFO)) logger.info(new String JavaDoc(m_buffer, 0, read));
229                }
230             }
231             catch (InterruptedIOException JavaDoc x)
232             {
233                Thread.currentThread().interrupt();
234                break;
235             }
236             catch (IOException JavaDoc x)
237             {
238                if (logger.isEnabledFor(Logger.INFO)) logger.info("Error while consuming process stream", x);
239                break;
240             }
241          }
242       }
243    }
244 }
245
Popular Tags