Issue #012
December, 1996
Contents:
Jack
Comparing C/C++ and Java Part 12 - Null
JavaScript
Introduction to Applet Programming Part 8 - Client/Server Example
Correction
JACK
Lex and Yacc are widely-used tools for doing lexical scanning and
parsing of input. You describe the structure of the input and these
tools generate programs (in C) that will accept and structure such
input. For example, an identifier might be lexically described as:
[a-zA-Z_][a-zA-Z_0-9]*
meaning that the identifier starts with a letter or underscore,
followed by zero or more letters, underscores, or digits.
Similarly, a simple expression in BNF (Backus Naur Form) could look
like:
E -> T | E + T
T -> F | T * F
F -> number | ( E )
This is known as a grammar, and programming languages like Java are
formally described via a grammar. O'Reilly and others publish books
on Lex/Yacc, if you want information on these tools.
Jack is a new tool that combines Lex and Yacc capabilities. It's
written in Java and produces Java output, that is, produces Java
programs for parsing input described via a grammar. Jack is available
on the Web at:
http://www.suntest.com/Jack
You need the Java Development Kit 1.0.2 to use this program. With
Jack you describe the lexical and syntactic structure of your program,
and then have it produce Java programs that understand this structure.
As an example of a problem made simple by a tool of this type,
consider the issue of extracting from Java programs basic information
about what is defined where, for example, where a specific class or
method is found in the source code. With Jack, it's simply a matter
of dumping out key information whenever a particular construct like a
method declaration is found.
For example, we might have this format for the output:
String.charAt method 204 java/src/java/lang/String.java
meaning that the charAt() method of class String is defined at line
204 of String.java.
An index produced in this format, representing all the classes,
interfaces, methods, and constructors for JDK 1.0.2, is available via
FTP at:
ftp://rmi.net/pub2/glenm/jack
along with a simple UNIX shell script browser to search and access any
of the symbols in the database.
There are many other possibilities for the use of a tool of this type,
for example test coverage or generation of class metrics. If you have
interest in this area, please send me a note (glenm@glenmccl.com).
COMPARING C/C++ AND JAVA PART 12 - NULL
In C and C++, "NULL" is a constant defined in a header file, with a
value like:
0
or:
0L
or:
((void*)0)
depending on the compiler and memory model options. NULL is not,
strictly speaking, part of C/C++ itself.
In Java, "null" is not a keyword, but a special literal of the null
type. It can be cast to any reference type, but not to any primitive
type such as int or boolean. The null literal doesn't necessarily have
value zero. And it is impossible to cast to the null type or declare a
variable of this type.
JAVASCRIPT
You may have heard the term "JavaScript". What is its relation to
Java and HTML? JavaScript started out as LiveScript and its
connection to Java is fairly loose, sharing some Internet heritage but
not that much else.
HTML (Hyper Text Markup Language) is not really a programming language
in the usual sense of the term, but rather a language that describes
what a page ought to look like. You can't really "do anything" with
HTML.
Java is a general purpose programming language. One type of Java
program, an applet, is downloadable by a Web browser and then executed
locally by the browser. This is useful, for example, in communicating
with remote databases. An applet's invocation is described via the
HTML tags .
JavaScript can be viewed as a language something like Perl, or as an
extension of HTML to allow customized functionality. As an example of
what a JavaScript application would look like, consider this example:
Link #1
Link #2
This particular application iterates over the links in a page and
displays them in a numbered list:
1. link1.html
2. link2.html
JavaScript as a programming language has a flavor something like Perl
or Awk, with weak typing and domain-specific system variables like
"document.links[]".
Note that the output of a JavaScript script is HTML, so for example we
use "
" instead of "\n" to go to the next line. In the above
example, the function doit() is defined, and then called to produce
HTML.
We will probably not say more about JavaScript, but there are a
variety of books available on the topic. You need a Web browser like
Netscape 3.0 to execute JavaScript programs.
INTRODUCTION TO APPLET PROGRAMMING PART 8 - CLIENT/SERVER EXAMPLE
In this issue we'll show a simple example of client/server
programming. The client will be an applet and the server a regular
Java program with a main() method in it.
In the client/server model, there is a server program running on some
computer. It accepts connections from clients across the network, and
serves each of them. For example, the client may be used to accept
some input from a user, which is sent to the server and entered into a
database. The server can also send information back to the client,
such as an acknowledgment.
Server and client communicate via what is known as a socket. More
technically, a socket is an endpoint of a communications channel, and
thus there is a socket on each end of the channel, one socket for the
server and one for the client.
Given a socket, it's possible to do conventional Java I/O between
server and client.
Let's now look at the programs:
// server.java
import java.io.*;
import java.net.*;
public class server extends Thread {
public static final int DEF_PORT = 1234;// port
private int port;
private ServerSocket listen; // server socket
public server()
{
// set up the server socket port
port = DEF_PORT;
try {
listen = new ServerSocket(port);
}
catch (IOException e) {
System.err.println("socket creation error");
System.exit(1);
}
// start the server thread running
start();
}
public void run()
{
try {
// accept connections and process them
for (;;) {
Socket cs = listen.accept();
connection c = new connection(cs);
}
}
catch (IOException e) {
System.err.println("connection error");
}
}
public static void main(String[] args)
{
new server();
}
}
class connection extends Thread {
private Socket client; // client socket
private DataInputStream in; // input from socket
private PrintStream out; // output to socket
public connection(Socket cs)
{
// set up an individual connection
try {
client = cs;
InputStream is = client.getInputStream();
in = new DataInputStream(is);
OutputStream os = client.getOutputStream();
out = new PrintStream(os);
}
catch (IOException e) {
try {
client.close();
}
catch (IOException ee) {
System.err.println("close error");
}
System.err.println("socket stream error");
return;
}
// start it running
start();
}
public void run()
{
// read from socket input and write back to output
try {
for (;;) {
String ln = in.readLine();
if (ln == null)
break;
if (ln.length() == 0)
out.println("empty input");
else
out.println("OK: " + ln);
}
}
catch (IOException e) {
System.err.println("server I/O error");
}
// close connection
finally {
try {
client.close();
}
catch (IOException ee) {
System.err.println("close error");
}
}
}
}
// client.java
import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
public class client extends Applet {
public static final int DEF_PORT = 1234;// port
Socket s; // socket
DataInputStream in; // socket input
private PrintStream out; // socket output
TextField input_field; // input field
TextArea out_area; // output display area
public void init()
{
try {
// set up socket
String host = getCodeBase().getHost();
s = new Socket(host, DEF_PORT);
in = new DataInputStream(s.getInputStream());
out = new PrintStream(s.getOutputStream());
// set up window
input_field = new TextField();
out_area = new TextArea();
out_area.setEditable(false);
setLayout(new BorderLayout());
add("North", input_field);
add("Center", out_area);
}
catch (IOException e) {
System.err.println("exception during setup");
}
}
public boolean action(Event e, Object o)
{
if (e.target == input_field) {
// we have some input from the user
try {
// dump it to the server
out.println((String)e.arg);
input_field.setText("");
// read response
String status = in.readLine();
out_area.setText(status);
return true;
}
catch (IOException ee) {
out_area.setText("server I/O error");
}
}
return false;
}
}
The server is compiled as usual and simply started as a Java program:
$ java server
while the client is driven via some HTML:
Client Applet
If you start the client without the server being present, it will give
an error because of failure to connect to the server.
This particular server/client combination simply validates input from
the client and sends back an acknowledgment. Each client connection
runs as a separate thread, so that many clients can be served
simultaneously without the need for polling.
Note that the server knows to close a given client connection (the
client has gone away) by receipt of a "null" when reading input from
that connection. By contrast, the server "never" goes away; it must
be explicitly terminated by the user.
Note also that the socket port must be unique on the system running
the server, and that the server and client must agree on port
assignments.
CORRECTION
In issue #011 we presented an example of animation. Steve Drach
pointed out that a call to dispose() is needed, as follows:
// run a thread
public void run()
{
for (;;) {
// get graphics for the applet window
Graphics g = this.getGraphics();
try {
switch (st++) {
case 0:
g.setColor(Color.red);
g.fillOval(25, 35, 250, 250);
break;
// other switch cases ...
}
// sleep for a second
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
g.dispose(); // <<<<<<<<<<<<<<<<<<<<
}
}
Without this, the animation will eventually stall out. This is
different from garbage collection, which is automatic, and involves
freeing of windows resources. That is, getGraphics() retrieves one of
a limited number of system window resources, which must be returned
via dispose(). A similar case might come up when dealing with a
resource such as UNIX file descriptors.
ACKNOWLEDGEMENTS
Thanks to Jay Burgess, Thierry Ciot, Irv Kanode, Mike McCann, Mike
Paluka, Srihari Sampathkumar, and Bob Shore for help with proofreading.
SUBSCRIPTION INFORMATION / BACK ISSUES
To subscribe to the newsletter, send mail to majordomo@world.std.com
with this line as its message body:
subscribe java_letter
Back issues are available via FTP from:
rmi.net /pub2/glenm/javalett
or on the Web at:
http://rainbow.rmi.net/~glenm
There is also a C++ newsletter. To subscribe to it, say:
subscribe c_plus_plus
using the same majordomo@world.std.com address.
-------------------------
Copyright (c) 1996 Glen McCluskey. All Rights Reserved.
This newsletter may be further distributed provided that it is copied
in its entirety, including the newsletter number at the top and the
copyright and contact information at the bottom.
Glen McCluskey & Associates
Professional Computer Consulting
Internet: glenm@glenmccl.com
Phone: (800) 722-1613 or (970) 490-2462
Fax: (970) 490-2463
FTP: rmi.net /pub2/glenm/javalett (for back issues)
Web: http://rainbow.rmi.net/~glenm