My challenge for this project was to seek a way to work with the Java programming language in a similar way. This was quite a risky challenge, as I didn't know what was possible at the time. However I feel I have succeeded in finding a good way of live programming with java, and learned a great deal about the language in the process. My notes show that I considered three ways of achieving this;
Looking at each possibility in turn;
This is what I do with Perl, it's easy in Perl to re-interpret the sourcecode for a class at runtime, replacing and creating methods and leaving the data of objects of that class untouched. However while the Java documentation shows ways of getting methods as objects, it shows no way of setting the methods of a class.
I later read that there is a way of "hot swapping" one method with another, introduced in Java version 1.4. The implementation is disappointing however, you can swap one method with another, but the new method must take exactly the same arguments as the one it replaces, and you cannot supply new methods at runtime. Useful for accurate profiling and minor debugging, but not useful for fully ad-hoc live programming.
Sun are considering improving this "hot swapping" feature, and are soliciting comments against this bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4910812 . I shall be watching this bug with interest.
This would be a nasty constraint, crippling many object oriented features of Java. Fairly straightforward to implement, but not very nice to use. A worst case scenario.
Rather than manipulating an object, the idea was to instead create a new object using the modified sourcecode, and copy the data from the old one. This is much like teleporting someone from one place to another by scanning their atoms in one location, creating a copy of their atoms in another location, and then killing the original person.
After reading "Java reflection in Action" [1], this is the approach I chose to try implementating. Reflection allows introspection, that is it allows a running program to look at the structure of its classes, methods and fields as objects in their own right. This the fields of any object to be found, equivilent fields to be searched for on another object, and if found, the values copied between them.
Java Reflection in Action also details the use of proxy classes, which also came in great use in my implementation. By using a proxy class I could swap one object for another without the rest of the program noticing.
Full implementation details can be found in the javadoc for my LiveProxy class.
There are two methods marked in LiveProxy.java that were not written from me, but were taken from the public domain examples within Java Reflection in Action [1]
Livework also uses the excellent 'jedit' textarea, for code editing with syntax highlighting. I have included it as a jar file here without source, but the sourcecode is available online [2]
I tested this project by using it. I wrote a few classes - Nourathar, NouratharColor and Envelope for the purpose of trying out my livecoding environment with a simple visual synthesiser. These Nourathar classes allow me to 'play' a colour on the screen, making a colour appear at a certain location for a set period of time.
When you first start up livework the editor will contain a simple class calling the play() method of a Nourathar object to produce a visual effect.
To see what happens when you change the class, make your change and then press ALT-x.
To test livework further, I intend to release it to a community under the GNU Public License, in order to gain feedback from those who might implement my ideas in their own software.
Because it needs to be able to compile java classes, livework requires a recent version of the Java SDK.
It needs to access the included 'jedit' jar file and tools.jar from sun.
For example:
/usr/lib/j2sdk1.5-sun/bin/java -classpath .:/usr/lib/j2sdk1.5-sun/lib/tools.jar:./jars/jedit.jar livework.LiveWork