Home | About | Partners | Contact Us
VA Linux Systems

Welcome to http://pjda.sourceforge.net/

By Ken Graham
Current Version: Stable - install.jar Official Release 1.0
[ FAQ | README | License | INSTALL ]

This has nothing to do with Sun's PersonalJava(TM) Application Environment(TM)

What is the Personal Java Data Assistant(PJDA)?

It can be thought of as a Java wrapper around an OS, providing a consistent form of interaction, scripting, nomenclature, etc, which is the same regardless of OS or platform.

Java is a great idea. Write your application once, then run it anywhere.  As most of you know, that is not the case. Java at its core, behaves differently depending upon the OS and platform. What is needed is a consistent framework within which the OS and platform become moot. The PJDA is exactly this. I applaud and look forward to what JOS has to offer. JOS requires replacing the OS. There will never be a day where every machine is running the same OS, whether it be Linux or JOS. However, we can I believe envision a day where most platforms and Operating Systems do have a JVM available, and it is this paradigm which motivate the PJDA design and implementation.

What does the PJDA offer that is of benefit or value?

Java applications are no longer required to be standalone. 

Arbitrary output from one Java application can simply be piped to the input of another Java application. 

Compile, test, compile, test, and compile, and test, your Java code without leaving the JVM. (This is one of the reasons why the class loader had to be redone).

Pipe output from any command as input to any other command. Notice that compiler output is displayed to the 'console'. To accomplish this feat, the whole java.io paradigm had to be discarded, and one that is more useful was implemented. One that is simpler and open to uses outside of the initial design framework. This is why the package jdkfix.io.Stdio, Stdin, Stdout, were created. For instance, when you do a new Stdin(Object o), 'o' can be a String in which case it could be a file name or a url, or it can be one of java.io's input classes. The resulting Stdin object is then used every- where. With this implementation, to implement a command is very simple, you read your input from stdio.stdin, you display your output to stdio.stdout, and any error messages go to stdio.stderr, and you still have access to the command input stream which caused these commands to be executed. Your command does not need to know the source of the input or the destination of the output. It does not need to handle separately each potential class of input or output object type, whether it be URL, File, Pipe, RandomAccessFile, BufferedReader, ...

Do automated testing by being able to pipe output between commands, so that conditions that cause a bug, can be easily reproduced, and diagnosed. In a typical GUI environment this is very difficult, if not impossible. It was this very ability which allowed a bug to be found in the JigSaw implementation of JDBM which can corrupt the hash bucket table. When I was using it simply, with a GUI front end, I would never have been able to put enough data in to cause the problem, much less, if I did encounter one, reproduce exactly the steps necessary to reproduce it. (Hint: it took a lot of data to cause the problem in the first place, much less reproduce the problem. If I had been constrained to only a GUI front end, it would never have been found, much less addressable had it even been encountered). The other reason for automated testing, is that you will find more bugs. This is true for your own code, the JVM, as well as the current AWT model. The ability to accurately reproduce the situation which causes the issue is invaluable. With this ability you then can easily deduce where the problem lies, and then concentrate your efforts in your code, or in a remedial solution when the problem cannot otherwise be addressed.

Do you want to be able to unload classes so they can be updated, or free memory for resources you know will no longer be needed? If you do, then the class jdkfix.lang.pjdaClassLoader should be looked at. Currently, if you use java.lang.ClassLoader, classes can never be unloaded. See my ClassLoader FAQ for information on what a proper design and implementation should and does look like.

Do you want a pseudo terminal interface which provides the same look and feel regardless of which platform you are on, including file path nomenclature? I use Windows at work, and Linux at home, and I use the PJDA in both places, use the same scripts to perform the same functionality, and I use the same file nomenclature, without having to remember whether this is a situation where I should use the backslash, the forward slash, etc, etc, etc.

Those are just the highlights. See the list of commands for a better feel for what is available and possible.

Here is a short list of potentially plagiarizable classes.

ReallyRandom is a class that uses an internal array of Random[], to provide a more truly "random" sequence. All single element random number generators that are LCG(linear congruential pseudorandom number generator), have a fixed sequence. For an excellent discussion on DSS, and its ease of being hacked, because of this problem, see: "Pseudo-Random" Number Generation within Cryptographic Algorithms: the DSS Case. What if seed size and generation were abstracted so that what is supplied is a recipe instead? A recipe where one component is any document on the web, and whose seed size is arbitrary and can be on the order of 1e6. A seed size of 1e5 took 28 seconds to generate on an NT Pentium 500 with 128 meg of ram. A seed size of 5e5 took just over two minutes, making a seed size of 1e6 within reach and reason for some applications. See the included documentation with the class for more information.

The jdbm package of a java implemented ndbm under JigSaw, has, like a lot of databases, a few problems. The one included here has the following changes. Instead of file location pointers being int, they are "long". This way, one could, if one was so inclined, have a "large" file of data. The enumeration of keys and values provided by JigSaw, did not guarantee that every item would be returned only once. This is a requirement for real use. There is a wrapper called JBase, which, using the aforementioned jdbm, has sets, keys, chains, and the ability to detect corruption(!!), as well as unload, reload, store, and restore. At some point in the future, the tool set will include database modification, non-keyed searches, etc.

Provides a properly implemented subclass of ClassLoader. It uses URL's, and loaded classes can be unloaded.
It includes a correct implementation of the Java 1.2 delegation model. Already loaded classes are NOT loaded again. This may seem like an obvious statement. It is not. java.lang.ClassLoader provides no means privately or publicly to perform this requirement. This implementation also actually does load the classes, so those classes get their 'o.getClassLoader()' value set correctly. The 1.2 class delegation model delegates all loading of classes to the system class loader, so even if you subclass their loader, your subclass never actually loads any class, so the classloader for those classes affected by your subclass will never report their classloader as your subclass. "Isn't that special."(SNL/DC/CL)
This implementation is correct for Java. Please see my ClassLoader FAQ for further details.

Provides an implementation of FileSystem.resolve($,$) such that when a fullpath(or absolute) is given as both parameters, or the child component is a path relative location, the return value is meaningful, useable, and correct. Currently if you do 'new File($,$)' where both parameters are given, what is returned is a mere concatenation without regard to the content of the second parameter. This is patently negligent behavior.

Note that this stand alone java application does not call System.exit(). It launches the AWT associated threads as daemons, so that when Pjda.main() returns, the AWT threads are summarily dispatched (no AWT pun intended :-) ) and the JVM terminates cleanly. See Tony LaPaso's "Beware The Daemons" article at Absolute Java, published in Java Developers Journal April 2000.

jdkfix.awt.EventDispatchThread is required so registered listeners receive desired events when they are themselves not AWT components/objects. java.awt.EventDispatchThread only dispatches events to AWT objects, ignoring the registered listener list.

Provides a class which will return a list of files which match a Perl5 pattern. This class is used to list the contents of a directory, even when that directory is in a jar. As noted above, there are bugs in some subclasses of URLConnection due to an incomplete implementation or erroneous design. For instance, see the source to the 'ls' command as well as the pjdaClassLoader references to a JarURLConnection.

Provides a Stdin and Stdout class definition which is used for all io regardless of source object. This is how output from "jar" or "Exception.printStackTrace()" get displayed to a "BigTextArea". To have IO delivered to Classes of your choice, simply implement the appropriate interfaces. See pjda.pjutil.BigTextArea, and Command.pjda.Command.cpCommand(or use 'wysiwyg cp') to see how they are used.

When you create a Child application(fork()/exec()) from your main Java application, a new AppContext is created. This means that Object/Thread/ThreadGroup associations and event dispatching are correct.

jdkfix.lang.fixSystem.threadGroupCount() returns a number which is both correct and valuable. Currently the number returned has no bearing on reality, and is not even an attempt at an approximation.

This implementation provides a PrintStream wrapper (jdkfix.stdio.Std_PrintStream) which makes a jdkfix.io.Stdout object look like a PrintStream object. This is what is used to send output to System.err, and System.out, and Process.out, to the current 'stdout'. This way it can come to the display or piped through to 'grep', for instance.

This implementation provides a C sprintf like class for formatting output, so you do not have to reinvent the wheel.

This implementation provides a DeathListener interface to allow applications to listen for the death of their children, and the event gets dispatched to registered listeners even when they are not AWT objects, because of the class jdkfix.awt.EventDispatchThread mentioned above.

This implementation provides a standard way of producing debugging output which is simple to use and provides sufficient information to replace the functionality of having source line numbers. It only requires hardcoding, which is a BAD programming practice required by the current definition of Java, in static instances. Java has not been designed or implemented to allow the developer to know the current class unless it is instantiated, and even though the yacc knows the current method as well as class at compile time, this information is not made available, lexically or syntactically. A wise person would consider this aspect of Java gross ineptitude.

This implementation provides an Alarm thread which handles single, repeating, and cron timing specifications. See 'at', 'cron', 'every', and 'in'. /* this alarm thread, being set as daemon, then also starts up the AWT threads so they are also daemon. This is where the code resides which allows for System.exit() to be avoided */

This application provides a method for making a file and/or attachment private. After having sent the email, it is possible to retroactively make the attachment undecipherable. :-)

The AWT has a problem in its implementation. TextComponent.append() or tc.setText(), create events to be executed by the AWT-Thread, AND! Thread execution order/prioritization when there are multiple threads (there are always multiple threads) is not guaranteed by the Java Language Specification. (JLS)
Whether this is an asset to the language or a deficit is debatable. What this means is that append() and setText() are simply "suggestions". They are not atomic, they are not necessarily completed prior to the methods return, and data structures within those objects are not valid for some arbitrary amount of time until after the AWT-Thread has had a chance to execute, which you cannot force.
Thread.yield() is documented to be a pointless call.
The above problem needs a solution. There is a way of coding around it, and you will find it in pjda.pjutil.BigTextArea.setSelection(). The other related issue, is that until the AWT Thread is alive and finished initializing the default AWT Toolkit and the values it returns are not valid, and there is no documented way of guaranteeing that the values returned are valid. By moving this issue to the PJDA, the applications programmer does not have to address the concerns of platform dependence inherent in Java as it currently exists.

You can automate testing. It is only by being able to throw a large mountain of test data at an application that you can be sure it is "sound". The PJDA provides the means for doing just that.

You can do class compiling, loading, testing, and unloading, over and over again without the need to stop the jvm and restart it. This is only true for classes loaded by the jdkfix.lang.LocalClassLoader instantiated by the CommandLocator class. Classes loaded by the default class loader or the first instance of LocalClassLoader cannot be unloaded. To explain why requires more of an explanation than is appropriate here. Please see my ClassLoader FAQ for further details.

The above list is representative, but by no means exhaustive.

WHERE CAN I GET IT?
The current version can be downloaded here

HOW CAN I HELP?
First, try it.
If you find a new bug, provide enough detail in your feedback that it can be found and fixed.
If you notice a missing feature, provide it, or request it.
If you have a solution to a problem in Java that is appropriate for here, Please contribute it.
If you have expertise that would contribute to a conversation about the class loader issues raised here and wish to participate in a solution that works, please join.

PJDA is hosted on SourceForge,
and you can visit the PJDA project page here.

This Open Source Java site owned by Ken Graham.
[ Previous 5 Sites | Previous | Next | Next 5 Sites | Random Site | List Sites ]