Applets are considered to be untrusted code, and as such they are subject to tight security restrictions that limit their access to system resources. You can assume that an applet will not have access to the local file system and will not be able to open, read, write, or access files or directories in any way. Additionally, an applet cannot initiate a network connection to or from any computer other than the one from which it was loaded. Figure 21-7 illustrates this point.
Figure 21-7: An Applet Can Only Connect To The Server From Which It Was Served
Referring to figure 21-7 — The applet executes in a restricted environment on the client machine and can only receive or initiate network connections to the server. However, the server can act as a proxy and communicate with other internet hosts on the applet’s behalf.
Any attempt to connect to the applet from a computer other than its serving host will result in an AccessControlException. To demonstrate this point examples 21.3 through 21.6 implement an applet named AppletServer that mimics the functionality of the SimpleServer program originally given in chapter 20.
Example 21.3: AppletServer.java
1 import java.applet.*; 2 import javax.swing.*; 3 4 public class AppletServer extends JApplet { 5 6 JTextArea _textarea = null; 7 JScrollPane _scrollpane = null; 8 ServerThread _st = null; 9 10 public void init(){ 11 _textarea = new JTextArea(10, 20); 12 _scrollpane = new JScrollPane(_textarea); 13 this.getContentPane().add(_scrollpane); 14 System.out.println("AppletServer init() method called..."); 15 } 16 17 public void start(){ 18 _st = new ServerThread(_textarea); 19 _st.start(); 20 System.out.println("AppletServer start() method called..."); 21 } 22 } // end AppletServer class definition
Example 21.4: ServerThread.java
1 import java.io.*; 2 import java.net.*; 3 import javax.swing.*; 4 import java.security.*; 5 6 public class ServerThread extends Thread { 7 8 private ServerSocket _server_socket = null; 9 private JTextArea_textarea = null; 10 11 public ServerThread(JTextArea text_area){ 12 _textarea = text_area; 13 try{ 14 _server_socket = new ServerSocket(5001); 15 }catch(Exception e){ 16 e.printStackTrace(); 17 } 18 }// end constructor 19 20 public void run(){ 21 while(true){ 22 try{ 23 Socket socket = _server_socket.accept(); 24 ClientProcessorThread cpt = new ClientProcessorThread(socket, _textarea); 25 cpt.start(); 26 }catch(AccessControlException ace){ 27 _textarea.append("Unauthorized network access detected.\n"); 28 } 29 catch(Exception e){ 30 e.printStackTrace(); 31 } 32 }//end while 33 }// end run() method 34 }// end class definition
Example 21.5: ClientProcessorThread.java
1 import java.io.*; 2 import java.net.*; 3 import javax.swing.*; 4 5 public class ClientProcessorThread extends Thread { 6 7 private Socket _socket = null; 8 private DataInputStream _dis = null; 9 private DataOutputStream _dos = null; 10 private JTextArea _textarea = null; 11 12 public ClientProcessorThread(Socket socket, JTextArea text_area){ 13 _socket = socket; 14 _textarea = text_area; 15 try{ 16 _dos = new DataOutputStream(_socket.getOutputStream()); 17 _dis = new DataInputStream(_socket.getInputStream()); 18 }catch(Exception e){ 19 e.printStackTrace(); 20 } 21 } // end constructor 22 23 public void run(){ 24 try{ 25 String s = null; 26 while((s=_dis.readUTF()) != null){ 27 System.out.println(s); 28 _dos.writeUTF(s); 29 _textarea.append(s + '\n'); 30 } 31 }catch(Exception e){ 32 e.printStackTrace(); 33 } 34 finally{ 35 try{ 36 _socket.close(); 37 _dis.close(); 38 _dos.close(); 39 }catch(Exception ignored){ } 40 } 41 } // end run() method 42 } // end ClientProcessorThread class definition
Example 21.6: appletserver.html
1 <html> 2 <applet code="AppletServer.class" height=200 width=300 > 3 </html>
Referring to examples 21.3 through 21.6 — the AppletServer program implements a simple multi-threaded server that reads a line of UTF text, appends it to a JTextArea, and echos it back to the client program. It does this with the help of two thread classes: ServerThread and ClientProcessorThread.
The AppletServer class implements two of the four applet life-cycle methods: init() and start(). The init() method initializes the AppletServer GUI components and the start() method kicks off an instance of ServerThread on lines 18 and 19 of example 21.3.
Referring to example 21.4 — the ServerThread class is responsible for listening for incoming client connections and passing the resulting Socket object to an instance of ClientProcessorThread. The ServerThread class constructor takes a reference to a JTextArea and eventually passes the reference on to the ClientProcessorThread constructor on line 24. Attempts to connect to AppletServer from hosts other than its server will result in an AccessControlException. This exception is thrown by the ServerSocket.accept() method and handled in the catch clause on line 26.
Referring to example 21.5 — the ClientProcessorThread takes the Socket and JTextArea references as arguments to its constructor. The purpose of this class is to write client messages to the applet’s JTextArea and echo them back to the client until the client disconnects or until the applet shuts down.
Example 21.6 gives the HTML code for a simple web page that hosts the AppletServer applet. Figure 21-8 shows the AppletServer applet running in a web browser and being accessed with the SimpleClient application originally presented in chapter 20.
Figure 21-8: AppletServer Applet Running In A Browser And Being Accessed By The SimpleClient Application
So long as the SimpleClient application is run on the same computer from which the AppletServer applet was served it can connect and interact with the AppletServer applet as expected. However, any attempt to connect to AppletServer from a computer other than its server has the results shown in figure 21-9.
Figure 21-9: Results of Attempting to Connect to AppletServer from a Computer Other Than its Server
In addition to file system and network access restrictions placed on untrusted applet code, applets are limited in the following ways:
They cannot listen on network ports less than or equal to 1024
They cannot register or create a URLStreamHandlerFactory, ContentHandlerFactory, or SocketImplFactory
They cannot call System.exit() or Runtime.exit()
They cannot call Runtime.exec() methods
They cannot dynamically load library modules using the System or Runtime classes’ load() or loadLibrary() methods
Swing windows created by applets have a warning at the bottom
They can’t print, access the clipboard, or access the system event queue
They have restricted access to certain system properties
They cannot create or access external threads or thread groups
They are limited in their ability to load classes
They are limited in their ability to use reflection
Having presented the general case I should point out that applets execute in an environment defined by the web browser. By manipulating web browser security policies and using signed applets these security restrictions can be significantly relaxed. Further research regarding security policies and signed applets is left to you as an exercise.
Applets run in a restricted environment and are considered to be untrusted code. An applet cannot, as a rule, access the local file system or initiate or receive network connections to any computer other than the one from which it was served.