KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > proactive > core > rmi > ClassFileServer


1 /**
2  *
3  * ProActive: The Java(TM) library for Parallel, Distributed,
4  * Concurrent computing with Security and Mobility
5  *
6  * Copyright (C) 1997-2002 INRIA/University of Nice-Sophia Antipolis
7  * Contact: proactive-support@inria.fr
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22  * USA
23  *
24  * Initial developer(s): The ProActive Team
25  * http://www.inria.fr/oasis/ProActive/contacts.html
26  * Contributor(s):
27  *
28  *
29  */

30 package org.objectweb.proactive.core.rmi;
31
32 import org.objectweb.proactive.core.component.asmgen.MetaObjectInterfaceClassGenerator;
33 import org.objectweb.proactive.core.component.asmgen.RepresentativeInterfaceClassGenerator;
34
35
36 /**
37  * The ClassFileServer implements a ClassServer that
38  * reads class files from the file system. See the
39  * doc for the "Main" method for how to run this
40  * server.
41  */

42 public class ClassFileServer extends ClassServer {
43     private java.io.File JavaDoc[] codebases;
44
45     //
46
// -- CONSTRUCTORS -----------------------------------------------
47
//
48

49     /**
50      * Constructs a ClassFileServer.
51      * @param classpath the classpath where the server locates classes
52      */

53     public ClassFileServer() throws java.io.IOException JavaDoc {
54         this(0, null);
55     }
56
57     /**
58      * Constructs a ClassFileServer.
59      * @param classpath the classpath where the server locates classes
60      */

61     public ClassFileServer(int port) throws java.io.IOException JavaDoc {
62         this(port, null);
63     }
64
65     /**
66      * Constructs a ClassFileServer.
67      * @param classpath the classpath where the server locates classes
68      */

69     public ClassFileServer(String JavaDoc paths) throws java.io.IOException JavaDoc {
70         this(0, paths);
71     }
72
73     /**
74      * Constructs a ClassFileServer.
75      * @param port the port to bound the server to
76      * @param classpath the classpath where the server locates classes
77      */

78     public ClassFileServer(int port, String JavaDoc paths) throws java.io.IOException JavaDoc {
79         super(port);
80         if (paths != null) {
81             codebases = findClasspathRoots(paths);
82         }
83         printMessage();
84     }
85
86     //
87
// -- PUBLIC METHODS -----------------------------------------------
88
//
89
public static boolean isPortAlreadyBound(int port) {
90         java.net.Socket JavaDoc socket = null;
91         try {
92             socket = new java.net.Socket JavaDoc(java.net.InetAddress.getLocalHost(),
93                     port);
94             // if we can connect to the port it means the server already exists
95
return true;
96         } catch (java.io.IOException JavaDoc e) {
97             return false;
98         } finally {
99             try {
100                 if (socket != null) {
101                     socket.close();
102                 }
103             } catch (java.io.IOException JavaDoc e) {
104             }
105         }
106     }
107
108     /**
109      * Main method to create the class server that reads
110      * class files. This takes two optional command line arguments, the
111      * port on which the server accepts requests and the
112      * root of the classpath. To start up the server: <br><br>
113      *
114      * <code> java ClassFileServer [&lt;classpath>] [&lt;port>]
115      * </code><br><br>
116      *
117      * The codebase of an RMI server using this webserver would
118      * simply contain a URL with the host and port of the web
119      * server (if the webserver's classpath is the same as
120      * the RMI server's classpath): <br><br>
121      *
122      * <code> java -Djava.rmi.server.codebase=http://zaphod:2001/ RMIServer
123      * </code> <br><br>
124      *
125      * You can create your own class server inside your RMI server
126      * application instead of running one separately. In your server
127      * main simply create a ClassFileServer: <br><br>
128      *
129      * <code> new ClassFileServer(port, classpath);
130      * </code>
131      */

132     public static void main(String JavaDoc[] args) {
133         int port = 0;
134         String JavaDoc classpath = null;
135         if (args.length >= 1) {
136             port = Integer.parseInt(args[0]);
137         }
138         if (args.length >= 2) {
139             classpath = args[1];
140         }
141         try {
142             new ClassFileServer(port, classpath);
143         } catch (java.io.IOException JavaDoc e) {
144             logger.fatal("Unable to start ClassServer: " + e.getMessage());
145             e.printStackTrace();
146         }
147     }
148
149     //
150
// -- PROTECTED METHODS -----------------------------------------------
151
//
152

153     /**
154      * Returns an array of bytes containing the bytecodes for
155      * the class represented by the argument <b>path</b>.
156      * The <b>path</b> is a dot separated class name with
157      * the ".class" extension removed.
158      *
159      * @return the bytecodes for the class
160      * @exception ClassNotFoundException if the class corresponding
161      * to <b>path</b> could not be loaded.
162      */

163     protected byte[] getBytes(String JavaDoc path)
164         throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
165         // System.out.println("ClassFileServer: looking for class " + path);
166
byte[] b = null;
167         if (codebases == null) {
168             // reading from resources in the classpath
169
b = getBytesFromResource(path);
170         } else {
171             for (int i = 0; i < codebases.length; i++) {
172                 try {
173                     if (codebases[i].isDirectory()) {
174                         b = getBytesFromDirectory(path, codebases[i]);
175                     } else {
176                         b = getBytesFromArchive(path, codebases[i]);
177                     }
178                 } catch (java.io.IOException JavaDoc e) {
179                 }
180             }
181         }
182         if (b != null) {
183             return b;
184         }
185
186         // try to get the class as a generated stub
187
// generate it if necessary
188
b = org.objectweb.proactive.core.mop.MOPClassLoader.getMOPClassLoader()
189                                                            .getClassData(path);
190         if (b != null) {
191             return b;
192         }
193
194         // COMPONENTS
195
// try to get the class as a generated component interface reference
196
b = RepresentativeInterfaceClassGenerator.getClassData(path);
197
198         if (b != null) {
199             return b;
200         }
201
202         // COMPONENTS
203
// try to get the class as a generated component interface reference
204
b = MetaObjectInterfaceClassGenerator.getClassData(path);
205         if (b != null) {
206             return b;
207         }
208
209         throw new ClassNotFoundException JavaDoc("Cannot find class " + path);
210     }
211
212     //
213
// -- PRIVATE METHODS -----------------------------------------------
214
//
215

216     /**
217      * Returns an array of bytes containing the bytecodes for
218      * the class represented by the argument <b>path</b>.
219      * The <b>path</b> is a dot separated class name with
220      * the ".class" extension removed.
221      * @param path the fqn of the class
222      * @return the bytecodes for the class
223      * @exception java.io.IOException if the class cannot be read
224      */

225     private byte[] getBytesFromResource(String JavaDoc path) throws java.io.IOException JavaDoc {
226         // System.out.println("ClassFileServer: looking for class " + path);
227
String JavaDoc filename = path.replace('.', '/') + ".class";
228         java.io.InputStream JavaDoc in = this.getClass().getClassLoader()
229                                      .getResourceAsStream(filename);
230         if (in == null) {
231             return null;
232         }
233         int length = in.available();
234
235         //if (logger.isDebugEnabled()) {
236
// //logger.debug("ClassFileServer reading: " + filename+" length="+length+" from classpath");
237
//}
238
if (length == -1) {
239             throw new java.io.IOException JavaDoc("File length is unknown: " +
240                 filename);
241         } else {
242             return getBytesFromInputStream(in, length);
243         }
244     }
245
246     /**
247      * Returns an array of bytes containing the bytecodes for
248      * the class represented by the argument <b>path</b>.
249      * The <b>path</b> is a dot separated class name with
250      * the ".class" extension removed.
251      * @param path the fqn of the class
252      * @param codeBase the File that must be a jar or zip archive that may contain the class
253      * @return the bytecodes for the class
254      * @exception java.io.IOException if the class cannot be read
255      */

256     private byte[] getBytesFromArchive(String JavaDoc path, java.io.File JavaDoc archive)
257         throws java.io.IOException JavaDoc {
258         String JavaDoc filename = path.replace('.', '/') + ".class";
259         java.util.zip.ZipFile JavaDoc jarFile = new java.util.zip.ZipFile JavaDoc(archive);
260         java.util.zip.ZipEntry JavaDoc zipEntry = jarFile.getEntry(filename);
261         if (zipEntry == null) {
262             return null;
263         }
264         int length = (int) (zipEntry.getSize());
265
266         //if (logger.isDebugEnabled()) {
267
// //logger.debug("ClassFileServer reading: " + filename+" length="+length+" from jar/xip file "+archive.getAbsolutePath());
268
//}
269
if (length == -1) {
270             throw new java.io.IOException JavaDoc("File length is unknown: " +
271                 filename);
272         } else {
273             return getBytesFromInputStream(jarFile.getInputStream(zipEntry),
274                 length);
275         }
276     }
277
278     /**
279      * Returns an array of bytes containing the bytecodes for
280      * the class represented by the argument <b>path</b>.
281      * The <b>path</b> is a dot separated class name with
282      * the ".class" extension removed.
283      * @param path the fqn of the class
284      * @param codeBase the File that must be a directory that may contain the class
285      * @return the bytecodes for the class
286      * @exception java.io.IOException if the class cannot be read
287      */

288     private byte[] getBytesFromDirectory(String JavaDoc path, java.io.File JavaDoc directory)
289         throws java.io.IOException JavaDoc {
290         java.io.File JavaDoc f = new java.io.File JavaDoc(directory,
291                 path.replace('.', java.io.File.separatorChar) + ".class");
292         if (!f.exists()) {
293             return null;
294         }
295         int length = (int) (f.length());
296
297         //if (logger.isDebugEnabled()) {
298
// //logger.debug("ClassFileServer reading: " + f.getAbsolutePath()+" length="+length);
299
//}
300
if (length == 0) {
301             throw new java.io.IOException JavaDoc("File length is zero: " + path);
302         } else {
303             return getBytesFromInputStream(new java.io.FileInputStream JavaDoc(f),
304                 length);
305         }
306     }
307
308     /**
309      * Returns an array of bytes containing the bytecodes for
310      * the class represented by the InputStream
311      * @param in the inputstream of the class file
312      * @return the bytecodes for the class
313      * @exception java.io.IOException if the class cannot be read
314      */

315     private byte[] getBytesFromInputStream(java.io.InputStream JavaDoc in, int length)
316         throws java.io.IOException JavaDoc {
317         java.io.DataInputStream JavaDoc din = new java.io.DataInputStream JavaDoc(in);
318         byte[] bytecodes = new byte[length];
319         try {
320             din.readFully(bytecodes);
321         } finally {
322             if (din != null) {
323                 din.close();
324             }
325         }
326         return bytecodes;
327     }
328
329     private void printMessage() {
330         if (logger.isDebugEnabled()) {
331             logger.debug(
332                 "To use this ClassFileServer set the property java.rmi.server.codebase to http://" +
333                 hostname + ":" + port + "/");
334         }
335         if (codebases == null) {
336             logger.info(
337                 " --> This ClassFileServer is reading resources from classpath");
338         } else {
339             logger.info(
340                 " --> This ClassFileServer is reading resources from the following paths");
341             for (int i = 0; i < codebases.length; i++) {
342                 logger.info(" (" + i + ") : " +
343                     codebases[i].getAbsolutePath());
344             }
345         }
346     }
347
348     private java.io.File JavaDoc[] findClasspathRoots(String JavaDoc classpath) {
349         String JavaDoc pathSeparator = System.getProperty("path.separator");
350         java.util.StringTokenizer JavaDoc st = new java.util.StringTokenizer JavaDoc(classpath,
351                 pathSeparator);
352         int n = st.countTokens();
353         java.io.File JavaDoc[] roots = new java.io.File JavaDoc[n];
354         for (int i = 0; i < n; i++) {
355             roots[i] = new java.io.File JavaDoc(st.nextToken());
356         }
357         return roots;
358     }
359 }
360
Popular Tags