The Florida State University College of Arts and Science A Java Enterprise Application -- Online Real-time Classroom By Yilei Wang September, 2001 A master project submitted to the Department of Computer Science In partial fulfillment of the requirements for the Degree of Master of Science Major Professor: Dr. Robert A. van Engelen Dr. Robert A. van Engelen Major Professor Dr. D. Schwartz Committee Member Dr. Hilbert Levitz Committee Member 1 Abstract In this project, I designed an online real-time classroom with client-server application model, and used Enterprise Java Technologies including Applet, Swing, JSP, JavaScript, RMI, JDBC, JNDI, etc. plus Java Sound package to implement it. This live instructor-led classroom website allows users to manager their own accounts, schedule a class, view their classes as well as starting a class on the Internet. The online classroom provides real-time voice, text and multimedia communications in a shared workspace, and delivers a classroom experience that accelerates learning. This application is mainly composed of two parts: class management and real-time classroom. For the first part, I generated Java Server Pages to present HTML response to the client requests in the web tier, while using JDBC to create connection with the database and store information into tables in the database tier. For the real-time classroom, three features are provided to allow communications between teachers and students: shared files, a voice room, and a chat room. Two servers are started up upon the teacher’s request at a remote machine to provide these services. Java sockets and RMI are applied between the clients and the servers. 2 Table of Contents 1 Introduction 1.1 1.2 2 3 Motivation 1.1.1 Distance Learning 1.1.2 Web-based Education System 1.1.3 Online Classroom Enterprise Java Technologies Online Real-time Classroom Overview 2.1 Functions of Class Management Part 2.2 Functions of Classroom Part Implementation Details 3.1 3.2 Class Management Part Implementation 3.1.1 Web Tier – JSPs and Servlets 3.1.2 Database Design Classroom Part Implementation 3.2.1 More JSPs and Tables 3.2.2 Voice Room 3.2.2.1 Java Sound API 3.2.2.2 Server SoundSer 3.2.3 4 5 Chat Room Deployment 4.1 Web Server 4.2 Deployment Process 4.3 Access Online Classroom Conclusion 3 1 Introduction 1.1 Motivation 1.1.1 Distance Learning Within a context of rapid technological change and shifting market conditions, the American education system is challenged with providing increased educational opportunities without increased budgets. Many educational institutions are answering this challenge by developing distance education programs. At its most basic level, distance education takes place when a teacher and student(s) are separated by physical distance, and technology, often in concert with face-to-face communication, is used to bridge the instructional gap. A wide range of technological options are available to the distance educator. They fall into four major categories: Voice - Instructional audio tools include the interactive technologies of telephone, audioconferencing, and short-wave radio. Video - Instructional video tools include still images such as slides, pre-produced moving images (e.g., film, videotape), and real-time moving images combined with audioconferencing (one-way or two-way video with two-way audio). Data - Computers send and receive information electronically. For this reason, the term "data" is used to describe this broad category of instructional tools. Teaching strategies based on computer applications are emerging that are more effective. 1.1.2 Web-based Education System The WWW and Web browsers have made the Internet a more user-friendly environment, and provide Internet users with a uniform and convenient means of accessing the wide variety of resources (pictures, text, data, sound, video) available on the Internet. The ability to integrate graphics, text, and sound into a single tool means that novice users do not have to struggle with such a steep learning curve. 1.1.3 Online Classroom However, for most teachers and students, web-based education still equals to visiting class homepages, submitting homework through e-mails. This situation stimulated me to think about designing and building interactive classrooms for teaching distant learners using various technologies, which allow teachers and learners to interact over a variety of telecommunications networks in a cost-effective manner. A typical online classroom should allow a teacher to: Teach a class entirely online. Effectively manage students through an easy to use, unit-based framework. 4 Post class notes, presentations. Administer online assessments. Interact easily with your students. 1.2 Enterprise Java Technologies Java is steadily becoming the language of choice for new enterprise-wide development project, because it is portable and the standards defined by the enterprise Java technologies reduce education cost. Currently the main technologies being adopted by enterprise developers include JDBC for database connectivity, the Java Naming and Directory Interface (JNDI) for accessing services, and RMI for Java remote method invocation and distributed objects. On top of this foundation are Servlets, JavaServer Pages, Enterprise Java Beans, Java Messaging Service, and Transaction management. All of these combine into a feature-rich tool kit for developing Java applications. Creating an enterprise application involves combining these technologies to create a complete solution to one’s business problems. The following are those technologies I decided to apply into my project. JDBC - The standard API for accessing relational data from a Java program. Servlets – Servlets replace CGI I providing server-side processing for HTTP requests. Servlets can extend dynamic Web pages using server-side includes or JSPs. Servlets can be used to form a gateway between Web Clients and other services such as databases, Enterprise JavaBeans, and JMS. JavaServer Pages – JSPs are used to create dynamic Web pages using Java as a scripting language. JSPs are primarily used in situations in which a Web page changes with each request. RMI and distributed objects – Many applications and libraries use RMI to form their network connections. Other applications may rely on raw sockets or HTTP connections to interact with servlets and Web Server. The goal of RMI is to provide a transparent link between two Java applications. JNDI – The standard API for accessing information in enterprise name and directory services. 5 2 Online Real-time Classroom Overview This application is composed of two portions: class management and real-time classroom. 2.1 Functions of Class Management Part This part is designed especially for teachers to manage their classes, such as scheduling a class, viewing their own classes, and updating the class information. The following diagram displays the relationship between these web pages. There are four function chains: register, schedule a class, view classes, and enter the classroom, which are shown in different line styles. Student Enter Classroom Home Schedule a Class Register View Classes Login Update Students Upcoming Class information Summary and Confirm Teacher Enter Classroom OK Figure 1. The Relationship between web pages Register Every returning user needs to login before he could take advantage of any features. For any new user, he must create an account at the first step. He will be asked to provide the name, e-mail address, password, and phone number, among which the e-mail address must be different from those of other users. 6 Schedule a Class It takes several steps to schedule a class. On the first page, the teacher needs to specify a date/time and a length of this class, as well as its subject and a brief description. The time must be in the future, otherwise an error message would be displayed. Then on the next page, a list of students’ contact information is supposed to be added, including students’ name, email address, and phone number. Finally, a scheduled class summary is shown, which also contains a pin number for every student. The pin number is supposed to be handed out by the teacher to each student, and later used by the student to enter this classroom. The instructor can then choose to cancel or really schedule this class. View Classes A teacher can view his upcoming classes as well as past classes at any time. For past classes, only instructor name, date/time, and subject are provided, while one can view much more details of upcoming classes, and update the class information by clicking a question mark icon in the same row. The instructor is allowed to change the class length, subject, and description at the next page, even add or drop students if he feels like doing so. There is always a door icon on each of these pages for the teacher to enter his classroom. He is encouraged to enter his classroom and make some preparations such as uploading a PowerPoint file before starting this class. 2.2 Functions of Classroom Part The classroom implements three features to allow communications between teachers and students: shared documents, a voice room, and a chat room. See figure 2. Shared Documents Before class, the instructor is encouraged to upload files from the local machine to the remote server. Files could be *.txt, *.doc, *.ppt, *.bmp, or other kinds of files for presentation in a class time. All the uploaded file names are displayed in a list at the bottom right frame. When you highlight one of these files, and click “Open”, this file would be displayed in the left big frame. Before the teacher starts entering the voice room and the chat room, he should first click a button “Start Class” at the upper right corner of the web page. This will start up two remote servers for the purpose of supporting the voice room and the chat room. Voice Room This voice room is used for the teacher to give a speech and for the students to listen to the teacher’s voice in a real time, exactly like students sitting in a classroom and hearing a lecture. However, this only allows teacher to talk, and students to listen, not on the contrary. At the instructor end, running the voice room as an applet requires the user to set the permission of audio recording, thus needs a line: Policy.url.3 = http://sirah.csit.fsu.edu:8270/learning/talk/applet.policy 7 appended to file <java.security> under path: C:/Program Files/JavaSoft/jre/lib/scurity/ Applet.policy is a policy file placed by me at the remote server, which is sirah.csit.fsu.edu I am currently using. After entering the voice room, i.e. starting the applet, the instruct clicks the “talk” button to speak, later click the “stop” button to end speaking. Chat Room The chat room is used for all teacher and students to communicate with each other by typing texts. Simply type a sentence into “send message” text field, and hit Enter key, the text would appear in the upper pane, seen by all other people. The teacher should always click “End Class” button at the upper right corner before exiting the classroom. This will allow other teachers to start a class. Figure 2. Real-time Classroom Interface 8 The student’s classroom interface is almost the same as the teacher’s, except that he doesn’t have the right to start or end a class, and he is only able to listen to the teacher’s speech. 9 3 Implementation Details 3.1 Class Management Part Implementation 3.1.1 Web Tier – JSPs and Servlets It was decided to generally use JSPs rather than servlets to implement the web tier. Servlets are not very suitable here, because in this case the web tier is permitted to change constantly, and this would require that we compile the program into byte code every time a change is made. Besides, a bunch of dynamic html web pages are generated upon users’ request, which makes servlets awkward to read. Therefore it is not easy to maintain a web site by using servlets. In the previous chapter, I pointed out that the main task of Class Management portion can be divided into three parts: (1) register, (2) schedule a class, and (3) view classes. I designed JSPs for each of these three parts. The following table lists the web page names and the corresponding JSP file names. Web Page Name JSP File Name Home index.jsp Register register.jsp Login login.jsp Schedule a Class schedule1.jsp Update Students students.jsp Summary and Confirm schedule2.jsp OK schedule3.jsp View Classes view1.jsp Upcoming Class Information view2.jsp Figure 3. Web tier JSPs The Java Server Pages specification [9] introduces on kind of application scenario for JSP. This is illustrated in Figure 4. After the client sends a request to the server, it is 10 recommended “to have the initial JSP page to determine details about the request, perhaps create and/or update some server-side objects, and then, if necessary, redirect the request to a different JSP page”. Create/Update Request Client JSP/Servlet ServerSide Object Redirect request Response JSP/Servlet Access/Update Figure 4. An Application Scenario of JSPs [9] In the implementation of the web site, JSP files are responsible for determining the client’s request, then either modify the current page, or redirect the request to another JSP page, or update server-side objects, i.e. update tables in the database. As an example of using JSP to perform these tasks, the following pieces of students.jsp code is given to demonstrate the way of accessing data from the back-end tables and using the data to present a response to the client. <% if ( request.getParameter("schedule2Submitted") != null ) { try { System.setProperty("jdbc.drivers", "oracle.jdbc.driver.OracleDriver"); String url = "jdbc:oracle:thin:@sirah.csit.fsu.edu:1521:oralin"; Connection conn = DriverManager.getConnection(url, "yilewang", "yilewang"); Statement stat = conn.createStatement(); ResultSet rs = stat.executeQuery("select NAME, EMAIL, PHONE, PIN from STUDENTS where ID=" + Integer.parseInt(request.getParameter("id")) ); while (rs.next()) { String info[]={rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4)}; ((Vector)session.getAttribute("students")).addElement(info); } stat.executeUpdate("delete STUDENTS where ID=" + Integer.parseInt(request.getParameter("id")) ); conn.close(); } 11 catch (SQLException e) { response.sendError(HttpServletResponse.SC_OK, "SQL error: " + e.getMessage()) ; } } …… if ( request.getParameter("action").equals("Update Student List") ) { String [] delete = request.getParameterValues("delete"); if ( delete != null ) { for( int i=0; i<delete.length; i++ ) ((Vector)session.getAttribute("students")).remove(Integer.parseInt(delete[i])); } } else if ( request.getParameter("action").equals("Add") ) { if ( request.getParameter("name").equals("") ) { %> <tr><td colspan=2 align="center"><font color="red"> You must enter a name. Please try again.</font></td></tr> <% } …… } } %> …… <tr><td colspan=2 bgcolor="#009999"><font color="white"><b> &nbsp;Current Student List</b></font></td></tr> <tr><td colspan=2> <table width=100% border=0 cellpadding=3 cellspacing=3> <tr align=left><th>Name</th><th>Email</th><th>Phone</th><th><center>Remove</th></tr> <% for (int i=0; i< ((Vector)session.getAttribute("students")).size(); i++) { String info[] = (String [])((Vector)session.getAttribute("students")).get(i); String name = info[0]; String email = info[1]; String phone = info[2]; out.println("<tr><td>" + name + "</td><td>" + email + "</td><td>" + phone + "</td><td align=center><input type=checkbox name=delete value=" + i + "></td></tr>"); } %> The first part of the above code accesses the database to retrieve student information from a table, and saves it into the current session object for a later use. The remaining part updates the student list based on the client’s request: Add/Remove. The following picture is the screen rendered by this code. 12 Figure 5. The web page created by students.jsp 3.1.2 Database Design Once the user creates a new account, his personal information will be stored in table TEACHERS. The schema is as follows. The email address is used for the primary key, thus must be different from others. Field Name Data Type Null? EMAIL ( primary key ) Varchar Not Null NAME Varchar Not Null PASSWORD Varchar Not Null PHONE Varchar Table 1. Schema of table TEACHERS 13 When the user clicks button “Schedule” to confirm scheduling a class, all class information is saved in table CLASSES. This table includes a field EMAIL serving as a foreign key in reference of that of an instructor, in order to ensure every class is bound to one instructor. Meanwhile, the contact information of students who has been added to this class is stored in table STUDENTS. The automatically generated random PIN number is used as a primary key of this table. Foreign key ID is used to specify to which class this student belong. Those schemas are as follows: Field Name Data Type Null? ID ( primary key ) Number Not Null EMAIL ( foreign key references TEACHERS (EMAIL) ) Varchar Not Null SUBJECT Varchar TIME Varchar LENGTH Varchar DESCRIPTION Varchar Table 2. Schema of table CLASSES Field Name Data Type Null? PIN ( primary key ) Char(7) Not Null ID ( foreign key references CLASSES (ID) ) Number Not Null EMAIL Varchar NAME Varchar PHONE Varchar Table 3. Schema of table STUDENTS 3.2 Classroom Part Implementation 3.2.1 More JSPs and Tables 14 In order to build the real-time classroom, it is necessary to write some other JSP, HTML files and two more tables are required. As you can see from figure 2., the classroom page is generated by file class.jsp, which consists of six frames. The corresponding files are shown in the following table. Frame JSP, HTML File Name Left Menu menu.jsp Right Menu menu2.jsp Left Co-browser Panel browser.html Voice Room Panel beforeTalk.jsp, talk.jsp Chat Room Panel beforeChat.jsp, chat.jsp Shared Documents Panel document.jsp Figure 6. JSP and HTML files for Classroom There is a “Start Class” button on the right menu to start up two remote servers: SoundSer and RmiServer. These two new processes are created from menu2.jsp. The following piece of code excerpted from menu2.jsp is to launch server SoundSer. The first line specifies a working directory. The next line executes the specified string command “java SoundSer” in a separate process with the specified environment, which is null, and working directory. File dir = new File("../webapps/learning/talk/"); Process talk = Runtime.getRuntime().exec("java SoundSer", null, dir); Whenever a new class is successfully started, its class ID must be inserted into table CLASSROOMS for reference. Field Name Data Type Null? ID ( primary key, foreign key references CLASSES (ID) ) Number Not Null Table 4. Schema of table CLASSROOMS Talk.jsp and chat.jsp respectively load a talk applet and a chat applet. Document.jsp is used to upload files, and later display them in the left co-browser panel. It includes a form as well as a JavaScript. The JavaScript function openWin(), when “Upload” button clicked, opens a new window for file uploading. File uploading is processed by servlet LoadFile.class. It takes advantage of multipart/form-data type of 15 the form encryption for transferring files, and save them under certain directory at the server side. Another table FILES is needed for keeping track of which file belongs to which class. So class ID is associated with each file in this table. The following is its schema. Field Name Data Type Null? LOCATION ( primary key ) Varchar Not Null FILENAME Varchar Not Null ID ( foreign key references CLASSES (ID) ) Number Not Null Table 5. Schema of table FILES 3.2.2 Voice Room This voice room is build with loaded applets at the client side, SoundStudent.class for students, SoundTeacher.class for the teacher, a server SoundSer.class running at the back-end responsible for receiving audio from the teacher and broadcasting it out to every students. 3.2.2.1 Java Sound API Version 1.3 of the JavaTM 2 Platform includes a powerful new API for capturing, processing, and playing back audio and MIDI (Musical Instrument Digital Interface) data. The JavaTM Sound API is a low-level API for effecting and controlling the input and output of sound media. Within our component, package javax.sound.sampled, which specifies interfaces for capture, mixing, and playback of digital (sampled) audio, is applied. Mixer and Line Many APIs for sound make use of the notion of an audio device. A device is often a software interface to a physical input/output device. In the Java Sound API, devices are represented by Mixer objects. The purpose of a mixer is to handle one or more streams of audio input and one or more streams of audio output. A line is an element of the digital audio "pipeline"-that is, a path for moving audio into or out of the system. Usually the line is a path into or out of a mixer (although technically the mixer itself is also a kind of line). The following diagram shows different types of lines in a simple audio-output system that could be part of an implementation of the Java Sound API: 16 Figure 7. A Possible Configuration of Lines for Audio Output In this example, an application program has gotten access to some available inputs of an audio-input mixer: one or more clips and source data lines. A clip is a mixer input (a kind of line) into which you can load audio data prior to playback; a source data line is a mixer input that accepts a real-time stream of audio data. The application program preloads audio data from a sound file into the clips. It then pushes other audio data into the source data lines, a buffer at a time. The mixer reads data from all these lines, each of which may have its own reverberation, gain, and pan controls, and mixes the dry audio signals with the wet (reverberated) mix. The mixer delivers its final output to one or more output ports, such as a speaker, a headphone jack, and a line-out jack. A simple audio-input system might be similar: Figure 8. A Possible Configuration of Lines for Audio Input Here, data flows into the mixer from one or more input ports, commonly the microphone or the line-in jack. Gain and pan are applied, and the mixer delivers the captured data to an application program via the mixer's target data line. Accessing Audio System Resources Before one can use the resources, the first thing is always gaining access to those available audio components on the computer. My program only needs a certain kind of line; the details of the mixer don't matter. So I use the AudioSystem method: static Line getLine(Line.Info info) to get a line directly from the audioSystem. The following is a snapshot cut from SoundStudent.java as an example to demonstrate the way of getting a source data line. First, it constructs a data line's info object from a specified audio format. Then, if the system supports a line that matches the specified Line.Info object, it goes on getting it, and finally opens it. 17 AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, rate, sampleSize, 1, sampleSize/8, rate, true); DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); if (!AudioSystem.isLineSupported(info)) { System.err.println("Line matching " + info + " not supported."); return; } try { srcLine = (SourceDataLine) AudioSystem.getLine(info); srcLine.open(format, bufSize); } catch (LineUnavailableException ex) { System.err.println("Unable to open the line: " + ex); return; } Playing Back Audio Playback is sometimes referred to as presentation or rendering. The essential feature is that a sequence of data is delivered somewhere for eventual perception by a user. On the student’s end, sound needs to be captured from the network socket, and played back through a headphone or a speaker. Here's an example of iterating through chunks of data that are read from a stream, writing one chunk at a time to the SourceDataLine for playback, which is also taken from SoundStudent.java. the drain() method of DataLine is invoked after writing the last buffer's worth of data. This method blocks until all the data has been played. When control returns to the program, the line is freed up. byte[] data = new byte[srcLine.getBufferSize()/5]; int numBytesRead; try { while ( (numBytesRead = in.read(data, 0, data.length)) != -1) { srcLine.write(data, 0, numBytesRead); if (StdPanel.stopped) out.println("bye"); } } catch (Exception e) { System.err.println("Error during playback: " + e); } srcLine.drain(); srcLine.stop(); srcLine.close(); srcLine = null; 18 Capturing Audio Capturing refers to the process of obtaining a signal from outside the computer. A common application of audio capture is recording, which is done at the instructor side. The procedure is quite similar to that of playing back, except that the read() method is invoked within a loop, until the instructor stops the speech, as in this example taken out of SoundTeacher.java: data = new byte[tgtLine.getBufferSize() / 5]; try { while (!TchPanel.stopped) { numBytesRead = tgtLine.read(data, 0, data.length); out.write(data, 0, numBytesRead); out.flush(); } out.flush(); out.close(); } catch (Exception e) { System.err.println("Error during recording: " + e); } tgtLine.stop(); tgtLine.close(); tgtLine = null; 3.2.2.2 Server SoundSer SoundSer is a multi-thread concurrent server that continues listening to the port, ready to accept connection requests from any teacher or student. If a student tries to connect the server, it adds this student if there's still a vacancy. The server is supposed to serve up to 100 students. All connecting students’ sockets are kept in a hashtable for later reference. When a teacher tries to connect the server, the main process starts a new thread “Transfer”. This thread performs a task of continuously retrieving sound from the teacher and broadcasting it to every student by executing a loop until the teacher clicks “Stop” button to end speaking. Within this loop, for every connecting student in the hashtable, the program first checks if he wants to stop listening. If so, it disconnects the student’s socket and removes it from the hashtable, otherwise sends sound through his socket. 3.2.3 Chat Room 19 The chat room is also a client/server based application that uses RMI to form its network connection. The Remote Interface: RmiChat This interface declares two methods that both client and server need to be awared of through RMI. One is getMessages() which is to get every string from a Message vector; the other is addMessage() which adds a new string into this vector. The Remote Class Implementation: RmiChatImpl This class implements those two methods in RmiChat interface. Server: RmiServer The server creates an internal Registry, creates an object of RmiChatImpl class, and binds this object with the input port number:16666 in that registry. It also sets the codebase as http://sirah.csit.fsu.edu:8270/learning/chat/ for dynamic class loading, which allows the client Java Virtual Machine transparently downloads the byte codes of stub class files from a web server. Client: ChatClient The client is a class extending JApplet. In the method init(), it calls getcontentpane() to load a GUI. When this JPanel starts to be constructed, it first creates a remote object by looking up the remote registry specified by "rmi://sirah.csit.fsu.edu:1666/chatservice", then starts a new thread. This thread repeatedly calls the remote method getMessages() to update the output text area every one second. When the user inputs a sentence at the bottom text field, and hits “Enter” kdy, it calls the remote method addMessage() to add this string into the Message vector. 20 4 Deployment After I finish coding, it is still necessary to set up a web server and deploy the files onto the server. This chapter introduces the server used in this project as well as the deployment process. 4.1 Web Server Standard Web Servers typically need some additional software to allow them to run servlets and JSPs. Tomcat is the official Reference Implementation for the Java Servlet and JavaServer Pages technologies. It can stand alone or be integrated into the Apache Web server. For debugging of servlets and JSPs, it seems necessary to use a stand-alone server, dedicated to the project I am developing. For this reason, I installed my own Tomcat server on machine Sirah.csit.fsu.edu at port 8270. 4.2 Deployment Process JSP and HTML Files All JSP and HTML files should be deployed under the directory: $TOMCAT_HOME/webapps/learning/ Servlets Sevlets and other associated Java files need to be compiled at first, and then be deployed under the directory: $TOMCAT_HOME/webapps/yilei/WEB-INF/classes/ RMI Compile RmiChat.java, RmiChatImpl.java, RmiServer.java, and ChatClient.java: >javac *.java >rmic RmiChatImpl Place the stub and skeleton classes created by rmic command on the web site http://sirah.csit.fsu.edu:8270/learning/chat/ as annotated with code-base. Place RmiServer under $TOMCAT_HOME/webapps/learning/chat/ for menu2.jsp to start. Place ChatClient under $TOMCAT_HOME/webapps/learning/chat/ too for chat.jsp to load this applet. Shared Files Create folder “files” under path $TOMCAT_HOME/webapps/learning/ in order to store all the uploaded documents. Voice Application Compile SoundSer.java, SoundTeacher.java, and SoundStudent.java, and put them under $TOMCAT_HOME/webapps/learning/talk/. Security file “applet.policy” needs to placed in the same directory, because clients will be asked to adopt this file through the net. 21 4.3 Access Online Classroom Installation JavaTM 2 Runtime Environment v 1.3 or JavaTM 2 Platform, Standard Edition v1.3 JavaTM Plug-in Modify Security File Append a line: Policy.url.3 = http://sirah.csit.fsu.edu:8270/learning/talk/applet.policy to file: C:/Program Files/JavaSoft/jre/lib/scurity/java.security Visit the Website Launch a web browser, type URL: http://sirah.csit.fsu.edu:8270/learning/, which leads you directly to the home page of Online Real-time Classroom. 22 5 Conclusions This is an initial attempt to design and build on online real-time classroom from the perspective of a real world project, with a bunch of popular Java technologies adopted. Through this project, I was exposed to as many enterprise Java technologies, and learned to choose the right ones for the job, combine and apply them appropriately. However, this is only a two-tier application. I considered using Enterprise JavaBeans, but gave up due to short of familiarity. It would have made a great way to encapsulate business rules and processes, and provide standard services that enterprise applications require. This is the future work that might need to be done for my project. 23 References [1] Core Java 2, by Cay S. Horstmann and Gary Cornell, Sun Microsystems Press, 1999 [2] Developing Java Enterprise Applications, by Stephen Asbury and Scott R. Weiner, Wiley, 1999 [3] Notes of course “Information Technology I, II”, by Geoffrey Fox and Bryan Carpenter, 2000 [4] http://java.sun.com/j2se/1.3/docs/guide/sound [5] Core Servlets and Java Server Pages, by Marty Hall, Prentice Hall, 2000 [6] JSP specification, Sun Microsystems Press, 1999 [7] JavaScript Bible, 4th Edition, by Danny Goodman, Hungry Minds, 2001 [8] Java RMI, by Troy Bryan Downing, IDG books, 1998 [9] http://www.onlineclass.com 24 ACKNOWLEDGEMENTS First of all, I want to thank Dr. van Engelen for his guidance. I also appreciate the support and encouragement from my committee members: Dr. Schwartz and Dr. Levitz. Finally I would like to thank my friends, especially Xi Rao for kind assistance. 25