Copy Link
Add to Bookmark
Report

Java Newsletter by Glen McCluskey - Issue 12

eZine's profile picture
Published in 
Java Newsletter
 · 2 years ago

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 <applet> and </applet>.

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:

        <html> 
<body>

<a href="link1.html">Link #1</a>
<br>
<a href="link2.html">Link #2</a>
<br>

<script>

<!--

function doit()
{
document.write("<br>This page's links are:<br><br>");
for (var i = 0; i < document.links.length; i++) {
var s = "";
s += (i + 1) + ". ";
s += document.links[i];
s += "<br>";
document.write(s);
}
}

doit()

<!-- -->

</script>

</body>
<html>


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 "<br>" 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:

        <html> 

<head>
<title>Client Applet</title>
</head>

<body>

<applet code="client.class" width=300 height=300></applet>

</body>

</html>


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

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT