Day 3 Summary

Back Up Next

 

java.io

What's in the java.io package?
I/O Stream classes to read and write Strings, byte/char arrays, and other Java primitive data types
Platform independent support of files, directories, and handles to either open file or socket
Serialization/Deserialization of Objects
I/O related Exceptions
Streams
An ordered sequence of data that have either a source (input stream) or destination (output stream)
Like C++'s cin and cout
Picture
Most I/O Stream classes in java.io do little more than read or write data in a particular manner (such as "I only read/write chars" or "I only read/write byte arrays" or "I buffer whatever bytes I read/write"), and they can be plugged together
Example

IOTest.java

import java.io.*;

public class IOTest {
	public static void main(String[] args) {
		try {
			File testFile = new File("C:\\DATA\\TEMP\\TestFile.txt");
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			FileWriter fw = new FileWriter(testFile);
			FileInputStream fis = new FileInputStream(testFile);
			DataOutputStream dos;

			String returnedLine = br.readLine();	//read a line from the console
			fw.write(returnedLine);			//write whatever was read into testFile
			fw.flush();
			fw.close();

			int ch;
			while ((ch = fis.read()) != -1)	//read in from file what we just wrote
				System.out.print((char)ch);

			fis.close();

			dos = new DataOutputStream(new FileOutputStream(testFile));
			dos.writeBoolean(true);			//write "true" to the file			dos.close();
		} catch (FileNotFoundException e) {
			System.out.println("File not found");
		} catch (IOException ee) {
			//consume IOExceptions for now
		}
	}
}
InputStreams, OutputStreams, Readers and Writers
What's the difference between the Input/Output Streams and Readers/Writers?
Input/Output Streams use bytes (8bits) as data (and its limitations)
Readers/Writers use chars (16bits) as data (which supports Unicode)
Thus, Readers and Writers are foreign-language-friendly and is an important internationalization feature in Java 1.1 and later
Use InputStreamReader and OutputStreamWriter to convert from Streams to Reader/Writer
This is the preferred way for conversions - these two classes handle the translation from bytes into Unicode characters according to the particular platform and locale dependent character encoding
Common I/O classes
BufferedReader/Writer and Buffered[Input, Output]Stream - buffer data to improve efficiency
FileReader/Writer and File[Input, Output]Stream - read/write to files
Object[Input, Output]Stream - (de)serialize objects from/to streams
Files and FileDescriptors
FileDescriptors are representations of low-level file-handles and sockets.  You cannot "create" your own FileDescriptor and have it make sense.  Useful for socket and low-level IO programming via JNI to communicate with C code.
Files enable you to do a whole host of actions on the local file system (those that security permit you to), including:
Creating, deleting, renaming files and creating temporary (uniquely named) files
Testing for file existence and reading its length
Reading and setting file/directory attributes such as readable, writable, hidden and modification time
Getting the absolute, relative, and canonical (system dependent) file path/name
Listing and creating directories
Serialization
An "automatic" way to save and restore Java Objects and primitive data types
Serialization saves fields that are non-transient, non-static, and non-private
Objects are read with the readobject method and written with the writeObject method
Primitives are read with the methods of DataInput and written with the methods of DataOutput
//
// Serialize today's date to a file.
//
FileOutputStream fos = new FileOutputStream("C:\\DATA\\TEMP\\TODAY.OBJ");
ObjectOutput oo = new ObjectOutputStream(fos);
oo.writeObject("Today");
oo.writeObject(new Date());
oo.flush();
//
// Deserialize a string and date from a file.
//
FileInputStream fis = new FileInputStream("C:\\DATA\\TEMP\\TODAY.OBJ");
ObjectInputStream ois = new ObjectInputStream(fis);
String today = (String)ois.readObject();
Date date = (Date)ois.readObject();
Caveat: Only Objects that implement the Serializable and Externalizable interfaces can be (de)serialized.
Additional caveats include: Can't serialize inner classes
Cool things Serialization enable: sending Java Objects perfectly to remote machines via the network
Full details at http://web2.java.sun.com/products/jdk/1.3/docs/guide/serialization/spec/serialTOC.doc.html

java.net

What's in the java.net package?
Classes that retrieve objects named by URLs
Classes that allow  UDP-Datagram/TCP-Streaming socket programming
Miscellaneous classes that allow DNS queries, URL encoding/decoding, and Socket options
Lots of other protected classes that should not be messed with

java.net significantly simplifies network programming and allows anyone to communicate/send/receive data with a small amount of code.

Networking Basics

With Java, you're mostly programming in the Application Layer.  This means that you don't have to know the details about how the lower levels work (such as TCP or UDP sockets) - Java has taken care of that for you in an architecture neutral way.

However, for those that want to network a bit lower using sockets, you need to understand TCP and UDP.

For Java's purpose, a host is uniquely identified by a hostname/IP and port.

URLs and URLConnections
URL
The easiest way to retrieve objects named by URLs.

URLRead.java

import java.net.*;
import java.io.*;

public class URLRead {
	public static void main(String[] args) {
		try {
			URL url = new URL(args[0]);
			BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
			StringBuffer buf = new StringBuffer();

			while (br.ready())
				buf.append(br.readLine() + "\r\n");

			br.close();
			System.out.println(buf.toString() + "\n" + buf.length() + " bytes read");
		} catch (MalformedURLException e) {
			System.out.println("Bad URL");
		} catch (IOException ee) {
			System.out.println("Read Error");
		}
	}
}
URLConnection
When you need to do more than retrieve URL named objects, such as send data to an remote cgi script
HttpURLConnection - special version of URLConnection that only does HTTP connections

Reverse.java

import java.io.*;
import java.net.*;

public class Reverse {
    public static void main(String[] args) throws Exception {

	if (args.length != 1) {
	    System.err.println("Usage:  java Reverse "
                               + "string_to_reverse");
	    System.exit(1);
	}

	String stringToReverse = URLEncoder.encode(args[0]);

	URL url = new URL("http://java.sun.com/cgi-bin/backwards");
	URLConnection connection = url.openConnection();
	connection.setDoOutput(true);

	PrintWriter out = new PrintWriter(connection.getOutputStream());
	out.println("string=" + stringToReverse);
	out.close();

	BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	String inputLine;

	while ((inputLine = in.readLine()) != null)
	    System.out.println(inputLine);

	in.close();
    }
}
UDP and TCP Sockets
Socket / ServerSocket
Useful for Client/Server TCP Socket programming
Usual Steps on the Client
  1. Open a socket
  2. Open an input stream and output stream to the socket
  3. Read from and write to the stream according to the server's protocol
  4. Close the streams
  5. Close the socket
Usual Steps on the Server
  1. Open the server's socket
  2. Open an output stream to the server's socket
  3. Wait for a client to connect
    When successfully connected,  keep track of the returned client socket
    Open an input stream to the client socket
  4. Read from the server's socket and write to the client's socket according to server protocol
  5. When the client disconnects
    Close the client stream and socket
  6. Close the server's stream and socket
DatagramSocket / DatagramPacket
Useful for Client/Server UDP Socket programming
Usual Steps on the Client
  1. Open a DatagramSocket
  2. Send a DatagramPacket to a known server
  3. (optional) receive the server's DatagramPacket response
  4. Close the DatagramSocket
Usual Steps on the Server
  1. Open a DatagramSocket
  2. Wait for a DatagramPacket to be received
  3. Process the contents of the packet and (optionally) respond according to server protocol
  4. (optional) send a DatagramPacket to the sender
  5. Close the DatagramSocket
QuoteServer.java
QuoteServerThread.java
QuoteClient.java
Miscellaneous Networking Utilities
InetAddress
Object representation of an IP address and hostname
Optionally can be used as DNS
SocketOption
URLEncoder
URLDecoder

java.util.jar / java.util.zip

Why use JAR files?
Security: digitally sign the contents of a JAR file. Users who recognize your signature can then optionally grant your software security privileges it wouldn't otherwise have.
Decreased download time: If your applet is bundled in a JAR file, the applet's class files and associated resources can be downloaded to a browser in a single HTTP transaction without the need for opening a new connection for each file.
Compression: The JAR format allows you to compress your files for efficient storage.
Package Sealing: Packages stored in JAR files can be optionally sealed so that the package can enforce version consistency. Sealing a package within a JAR file means that all classes defined in that package must be found in the same JAR file.
Package Versioning: A JAR file can hold data about the files it contains, such as vendor and version information.
Portability: The mechanism for handling JAR files is a standard part of the Java platform's core API.
Common JAR Usage
Operation Command
To create a JAR file jar cf jar-file input-file(s)
To view the contents of a JAR file jar tf jar-file
To extract the contents of a JAR file jar xf jar-file
To extract specific files from a JAR file jar xf jar-file archived-file(s)
To run an application packaged as a JAR file
(version 1.1)
jre -cp app.jar MainClass
To run an application packaged as a JAR file
(version 1.2 -- requires Main-Class
manifest header)
java -jar app.jar
To invoke an applet packaged as a JAR file
<applet code=AppletClassName.class
        archive="JarFileName.jar"
        width=width height=height>
</applet>
Manifests
In many ways, the jar package is a specialized use of the zip package. Thus, it only thinly wraps the zip package
A JAR file is basically a ZIP file with a manifest, which gives JAR files a wide range of functionality
Manifests allow textual descriptions and attributes to be externally associated with class files
Manifests can be used to allow
Electronic signing and version control
Package sealing
Name: myCompany/myPackage/
Sealed: true
Download Extensions
Class-Path: servlet.jar infobus.jar acme/beans.jar
Applications bundled as JAR files
Main-Class: classname

java.security

Evolution of the Java Security Model
JDK 1.0 Model - sandbox

JDK 1.1 Model - trusted, signed applets and sandbox

JDK 1.2 - all code subject to security policy, which defines the permissions on actions
Domains aggregate code with same permissions

Java 1.2 Security Security Model in depth
New Policy/Permissions/Domain concept for security
Cryptographic API
Cryptographic services
Certificate management
Key management
Security related tools
keytool - create public/private key pairs, import/display/export certificates, and generate X.509 v1 self-signed certificates and certificate requests that can be sent to a certification authority
jarsigner - signs and verifies the authenticity of signatures on JAR files
policytool - creates and modifies the policy configuration files that define your installation's security policy
How to control Applets and Applications
Applets - by default, still restricted system access
SecurityManager runs by default
Use policytool to edit the policy file to grant more access
Applications - by default, still unrestricted system access
Must run with SecurityManager in place
java -Djava.security.manager ApplicationClassName
Use policytool to edit the local policy file to control application access

Java VM and Bytecode

What is the Java VM?
The Java virtual machine is an abstract computing machine. Like a real computing machine, it has an instruction set and manipulates various memory areas at run-time
The Java virtual machine knows nothing of the Java programming language, only of a particular binary format, the class file format. A class file contains Java virtual machine instructions (or bytecodes) and a symbol table, as well as other ancillary information
For the sake of security, the Java virtual machine imposes strong format and structural constraints on the code in a class file. However, any language with functionality that can be expressed in terms of a valid class file can be hosted by the Java virtual machine
Java VM Structure
To implement the Java virtual machine correctly, you need only be able to read the class file format and correctly perform the operations specified therein. Implementation details that are not part of the Java virtual machine's specification would unnecessarily constrain the creativity of implementors. For example, the memory layout of run-time data areas, the garbage-collection algorithm used, and any internal optimization of the Java virtual machine instructions (for example, translating them into machine code) are left to the discretion of the implementor
Two data types - primitives and references
"Stack" programming language with random-access memory
Java VM Instruction Set
Opcodes and mnemonics