Page 2 of 4
Configuration files must be created that contain all of the information relevant to the distributed applications. From now on, all of the code, files, and pieces that must be distributed to a client machine will be referred to as an application bundle.
Now, each file in a bundle must contain certain base information for the distribution class to work with. For this example, the following information will be contained in the configuration file for each piece in the bundle.
A file with the name of the bundle will be created that contains a listing of files and revisions. This file will reside on the http server.
A class must be created that handles pulling the configuration information from the http server, compares it to the local configuration, and pulls down any new files. This class will need to know the name of the bundle that it is going to check, and the address of the http server where the bundle resides. Following are the public members of this class.
Class : AutoDistribute
Public Members : Constructor (String http_server_address) boolean getClasses(String bundlename)
Every new application written now includes the AutoDistribute class as the first class in the Main. They instantiate the class and give it the address of the http server that contains the configuration information. Next, they call getClasses() and pass it the name of the bundle. If any classes are returned, then the member returns true.
The constructor goes to the http server and pulls the configuration file for the bundle. When getClasses() is called, it checks the local disk for the bundles configuration file. It compares the revisions of each file in the bundle, and pulls down any file that has a newer revision. It would be nice here to use an overloaded class loader. However, there seems to be a problem in the code. The objects pulled in via the class loader are not used by the program; only the versions of the classes on the disk at the time of application instantiation are used. This means that if the program has new classes, it must be restarted before the changes will take affect.
The class classLoader was not meant to replace any already-loaded classes. The interpreter first tries to load a class from the classpath and local directory. Then any new classLoaders are called. It would be nice if we could drop any loaded classes from the Hashtable, and reload with the new class from the server. Then a program would not have to be restarted after new classes are distributed to it.
The code used to pull files from the http server and store to disk is:
URL swopURL = new URL(urladdress+filename);
// Open the connection to the object URLConnection swopURLConn = swopURL.openConnection();
// Check to see if this is a text/plain type of file if(swopURLConn.getContentType().equals("text/plain")) { String newclass = (String)swopURL.getContent();
int datalen = swopURLConn.getContentLength(); byte data[] = new byte[datalen]; newclass.getBytes(0,datalen,data,0);
FileOutputStream fos = new FileOutputStream(newelem.classname+".class"); fos.write(data); fos.close();
return true;
}
The advantage of this system is its ability to use current http servers in its implementation, and it only requires the development of a single class on the client side. In addition, to release a piece of software for the first time, only the main class and the distribution class need to be on the client machine. However, the disadvantage is trying to keep a configuration file in sync with all of the files in a bundle. This could become an onerous task, and if things get mixed up, it could create a lot of havoc. In addition, if any class files are downloaded, the program needs to be restarted to take advantage of them. Because of the loadClass problem, classLoader does not solve this problem and allow us to dynamically load classes that have already been loaded into memory.