diff options
author | pjain <pjain@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-03-10 21:25:09 +0000 |
---|---|---|
committer | pjain <pjain@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-03-10 21:25:09 +0000 |
commit | aa2e9ccc6ea95a71e9b57f853186030f2029addc (patch) | |
tree | 6bd1ef045ddfd4027e9d8c93a147d04aef384e5d /java | |
parent | aedde8787710fa768a681f42dba1111da8e77697 (diff) | |
download | ATCD-aa2e9ccc6ea95a71e9b57f853186030f2029addc.tar.gz |
Added support to load classes across the network.
Diffstat (limited to 'java')
-rw-r--r-- | java/src/ServiceConfig.java | 25 | ||||
-rw-r--r-- | java/src/ServiceRepository.java | 161 |
2 files changed, 167 insertions, 19 deletions
diff --git a/java/src/ServiceConfig.java b/java/src/ServiceConfig.java index 8ffa26d9e98..3cf97db7eae 100644 --- a/java/src/ServiceConfig.java +++ b/java/src/ServiceConfig.java @@ -12,6 +12,7 @@ package ACE.ServiceConfigurator; import java.io.*; +import java.net.*; import ACE.OS.*; import ACE.Misc.*; @@ -55,13 +56,15 @@ public class ServiceConfig // Set '#' as comment character to be ignored and set '/' as // ordinary character (was original comment character) - in.commentChar ('#'); + // in.commentChar ('#'); in.ordinaryChar ('/'); - // Set characters in ASCII range 33 to 47 and ASCII range 91 to 96 - // as ordinary characters + // Set characters in ASCII range 33 to 47, ASCII range 91 to 96, + // and ASCII range 123 to 126 as ordinary characters in.wordChars ('!', '/'); // ASCII range 33 to 47 + in.wordChars (':', '@'); // ASCII range 58 to 64 in.wordChars ('[', '`'); // ASCII range 91 to 96 + in.wordChars ('{', '~'); // ASCII range 123 to 126 String className = null; String classType = null; @@ -95,7 +98,21 @@ public class ServiceConfig { args = in.sval; // Load the class - Class c = ServiceConfig.svcRep_.load (className); + Class c = null; + + // First check if we need to load the class from the + // file system or from across the network. + if (className.lastIndexOf ("://") != -1) + { + // We need to get the bytes over the network since + // the name specified in the configuration file + // contains a protocol specification + c = ServiceConfig.svcRep_.load (new URL (className)); + } + else + { + c = ServiceConfig.svcRep_.load (className); + } // Note that c should be defined else an exception // would have been thrown by now diff --git a/java/src/ServiceRepository.java b/java/src/ServiceRepository.java index 9ae7ed12668..e284679f458 100644 --- a/java/src/ServiceRepository.java +++ b/java/src/ServiceRepository.java @@ -13,8 +13,23 @@ package ACE.ServiceConfigurator; import java.io.*; import java.util.*; +import java.net.*; import ACE.OS.*; +/** + * <hr> + * <h2>SYNOPSIS</h2> + *<blockquote> + * Provides a repository for loaded Java classes + *</blockquote> + * + * <h2>DESCRIPTION</h2> + *<blockquote> + * This class provides a means to load Java classes explicitly at + * runtime. Note that since the class makes use of the Java + * ClassLoader, this class can not be used in a Java applet. + *</blockquote> + */ public class ServiceRepository { /** @@ -22,7 +37,27 @@ public class ServiceRepository */ public ServiceRepository () { - this.loader_ = new ServiceLoader (); + this.loader_ = new ServiceLoader (null); + } + + /** + * Create a Service Repository passing in the context. Note that + * this can cause problems for the default system loader since it will + * try to load all the system classes using the context specified. + *@param context Context to use when loading classes. + */ + public ServiceRepository (String context) + { + this.loader_ = new ServiceLoader (context); + } + + /** + * Set the context + *@param context Context to use when loading classes. + */ + public void context (String c) + { + this.loader_.context (c); } /** @@ -39,29 +74,96 @@ public class ServiceRepository return this.loader_.loadClass (name, true); } + /** + * Load a Java Class across the network. The method tries to load + * the bytes for the class and then create the Class from these + * bytes. + *@param url URL of the class to load + *@return Class corresponding to the url + */ + public Class load (URL url) throws ClassNotFoundException + { + return this.loader_.loadClass (url, true); + } + private ServiceLoader loader_; } class ServiceLoader extends ClassLoader { - public ServiceLoader () + public ServiceLoader (String context) { super (); - this.getClassPath (); + if (context == null) + this.getClassPath (); + else + this.context_ = context; } - + + public void context (String c) + { + this.context_ = c; + } + // Load a compiled class file into runtime public Class loadClass (String name, boolean resolve) throws ClassNotFoundException { Class newClass; - try + if (this.context_ == null) + { + try + { + // Try to load it the class by reading in the bytes. + // Note that we are not catching ClassNotFoundException here + // since our caller will catch it. + try + { + byte[] buf = bytesForClass (name); + newClass = defineClass (buf, 0, buf.length); + // ACE.DEBUG ("Loaded class: "+ name); + + // Check if we need to load other classes referred to by this class. + if (resolve) + resolveClass (newClass); + } + catch (ClassNotFoundException e) + { + // ACE.DEBUG ("Using default loader for class: "+ name); + // Try default system loader + if ((newClass = findSystemClass (name)) != null) + return newClass; + else + throw (e); // Rethrow the exception + } + } + catch (IOException e) + { + throw new ClassNotFoundException (e.toString ()); + } + } + else { + System.out.println ("Fetching over the net"); + System.out.println ("Context: " + this.context_); // Try to load it the class by reading in the bytes. // Note that we are not catching ClassNotFoundException here // since our caller will catch it. try { - byte[] buf = bytesForClass (name); + URL url = new URL (this.context_ + name); + URLConnection urlConnection = url.openConnection (); + + // Get the input stream associated with the URL connection and + // pipe it to a newly created DataInputStream + DataInputStream i = new DataInputStream (urlConnection.getInputStream ()); + + // Allocate a buffer big enough to hold the contents of the + // data we are about to read + byte [] buf = new byte [urlConnection.getContentLength ()]; + + // Now read all the data into the buffer + i.readFully (buf); + newClass = defineClass (buf, 0, buf.length); // ACE.DEBUG ("Loaded class: "+ name); @@ -69,16 +171,43 @@ class ServiceLoader extends ClassLoader if (resolve) resolveClass (newClass); } - catch (ClassNotFoundException e) + catch (IOException e) { - // ACE.DEBUG ("Using default loader for class: "+ name); - // Try default system loader - if ((newClass = findSystemClass (name)) != null) - return newClass; - else - throw (e); // Rethrow the exception + throw new ClassNotFoundException (e.toString ()); } } + return newClass; + } + + // Load a compiled class file across the network + public Class loadClass (URL url, boolean resolve) throws ClassNotFoundException + { + Class newClass = null; + // Try to load it the class by reading in the bytes. + // Note that we are not catching ClassNotFoundException here + // since our caller will catch it. + try + { + URLConnection urlConnection = url.openConnection (); + + // Get the input stream associated with the URL connection and + // pipe it to a newly created DataInputStream + DataInputStream i = new DataInputStream (urlConnection.getInputStream ()); + + // Allocate a buffer big enough to hold the contents of the + // data we are about to read + byte [] buf = new byte [urlConnection.getContentLength ()]; + + // Now read all the data into the buffer + i.readFully (buf); + + newClass = defineClass (buf, 0, buf.length); + // ACE.DEBUG ("Loaded class: "+ name); + + // Check if we need to load other classes referred to by this class. + if (resolve) + resolveClass (newClass); + } catch (IOException e) { throw new ClassNotFoundException (e.toString ()); @@ -113,9 +242,9 @@ class ServiceLoader extends ClassLoader ".class"); // Check if file exists, is a normal file and is readable - if (classFile.exists () && + if (true) /*classFile.exists () && classFile.isFile () && - classFile.canRead ()) + classFile.canRead ()) */ { // Set up the stream FileInputStream in = new FileInputStream (classFile); @@ -148,4 +277,6 @@ class ServiceLoader extends ClassLoader private String fileSeparator_; // Platform-dependent file separator (e.g., / or \) + + private String context_ = null; } |