KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > launcher > ParentListener


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.commons.launcher;
18
19 import java.io.File JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22
23 /**
24  * A class for detecting if the parent JVM that launched this process has
25  * terminated.
26  *
27  * @author Patrick Luby
28  */

29 public class ParentListener extends Thread JavaDoc {
30
31     //------------------------------------------------------------------ Fields
32

33     /**
34      * Cached heartbeat file.
35      */

36     private File JavaDoc heartbeatFile = null;
37
38     //------------------------------------------------------------ Constructors
39

40     /**
41      * Validates and caches a lock file created by the parent JVM.
42      *
43      * @param path the lock file that the parent JVM has an open
44      * FileOutputStream
45      * @throws IOException if the heartbeat cannot be converted into a valid
46      * File object
47      */

48     public ParentListener(String JavaDoc path) throws IOException JavaDoc {
49
50         if (path == null)
51             throw new IOException JavaDoc();
52
53         // Make sure we have a valid path
54
heartbeatFile = new File JavaDoc(path);
55         heartbeatFile.getCanonicalPath();
56
57     }
58
59     //----------------------------------------------------------------- Methods
60

61     /**
62      * Periodically check that the parent JVM has not terminated. On all
63      * platforms other than Windows, this method will check that System.in has
64      * not been closed. On Windows NT, 2000, and XP the lock file specified in
65      * the {@link #ParentListener(String)} constructor is monitored as reading
66      * System.in will block the entire process on Windows machines that use
67      * some versions of Unix shells such as MKS, etc. No monitoring is done
68      * on Window 95, 98, and ME.
69      */

70     public void run() {
71
72         String JavaDoc osname = System.getProperty("os.name").toLowerCase();
73
74         // We need to use file locking on Windows since reading System.in
75
// will block the entire process on some Windows machines.
76
if (osname.indexOf("windows") >= 0) {
77
78             // Do nothing if this is a Windows 9x platform since our file
79
// locking mechanism does not work on the early versions of
80
// Windows
81
if (osname.indexOf("nt") == -1 && osname.indexOf("2000") == -1 && osname.indexOf("xp") == -1)
82                 return;
83
84             // If we can delete the heartbeatFile on Windows, it means that
85
// the parent JVM has closed its FileOutputStream on the file.
86
// Note that the parent JVM's stream should only be closed when
87
// it exits.
88
for ( ; ; ) {
89                 if (heartbeatFile.delete())
90                     break;
91                 // Wait awhile before we try again
92
yield();
93                 try {
94                     sleep(5000);
95                 } catch (Exception JavaDoc e) {}
96             }
97
98         } else {
99
100             // Cache System.in in case the application redirects
101
InputStream JavaDoc is = System.in;
102             int bytesAvailable = 0;
103             int bytesRead = 0;
104             byte[] buf = new byte[1024];
105             try {
106                 while (true) {
107                     synchronized (is) {
108                         // Mark the stream position so that other threads can
109
// reread the strea
110
is.mark(buf.length);
111                         // Read one more byte than has already been read to
112
// force the stream to wait for input
113
bytesAvailable = is.available();
114                         if (bytesAvailable < buf.length) {
115                             bytesRead = is.read(buf, 0, bytesAvailable + 1);
116                             // Reset so that we "unread" the bytes that we read
117
is.reset();
118                             if (bytesRead == -1)
119                                 break;
120                         } else {
121                             // Make the buffer larger
122
if (buf.length < Integer.MAX_VALUE / 2)
123                                 buf = new byte[buf.length * 2];
124                         }
125                     }
126                     yield();
127                 }
128             } catch (IOException JavaDoc ioe) {}
129
130         }
131
132         // Clean up before exiting
133
if (heartbeatFile != null)
134             heartbeatFile.delete();
135
136         // Exit this process since the parent JVM has exited
137
System.exit(0);
138
139     }
140
141 }
142
Popular Tags