After I left Sun to pursue fame and fortune by helping to found companies and try to participate in the Internet Bubble, I wrote a column for the online magazine JavaWorld. That column provided me with a forum for discussing some of the finer points of Java with the net readership at large. After my August '98 column I sort of ran out of things to write about. Each month I tried to focus fairly deeply on a particular topic, sometimes that focus runs over the course of a couple of months as in the case with my first series of columns on threads.
As I wrote my columns I made sure to keep copies of the code on my web site. That worked wonderfully until the building my web server was in caught on fire, and I discovered I didn't have a backup. At least not one that I could use to restore the system to where I wanted it to be. So using Brewster Kale's "way back machine" and some Zip disks and a bit of crusty crainial cells, I've reconstructed all of the Javaworld Content on my site.
I've been going through the sources and porting/cleaning them up to bring them up to "current" standards so that they are at least demonstrable under a modern browser or with the Sun JDK. I've tested all the examples under Internet Explorer, as I get a chance to do more testing I'll update this data.
Click here to get back to Chuck's home page.
Originally I had organized this page in reverse order so that newest things were at the top, now it is organized in chronological order. That way lets you get a feel for how the concepts presented in the columns developed over time.
Interestingly to me, a number of these columns also ended up on the Java Developer's CD distributed by Sun.
An introduction to synchronizing threads using the wait() and notify() interfaces in class Object. If you recall 1996 you will remember that "threading" was something that was just coming into vogue for mainstream applications. Now of course you can't turn around without running into a threading package but when Java was released with threading as part of the language specification, you knew you had to understand it. Built in threading and garbage collection were perhaps the two most fundamental features of the language.
This article is a gentle introduction into one way to use threads in Java. At FirstPerson the Java port to Solaris (it started on SunOS 4.x) was running when it could run "HelloWorld.class" but it was really running when it could run HelloHelloHelloWorldWorldWorld (a threaded version of HelloWorld).
The classes used in this article consist of our synchronization class, a user of that class, and a container for both the threads and their owners.
- PingPong.java - This is the class that supports synchronization.
- Player.java - This is an instance of a ping pong player.
- Game.java - This is a program that pits two players against each other.
In this installment the use of multiply synchronized threads, exchanging information on data channels is explored. A simple parallel computer is simulated.
When I wrote this article I was really excited about this idea, nobody else seemed to "get" it :-). Here was a language where you could express algorithms as parallel threads as easily as if you were using a single thread. The cool bit is that languages like VHDL that describe hardware circuits can really optimize the heck out this stuff. BYU has even experimented with JHDL which takes Java's inherent parallelism as a way to express hardware.
- DataChannel.java - This is the basic channel holder for interthread communication.
- DataItem.java - A package private class that provides the rendezvous point for threads.
- DataChannelException.java - The generic exception thrown by the DataChannel classes.
- DataChannelTimeout.java - An exception that indicates the channel is receiving no data.
- DataChannelOverrun.java - An exception that indicates that the channel's queue has overflowed and data has been discarded.
- DataChannelShutdown.java - This exception indicates that the "owner" of the channel has marked it for shutdown.
- Computer.java - This is an example DataChannel client that performs a mathematical operation.
- Quadratic.java - This application class uses Computer classes to compute the value of a quadratic equation.
In this column using the data channels for creating "smart" controls on web pages is discussed. The base architecture for a user interface model where every widget has its own thread is defined. The example uses both HTML and Java to build a very simple application.
The clever bit here is that the example converts Fahrenheit to Celsius (and vice versa) because it is structurally set up to do so. This is similar to those paper converters where the ratio of two circles determines the conversion factor. It also showed an interesting form of threaded user interface where every control on the screen is its own thread doing its own thing. Similar in concept to Rod Brook's subsumption architecture for robots.
- SimpleNumeric.java - A numeric indicator for a web page that uses a DataChannel for receiving information.
- SimpleSlider.java - A proportional slider which can feed data into a DataChannel.
- Example: June Example - A web page that uses these applets.
More complex applications are built and a mechanism for merging events is defined. The use of instanceof is demonstrated to show selection by class type.
So at this point the benefit of using "smart controls" was pretty clear to me, and it must have been pretty clear to Sun as well as almost exactly 12 months after this column appeared Sun announced the JavaBeans technology. Coincidence? probably. The notion of building a UI out of customizable controls was a feature of Visual BASIC at the time and the Delphi environment from Borland.
- DataChannelMux.java - A multiplexed DataChannel for multiple writers.
- MuxItem.java - The type of object that pops out the back of a DataChannel multiplexor.
- VJApplet.java - A subclass of Applet that contains common housekeeping methods (such as
getColor
).- Numeric.java - A more sophisticated Numeric indicator that listens to a control channel as well as a data channel.
- OptionButton.java - A "chooser" control that provides exclusive choices and can send control messages.
- Slider.java - A scroll bar control that is a subclass of
VJApplet
.- Password.java - A password entering control.
- TextWidget.java - An applet that can display encrypted text (when fed the correct password).
- Example 1: - A more sophisticated temperature converter (requires Netscape 3.0)
- Example 2: - Using
Password
andTextWidget
to protect information on an otherwise public web page.
A tour of some of the IDEs that are shipping today and planned for tomorrow. I give my opinion on where I think they should be headed :-).
When this column went to press the competition between Symantec's Cafe and Borland's JBuilder was just heating up, and Microsoft was about to release J++. My current IDE of choice is either using the Sun JDK (its still the simplest way to go) or to use Visual SlickEdit which is a customizable editor that can be an IDE for anything.
A discussion of why you may wish to do some local management of resources to minimized thrashing the Java heap. Some classes are written that can implement a "recycling" program, returning object instances to their instantiatior for re-use. The canonical example is a psuedo terminal that can generate many short lived objects that overly tax the Java gc system.
This column generated a bit of controversy. "If garbage collection was so good, why did you have to code around it?" was a common refrain in my email. And the simple answer was that writing good code was writing good code, knowing your environment and optimizing for it was just good hygiene.
The radical bit was of course that Java did have a garbage collector and you couldn't manage your own resources, or could you? The answer is that of course you could, especially if you were using classes that used the factory pattern to generate instances of the object.
The thing to note is that the DataChannels were perturbed by this column and I had to add a synchronization interface that was absent before, thus these data channels are subtly different than the ones from the previous columns, they are compatible however.
- DataChannelOutputStream.java - An output stream class using DataChannels.
- DataItem.java - A modified version of DataItem
- DataChannelInputStream.java - An input stream based on Datachannels.
- StreamBuffer.java - A buffer class for the data channel streams.
- StreamBufferList.java - A collection class for StreamBuffer objects.
- Recyclable.java - An interface for recyclable objects.
- Referenced.java - An interface for reference counting on recyclable objects.
- DumbTTY.java - An example Applet
- Example 1. - An example class DumbTTY that uses DataChannel streams to communicate to a Java application.
This column covers the basic information needed to build custom class loaders for Java applications. The source included here is a simple class loader and a test class to run through it.
Of all the columns I wrote, this and the BASIC interpreter have probably brought me the most correspondence. ClassLoaders are pretty powerful weapons in Java and part of the enabler for much of the security concepts.. To see this code in action, you need to download these files and compile them (javac *.java) works well for that. Then move the resulting TestClass.class into a subdirectory called "store". Now use java Example to run the test. The output under Windows XP's COMMAND shell is as follows:
U:\CLASSES>java Example
This program will exercise the SimpleClassLoader.
>>>>>> Load class : TestClass
>>>>>> Not a system class.
>>>>>> Fetching the implementation of TestClass
>>>>>> Load class : java.lang.Object
>>>>>> returning system class (in CLASSPATH).
>>>>>> Load class : LocalModule
>>>>>> returning system class (in CLASSPATH).
>>>>>> Returning newly loaded class.
>>>>>> Load class : java.util.Vector
>>>>>> returning system class (in CLASSPATH).
>>>>>> Load class : java.lang.System
>>>>>> returning system class (in CLASSPATH).
>>>>>> Load class : java.lang.StringBuffer
>>>>>> returning system class (in CLASSPATH).
>>>>>> Load class : java.io.PrintStream
>>>>>> returning system class (in CLASSPATH).
Running the Test class, option was 'none'
Now initializing a Random object.
>>>>>> Load class : java.util.Random
>>>>>> returning system class (in CLASSPATH).
>>>>>> Load class : java.lang.Integer
>>>>>> returning system class (in CLASSPATH).
A series of 5 random numbers:
0: -89681414
1: -1167526225
2: 1424097917
3: 1317299300
4: 1216163438
U:\CLASSES>
The interesting bit is of course that TestClass isn't found by the default class loader and so it calls SimpleClassLoader to go off and find the class. The code that does that in our example is simple, however a much more complex version is possible, perhaps even decrypting classes as they are loaded or verifying MD5 checksums.
A number of application developers used this data to build IDEs that would run a class and then replace it with a new version once a change had been made. This is possible because once the SimpleClassloader object is no longer referenced, any classes it loaded are no longer referenced and available for collection.
This column begins a series on application development in Java. In the first part I show you how to build "containers" using the standard Java classes. The example implements a Binary Search tree based container.
Certainly not a barn burner of a column but this was before Sun had any serious container support. The next column extended the concept to include something similar to Objective C's "Mix-in" concept. In both cases, the beginning of building some reusable classes was being pursued. An interesting tidbit was that I offered Sun these classes as a set of containers but they turned me down because they were waiting for Parameterized Types which were going to be available before the end of 1997. Seven years later (2004) Parameterized types are finally part of Java.
When I wrote this column there was a tremendous churn in the Java community about whether or not Java was going to evolve. In many ways the worst fears of the community were realized as Java remained fairly static as a language for the next 5 - 7 years. With 1.5 Java made some fairly significant changes in the way things were done. Its a wonder sometimes that Java is still around.
This column builds on the November column by providing three separate solutions for making the key value in custom containers be generic. There are three sets of code, each with the same function but implementing that function slightly differently.
Click on this link to see the output from running this class.
Click on this link to see the output from running this class.
Click on this link to see the output from running this class.
This wasn't a column this was just an article on some pretty cool technology in Java that generated a parser. So called "compiler compilers" were the subject of a lot of research in the late 70's and they are tremendously useful when you need to add a scripting language to your application. This article still gets hits and as JavaCC has moved out of Sun and back into Sun again, its managed to stay avaialable.
Another parser generator that was profoundly affected by this was Terence Parr's PCCTS. Terence completely rewrote PCCTS in Java and it became ANTLR. Both JavaCC and ANTLR are available on the web and both do a good job of translating a language specification into something that a parser can be built from. At some point I will re-do Cocoa with one of these tools to make it more maintainable.
The article included a number of sample grammars to lead the reader through the process of creating a grammar. Given that most browsers haven't a clue on how to display JavaCC grammar files, you should probably right click on the link and then choose "save to disk" (or "save link as") then open the file with a text editor.
Calc1.jack - Basic four function integer calculator
Calc1i.jack - Same grammar with Java code to implement it.
Calc2.jack - Additional exponentiation operator, constant expressions, floating point.
Calc2i.jack - Same above but with implementation capabilities
Calc3.jack - Adds functions and logical operators (AND, OR, Etc.)
Calc3i.jack - Same as above but with Java code to implement it.
Click this link for a zip file with all of the above grammars in it.
This column is probably 3 or 4 in terms of people who wrote in about it. Generally its a very useful thing to be able to parse strings into keywords. Originally written to do command line parsing and awk(1) like things with files, I always thought that some of the stuff from JavaCC (covered later) should have made it into the base Java classes.
This column discussed the classes that are available in the base Java distribution that support lexical analysis. Building simple parsers with these classes fills the gap between complex auto-generated parsers such as the ones Jack (now JavaCC) builds, and simple string compares that are often used for option parsing.
There isn't a lot of source but there are a couple of cool examples. Note that compiling the examples will give you a bunch of warnings about deprecated interfaces. As these classes were generated by an applet generator in Visual Cafe I decided to leave them unchanged. (Rather than update them for Java 1.5). They are easily rewritten to get around the use of things like reshape.
This column uses a StreamTokenizer class to implement an interactive calculator along the same lines of the UNIX bc(1) command. It takes the StreamTokenizer class right to the edge of its usefulness.
When I wrote this column it triggered a discussion about what other sort of interpreted things one might do in Java and it was where the whole idea of doing a BASIC interpreter came up.
There is source for the calculator is available off the links below.
Click on this link to see the output from running this class.
Next to the ClassLoaders column this column is definitely in the top two or three. Actually it was three columns over the course of the summer but they came together into a single application. One thing that seemed to get lost on some people this is copyrighted code. Just because you read about it on the web, and the source is there for you to inspect and learn from, you don't have the right to use it in your products or applications without clearing it through me first. A couple of people have licensed the code and are using it in their products, its a pretty painless license.
I've gone so far as to give the interpreter its own set of web pages that you can get to by following this link.
Column one was primarily a planning exercise, this column begins a series describing how you can build interpreters in Java. The example program is a BASIC interpreter named COCOA. There is no source in this column, just a discussion of the structure of the interpreter and some of the thoughts that went into its design.
Column two begins by covering lexical analysis and parsing. Interestingly, this code was written without using JavaCC or any parser generators. I'm not sure if that was a good idea in retrospect, but because it was pretty clear what I wanted to generate out of this I didn't go back and re-do my efforts.
Finally in column three the full interpreter is shown running and a web page that has one of my "dumb" tty's is used as a demonstrator for the language. The plan was to use something datachannel like and be able to parse BASIC code from the pages themselves, but I've never implemented that.
Useful links:
The Cocoa home page is here.
Documentation on the language is here.
And a complete manifest of source files (with links) is here.
Remember, use it to learn about writing interpreters but don't redistribute my code. Thanks!
The August column begins a look at introspection. That is, looking at the structure of a Java class, rather than treating it as simply an execution abstraction. It introduces the notion of a class transformer in the form of a set of classes that can read class files, modify them and then rewrite them. Such a transformer could be used to obfuscate a class file for example.
These columns were a useful companion to Bill Venners articles on the JVM and its internals. They also represented some code that I had intended to be part of the core Java technology but were rejected by a guy in the Java group who didn't understand their value. They were written whilst in the midst of figuring out whether or not Java could be made into a Trusted Computing Base or TCB. One way to do that would be to not only validate privilege levels prior to loading a class, but also to remove those methods to which you did not have access. The concept was that class methods would be the equivalents of capabilities that could be allowed or disallowed based on the current security context within a class loader context.
For example, the current Java code disallows access to class File for applets. However what that means is you are forced to load the applets version of file I/O if you want to allow applets access to files. That makes it very hard to trust. Now consider a File class that had methods that were restricted to reading and writing into a single directory. as well as the regular methods. Now when the class is loaded, and the security context is "applet" the class could be edited on the fly to reduce the scope of its behavior. And because it was edited rather than by simply setting a value somewhere, no amount of hackery could restore the deleted methods. This sort of borrows from the Kung Fu theory that the only block that can defeat any blow, is to move out of the way.
Anyway, on my way toward building a secure class loader I wrote some functions to inspect class files.
System.out
Click on this link to see the output from running this class.
In this months column I look at Reflection, a new API in the 1.1 release of Java that allows a Java class to look at the internals of another Java class. Unlike last month, you can't change a class, however you can cache a reference to a method and invoke it later. This makes it a very powerful API.
Click on this link to see the output from running this class.
This column was a lot of fun because it showed some of the "big guns" of the time coming on board and building IDEs around Java. Today (October 2004) I use Visual SlickEdit and the Sun JDK as a Java development environment.
The original text describing this column is:
A new IDE to play with! Borland finally releases their IDE and I get to play with it. Delphi fans will be pleased, it certainly feels like Delphi. This is the first IDE I've tried that I'd consider using instead of Visual Cafe Pro. (I used JBuilder Pro) Of course it isn't all wonderful, it irritates the heck out of me that I can't customize the key controls for the editor.
Of course the life and times of Java IDEs became tumultuous to say the least. At some point the technology that was Visual Cafe was sold to WebGain who then sold it to TogetherSoft who was the repository for Borland's JBuilder. The only other serious IDEs for Java were Microsoft's J++ which was the foundation of one of Sun's lawsuits against them, and Visual Age from IBM.
Now Eclipse.org has a pretty cool free IDE and various other development environments are include Java support as a standard feature.
This month column looks at the Reader and Writer classes in Java 1.1. I originally asked the question, why is PrintStream being deprecated and this was what I found. As a bonus it contains some really hard to find info on just what those ByteToChar encoders do...
This column looks at using threads with collections. Part 1 is mostly setting up the problem for folks who haven't spent much time thinking about this issue.
Click this link to see an output from the SynchroTest class.
In part 2 of this column I build a thread safe collection and demonstrate its operation with a simple applet.
The Synchro Applet can be seen in a page by following this link.
I really like the Java powered i-Buttons. Apparently everyone thinks they are "cool" but few people actually use them (this from an inside source at Dallas now Maxim) This column generated a fair bit of email, a number of them from Cryptographers who were glad to see a decent explanation of how the Enigma machine (WW II German Cipher box) worked. It also showed the power of having a programmable embedded device when its "crypto" features were disabled. (This was before crypto was working on the buttons). Finally, a number of people pointed out that I could have made it so that the rotors were downloaded as well. However that would have increase the "strength" of the encryption provided and turned the software into something considered a weapon at the time!
This column is very long. (6,000 words) and talks about my experience in developing an applet for the Java Ring. The ringlet is an ENIGMA machine simulator (three rotors). The column discusses the ENIGMA, my code, and the problems I encountered while developing the applet. Note that these sources are a bit later than the ones in the article so they are slightly different (but in a good way :-)
This section contains text output from running some of the text-only examples under Windows XP's shell (COMMAND.EXE)
Version 1 of this code uses strings to sort the Dictionary.
U:\CLASSES\V1>java DictionaryTest
BinarySearchTree contains :
20: aquamarine
18: beige
12: black
19: blue
17: bronze
11: brown
4: chartreuse
7: cyan
15: gold
5: gray
1: green
6: magenta
2: orange
16: pink
3: purple
0: red
14: silver
9: tangerine
10: turquoise
13: white
8: yellow
press any key to continue.
Deleting node : 2: orange
Deleted node : 2: orange
Dictionary contains :
20: aquamarine
18: beige
12: black
19: blue
17: bronze
11: brown
4: chartreuse
7: cyan
15: gold
5: gray
1: green
6: magenta
16: pink
3: purple
0: red
14: silver
9: tangerine
10: turquoise
13: white
8: yellow
press any key to continue.
U:\CLASSES\V1>
The second version of the container uses a custom class called "ColorKey" which is both the Key and the Value of the entry into the binary tree.
U:\CLASSES\V2>java DictionaryTest
BinarySearchTree contains :
ColorKey:: 'aquamarine' ==> '21: aquamarine'
ColorKey:: 'beige' ==> '19: beige'
ColorKey:: 'black' ==> '13: black'
ColorKey:: 'blue' ==> '20: blue'
ColorKey:: 'bronze' ==> '18: bronze'
ColorKey:: 'brown' ==> '12: brown'
ColorKey:: 'chartreuse' ==> '5: chartreuse'
ColorKey:: 'cyan' ==> '8: cyan'
ColorKey:: 'gold' ==> '16: gold'
ColorKey:: 'gray' ==> '6: gray'
ColorKey:: 'green' ==> '2: green'
ColorKey:: 'magenta' ==> '7: magenta'
ColorKey:: 'orange' ==> '3: orange'
ColorKey:: 'pink' ==> '17: pink'
ColorKey:: 'purple' ==> '4: purple'
ColorKey:: 'red' ==> '1: red'
ColorKey:: 'silver' ==> '15: silver'
ColorKey:: 'tangerine' ==> '10: tangerine'
ColorKey:: 'turquoise' ==> '11: turquoise'
ColorKey:: 'white' ==> '14: white'
ColorKey:: 'yellow' ==> '9: yellow'
press any key to continue.
Deleting node : ColorKey:: 'purple' ==> '4: purple'
Deleted node : ColorKey:: 'purple' ==> '4: purple'
Dictionary contains :
ColorKey:: 'aquamarine' ==> '21: aquamarine'
ColorKey:: 'beige' ==> '19: beige'
ColorKey:: 'black' ==> '13: black'
ColorKey:: 'blue' ==> '20: blue'
ColorKey:: 'bronze' ==> '18: bronze'
ColorKey:: 'brown' ==> '12: brown'
ColorKey:: 'chartreuse' ==> '5: chartreuse'
ColorKey:: 'cyan' ==> '8: cyan'
ColorKey:: 'gold' ==> '16: gold'
ColorKey:: 'gray' ==> '6: gray'
ColorKey:: 'green' ==> '2: green'
ColorKey:: 'magenta' ==> '7: magenta'
ColorKey:: 'orange' ==> '3: orange'
ColorKey:: 'pink' ==> '17: pink'
ColorKey:: 'red' ==> '1: red'
ColorKey:: 'silver' ==> '15: silver'
ColorKey:: 'tangerine' ==> '10: tangerine'
ColorKey:: 'turquoise' ==> '11: turquoise'
ColorKey:: 'white' ==> '14: white'
ColorKey:: 'yellow' ==> '9: yellow'
press any key to continue.
U:\CLASSES\V2>
This final version used the color's actual "Hue" to sort colors. It should be in color-wheel order although to be honest I can't tell if it is or not. I do know that the sort is done on the HSB (Hue, Saturation, Brightness) value which is printed out behind the colors.
U:\CLASSES\V3>java DictionaryTest
BinarySearchTree contains :
Color: black, value 0.0,0.0,0.0
Color: darkGray, value 0.0,0.0,0.2509804
Color: gray, value 0.0,0.0,0.5019608
Color: lightGray, value 0.0,0.0,0.7529412
Color: pink, value 0.0,0.3137255,1.0
Color: red, value 0.0,1.0,1.0
Color: white, value 0.0,0.0,1.0
Color: orange, value 0.13071896,1.0,1.0
Color: yellow, value 0.16666667,1.0,1.0
Color: green, value 0.33333334,1.0,1.0
Color: cyan, value 0.5,1.0,1.0
Color: blue, value 0.6666667,1.0,1.0
Color: magenta, value 0.8333333,1.0,1.0
press any key to continue.
Testing two keys for equality ... true
Deleting node : Color: orange, value 0.13071896,1.0,1.0
Deleted node : Color: orange, value 0.13071896,1.0,1.0
Dictionary contains :
Color: black, value 0.0,0.0,0.0
Color: darkGray, value 0.0,0.0,0.2509804
Color: gray, value 0.0,0.0,0.5019608
Color: lightGray, value 0.0,0.0,0.7529412
Color: pink, value 0.0,0.3137255,1.0
Color: red, value 0.0,1.0,1.0
Color: white, value 0.0,0.0,1.0
Color: yellow, value 0.16666667,1.0,1.0
Color: green, value 0.33333334,1.0,1.0
Color: cyan, value 0.5,1.0,1.0
Color: blue, value 0.6666667,1.0,1.0
Color: magenta, value 0.8333333,1.0,1.0
press any key to continue.
U:\CLASSES\V3>
This is the run of the February app called "STExample." A simple interactive calculator.
U:\CLASSES>java STExample
Enter an expression...
22/7
Syntax Error detected! - missing initial '=' sign.
Enter an expression...
=22/7
Parsed expression : (22.0 / 7.0)
Value is : 3.142857142857143
Enter an expression...
345^2
Syntax Error detected! - missing initial '=' sign.
Enter an expression...
=234^3
Parsed expression : (234.0 ^ 3.0)
Value is : 1.2812904E7
Enter an expression...
a=3
Parsed expression : 3.0
Value is : 3.0
Assigned to : a
Enter an expression...
=16*a/2
Parsed expression : ((16.0 * a) / 2.0)
Value is : 24.0
Enter an expression...
exit
U:\CLASSES>
This is the run of the August '97 app called "dumpclass." A simple class dumper class. I used the BinarySearchTree class from December '96 as it used a number of Java features and thus provided an "interesting" dump.
U:\CLASSES\AUG97>java dumpclass ..\BinarySearchTree.class
import BSTEnumerator;
import java.lang.String;
import BSTNode;
/*
* This class has 1 optional class attributes.
* These attributes are:
* Attribute 1 is of type SourceFile
* SourceFile : BinarySearchTree.java
*/
public synchronized class BinarySearchTree extends java.util.Dictionary {
/* Instance Variables */
BSTNode rootNode;
private int elementCount;
/* Methods */
public void BinarySearchTree();
public void print(java.io.PrintStream a);
private static BSTNode search(BSTNode a, java.lang.String b);
private void insert(BSTNode a);
private BSTNode delete(BSTNode a);
public BSTNode search(java.lang.String a);
public java.util.Enumeration elements();
public java.util.Enumeration keys();
public java.lang.Object get(java.lang.Object a);
public boolean isEmpty();
public int size();
public java.lang.Object remove(java.lang.Object a);
public java.lang.Object put(java.lang.Object a, java.lang.Object b);
}
U:\CLASSES\AUG97>
This is the run of the September '97 app called "ReflectClass." It uses the Reflection API to implement a class dumper as well. The difference here is that ReflectClass depends on the JVM being able to load the class in order to reflect it, but dumpclass simply analyzes a file (or bag of bits) assuming it is a class.
As in August I used the BinarySearchTree class so that you can compare the output between the Reflection API and my class dumper.
U:\CLASSES>java ReflectClass
BinarySearchTree
import java.lang.String;
import java.lang.Object;
import java.io.PrintStream;
import java.util.Enumeration;
public class BinarySearchTree extends Dictionary {
/*
* Field Definitions.
*/
BSTNode rootNode;
private int elementCount;
/*
* Declared Constructors.
*/
public BinarySearchTree( ) { ... }
/*
* Declared Methods.
*/
public Object put( Object, Object) { ... }
public Object get( Object) { ... }
public int size( ) { ... }
public Enumeration elements( ) { ... }
public Object remove( Object) { ... }
public void print( PrintStream) { ... }
public Enumeration keys( ) { ... }
public boolean isEmpty( ) { ... }
private BSTNode delete( BSTNode) { ... }
private void insert( BSTNode) { ... }
private static BSTNode search( BSTNode, String) { ... }
public BSTNode search( String) { ... }
}
U:\CLASSES>
This is the run of the SyncrhoTest code as an application..
U:\CLASSES>java SynchroTest
Total array size was 24 elements.
ELEMENT[1] - 0
ELEMENT[2] - 1
ELEMENT[3] - 2
ELEMENT[4] - 3
ELEMENT[5] - 5
ELEMENT[6] - 6
ELEMENT[7] - 10
ELEMENT[8] - 12
ELEMENT[9] - 17
ELEMENT[10] - 24
ELEMENT[11] - 25
ELEMENT[12] - 20
ELEMENT[13] - 30
ELEMENT[14] - 31
ELEMENT[15] - 32
ELEMENT[16] - 33
ELEMENT[17] - 34
ELEMENT[18] - 40
ELEMENT[19] - 45
ELEMENT[20] - 45
ELEMENT[21] - 46
ELEMENT[22] - 47
ELEMENT[23] - 49
ELEMENT[24] - 55
U:\CLASSES>