Friday, April 24, 2009

Scala Syntax Highlighter For Eclipse

A Light Eclipse Plugin for the Scala Programming Language



http://code.google.com/p/lightscalaplugin/

This Eclipse plugin provides syntax highlighting for the Scala programming language.
At present, the plugin only supports syntax-highlighting. The highlighting style is similar to the default Java style for Eclipse.

Last Tested on WindowsXP, Java 1.5, Eclipse 3.4.2 (As of 4/24/2009)

----

Monday, April 20, 2009

Chris McKinstry: And now for the movie

http://themanbehindthecurtainfilm.com/

"The Man Behind the Curtain is a documentary exploring the troubled mind and tumultuous life of artificial intelligence and cognitive science researcher Chris McKinstry. Plagued with mental instability, Chris left in his wake a swath of broken relationships and public suicide attempts, ultimately culminating in an online forum post detailing his last moments."

Sunday, April 19, 2009

Java Genetic Algorithms Package(JGAP) and Scala

This is example source for a non-idiomatic example with JGap and Scala. The goal of this code is to give an input amount of change, say 30 cents and let the program calculate the least number of American coins. This is mostly a source example, there are some resources for learning Scala and JGap in the resources section at the bottom of this blog entry.

[java] Running Make Change
[java] Input amount of change => 30
[java] Total evolution time: 2661 ms
[java] The best solution has a fitness value of 296.0
[java] It contained the following:
[java] 1 quarters.
[java] 0 dimes.
[java] 1 nickels.
[java] 0 pennies.
[java] Done


On Scala and JGap:

"Scala goes further than all other well-known languages in fusing object- oriented and functional programming into a uniform language design.
In addition to being a pure object-oriented language, Scala is also a full-blown functional language." -- Programming in Scala Book

"JGap provides basic genetic mechanisms that can be easily used to apply evolutionary principles to problem solutions." -- JGap Website

The Scala example consists of one scala source file. The original Java consists of two classes. It uses non-idiomatic Scala code, it is really just a quick example to show syntax differences with the Java version of the source.

/*
* This was based on an example from JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licensing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*
* Original Authors:
*
* @author Neil Rotstan
* @author Klaus Meffert
*
* Converted to Java Genetic Algorithms Example (Jgap) and Scala - Berlin Brown, 4/14/2009
*/


package org.bnode.genetics

import org.jgap._;
import org.jgap._;
import org.jgap.data._;
import org.jgap.impl._;
import org.jgap.xml._;
import org.w3c.dom._;

import java.io._;

/**
* This class provides an implementation of the classic "Make change" problem
* using a genetic algorithm. The goal of the problem is to provide a specified
* amount of change (from a cash purchase) in the fewest coins possible. This
* example implementation uses American currency (quarters, dimes, nickels, and
* pennies).
* <p>
* This example may be seen as somewhat significant because it demonstrates the
* use of a genetic algorithm in a less-than-optimal problem space. The genetic
* algorithm does best when there is a smooth slope of fitness over the problem
* space towards the optimum solution. This problem exhibits a more choppy space
* with more local optima. However, as can be seen from running this example,
* the genetic algorithm still will get the correct (or a very close) answer
* virtually everytime.
*
*/

object MakeChange {

val MAX_ALLOWED_EVOLUTIONS = 600;

/**
* Amount of input change we are targetting.
*/

val a_targetChangeAmount = 30
val mainPopulationSize = 300

/* ///////////////////////////////////////////////////////////////// */

/**
* Main Entry Point for the application.
*/

def main(args: Array[String]): Unit = {
println("Running Make Change")
println("Input amount of change => " + a_targetChangeAmount)
makeChangeForAmount()
println("Done")
} // End of the method

/* ///////////////////////////////////////////////////////////////// */

/**
* Sample fitness function for the MakeChange example.
*/

class MakeChangeFunction(atargetAmount:Int) extends FitnessFunction {

var targetAmount = 0
val MAX_BOUND = 600

targetAmount = atargetAmount

def getTotalNumberOfCoins(a_potentialsolution:IChromosome) : Int ={
val numberOfGenes = a_potentialsolution.size()
var i = 0
var totalCoins = 0
while (i < numberOfGenes) {
totalCoins += getNumberOfCoinsAtGene(a_potentialsolution, i)
i += 1
}
return totalCoins
}

/**
* Calculates the total amount of change (in cents) represented by the given
* potential solution and returns that amount.
*
*/

def amountOfChange(a_potentialSolution:IChromosome) : Int = {
val numQuarters = getNumberOfCoinsAtGene(a_potentialSolution, 0)
val numDimes = getNumberOfCoinsAtGene(a_potentialSolution, 1)
val numNickels = getNumberOfCoinsAtGene(a_potentialSolution, 2)
val numPennies = getNumberOfCoinsAtGene(a_potentialSolution, 3)
return (numQuarters * 25) + (numDimes * 10) + (numNickels * 5) + numPennies
}

def changeDifferenceBonus(a_maxFitness:Double, a_changeDifference:Double) : Double = {

if (a_changeDifference == 0) {
return a_maxFitness
} else {
if ((a_changeDifference * a_changeDifference) >= (a_maxFitness / 2)) {
return 0.0
} else {
return a_maxFitness / 2.0 - a_changeDifference * a_changeDifference
} // End of if - else

} // End of if - else
}

def computeCoinNumberPenalty(a_maxFitness:Double, a_coins:Int) : Double = {
if (a_coins == 1) {
return 0
} else {
return Math.min(a_maxFitness, a_coins * a_coins)
}
}

/**
* Determine the fitness of the given Chromosome instance. The higher the
* return value, the more fit the instance. This method should always return
* the same fitness value for two equivalent Chromosome instances.
*
*/

def evaluate(a_subject:IChromosome) : Double = {

val defaultComparation = a_subject.getConfiguration().getFitnessEvaluator().isFitter(2, 1)

// The fitness value measures both how close the value is to the
// target amount supplied by the user and the total number of coins
// represented by the solution. We do this in two steps: first,
// we consider only the represented amount of change vs. the target
// amount of change and return higher fitness values for amounts
// closer to the target, and lower fitness values for amounts further
// away from the target. Then we go to step 2, which returns a higher
// fitness value for solutions representing fewer total coins, and
// lower fitness values for solutions representing more total coins.
val changeAmount = amountOfChange(a_subject)
val totalCoins = getTotalNumberOfCoins(a_subject)
val changeDifference = Math.abs(targetAmount - changeAmount)

var fitness = 0.0
if (defaultComparation) {
fitness = 0.0
} else {
fitness = MAX_BOUND / 2.0
}

if (defaultComparation) {
fitness += changeDifferenceBonus(MAX_BOUND / 2, changeDifference)
} else {
fitness -= changeDifferenceBonus(MAX_BOUND / 2, changeDifference)
}

if (defaultComparation) {
fitness -= computeCoinNumberPenalty(MAX_BOUND / 2.0, totalCoins.asInstanceOf[Int])
} else {
fitness += computeCoinNumberPenalty(MAX_BOUND / 2.0, totalCoins.asInstanceOf[Int])
}

return Math.max(1.0, fitness)
}

def getNumberOfCoinsAtGene(a_potentialSolution:IChromosome, a_position:Int) : Int = {
val numCoins = a_potentialSolution.getGene(a_position).getAllele()
return numCoins.asInstanceOf[Int]
}

} // End of Class

/* ///////////////////////////////////////////////////////////////// */

/**
* Executes the genetic algorithm to determine the minimum number of coins
* necessary to make up the given target amount of change. The solution will
* then be written to System.out.
*/

def makeChangeForAmount() {

val conf = new DefaultConfiguration();
conf.setPreservFittestIndividual(true)
val myFunc = new MakeChangeFunction(a_targetChangeAmount)
conf.setFitnessFunction(myFunc)

// Now we need to tell the Configuration object how we want our
// Chromosomes to be setup. We do that by actually creating a
// sample Chromosome and then setting it on the Configuration
// object. As mentioned earlier, we want our Chromosomes to each
// have four genes, one for each of the coin types. We want the
// values (alleles) of those genes to be integers, which represent
// how many coins of that type we have. We therefore use the
// IntegerGene class to represent each of the genes. That class
// also lets us specify a lower and upper bound, which we set
// to sensible values for each coin type.

val sampleGenes = new Array[IntegerGene](4);

// Quarters
sampleGenes(0) = new IntegerGene(conf, 0, 3 * 10)
// Dimes
sampleGenes(1) = new IntegerGene(conf, 0, 2 * 10)
// Nickels
sampleGenes(2) = new IntegerGene(conf, 0, 1 * 10)
// Pennies
sampleGenes(3) = new IntegerGene(conf, 0, 4 * 10)

val sampleChromosome = new Chromosome(conf.asInstanceOf[Configuration],
sampleGenes.asInstanceOf[Array[Gene]])
conf.setSampleChromosome(sampleChromosome);
conf.setPopulationSize(mainPopulationSize)
val population = Genotype.randomInitialGenotype(conf)

var i = 0;
val startTime = System.currentTimeMillis()
while (i < MAX_ALLOWED_EVOLUTIONS) {
population.evolve();
i += 1;
} // End of While
val endTime = System.currentTimeMillis()
println("Total evolution time: " + (endTime - startTime) + " ms")

val builder = DataTreeBuilder.getInstance()
val doc2 = builder.representGenotypeAsDocument(population)

// Write the XML document but do not read it.
val docbuilder = new XMLDocumentBuilder()
val xmlDoc = docbuilder.buildDocument(doc2)

XMLManager.writeFile(xmlDoc.asInstanceOf[Document], new File("JGAPExample26.xml"))
val bestSolutionSoFar = population.getFittestChromosome()

// Print the best solutions
println("The best solution has a fitness value of " + bestSolutionSoFar.getFitnessValue())
println("It contained the following: ")
println("\t" + myFunc.getNumberOfCoinsAtGene(bestSolutionSoFar, 0) + " quarters.")
println("\t" + myFunc.getNumberOfCoinsAtGene(bestSolutionSoFar, 1) + " dimes.")
println("\t" + myFunc.getNumberOfCoinsAtGene(bestSolutionSoFar, 2) + " nickels.")
println("\t" + myFunc.getNumberOfCoinsAtGene(bestSolutionSoFar, 3) + " pennies.")

true
} // End of Method


} // End of Object


For comparison, you can see that some of the Java constructs look similar to the Scala version:

public double evaluate(IChromosome a_subject) {

boolean defaultComparation = a_subject.getConfiguration().getFitnessEvaluator().isFitter(2, 1);

int changeAmount = amountOfChange(a_subject);
int totalCoins = getTotalNumberOfCoins(a_subject);
int changeDifference = Math.abs(m_targetAmount - changeAmount);
double fitness;
if (defaultComparation) {
fitness = 0.0d;
} else {
fitness = MAX_BOUND / 2;
}

if (defaultComparation) {
fitness += changeDifferenceBonus(MAX_BOUND / 2, changeDifference);
} else {
fitness -= changeDifferenceBonus(MAX_BOUND / 2, changeDifference);
}

if (defaultComparation) {
fitness -= computeCoinNumberPenalty(MAX_BOUND / 2, totalCoins);
} else {
fitness += computeCoinNumberPenalty(MAX_BOUND / 2, totalCoins);
}

return Math.max(1.0d, fitness);
}


Resources

This example was tested with Scala 2.7.3 and JGap 3.4.3

http://jgap.sourceforge.net/

http://www.scala-lang.org/

Full Source

The full source is hosted as a google code project, jvmnotebook. You can browse through the source or perform a svn checkout.

http://jvmnotebook.googlecode.com/svn/trunk/scala/jgap

-------

Wednesday, April 8, 2009

Google AppEngine Next language - Java

http://googleappengine.blogspot.com/?

"Today, we're very excited to announce the availability of a new programming language for Google App Engine. Please welcome the Java runtime!"

Tuesday, April 7, 2009

My set of buzzwords and things I want to learn over the next 6 months or year

1. drools
2. genetic algorithms

3. jquery - for client side web development
4. ajax - for client side web development
5. gwt - for client side web development

6. better software engineering practices
7. better TDD

8. emacs-lisp - better emacs support
9. factor - amazing technology
10. gnu forth - great skill to learn
11. spring-framework - enterprise java development
12. scala -
13. haskell - great language to learn
14. mono - enterprise .net development on linux
15. cocoa - for mac gui development
16. statistics
17. boolean algebra

Monday, April 6, 2009

Practical Clojure with SWT, JUnit and Spring

Date: Mon Apr 06 13:56:55 EDT 2009



The following entry describes a practical approach for using the Clojure programming language. Clojure is a new lisp dialect that targets the Java Virtual Machine. It has a lot of syntatic sugar of other Lisp languages but can also be used interoperate with existing Java libraries. This entry describes how to build a simple test helper GUI application that launches a script to compile your tests, run your tests and also runs Java's hprof and verbose garbage collection statistics. I have always had trouble compiling, launching and manipulating a collection of test scripts. By using clojure and this tool, I can quickly launch of series of tests without having to visit the command line. In reality, this test only LAUNCHES a script that then launches the actual test main application. So, the GUI application only acts as a facility for launching other processes. In our case, the processes are the Clojure test suites. The hprof and verbosegc command-line arguments are used depending on the button even that is invoked. The application relies on SWT (Eclipse's Standard Widget Toolkit), Clojure and Spring. Spring is not really needed for this type of small applcation but I introduce it here so that you have an example on how to use the framework alongside Clojure.

Java oriented approach for Bootstrapping Clojure and Spring:

There are several different approaches for invoking Clojure on your source:

  • clojure.lang.Script - Use the Script main class to invoke Clojure on a particular source file.
  • clojure.lang.Repl - Use the Repl main class to invoke the Clojure Repl loop on a file
  • Compile Clojure source to a Java bytecode and then invoke that particular main class
  • Compile your own bootstrap code that uses the Clojure java API. We used this approach for bootstrapping the GUI application. Essentially, we are using the low-level Java Clojure code to invoke clojure.main.

The Java Bootstrap Code:


I wrote a small blog entry on how to call Clojure from Java using Clojure's low-level API. It boiled down to taking the code from clojure.lang.Script and reworking some of the calls. The goal is to invoke the Clojure runtime and launch our script.

private static final String BEAN_FACTORY = "beanFactoryRef-testwin.xml";
private static final String [] CLASSPATH_CONTEXTS = { "conf/applicationContext-testwin.xml" };
private static final String BASIC_TEST_WIN_GLOBALS = "light.test.win.spring_globals";
private static final String BASIC_TEST_WIN_NAMESPACE = "light.test.win.basic_test_window";

public Object invokeContract(Object precondInput) throws ContractError {
final ApplicationContext context = (ApplicationContext) precondInput;
//////////////////////////////////
// Init the clojure main library
//////////////////////////////////
final Symbol symbolClojureMain = Symbol.create("clojure.main");
final Namespace namespaceClojureMain = Namespace.findOrCreate(symbolClojureMain);
final Var varRequire = Var.intern(RT.CLOJURE_NS, Symbol.create("require"));

// Setup clojure/main
try {
varRequire.invoke(symbolClojureMain);

// Call require on our utility clojure code
// Set the variable spring-context for use in the clojure script
Var.intern(Namespace.findOrCreate(Symbol.create(BASIC_TEST_WIN_GLOBALS)), Symbol.create("*spring-context*"), context);

// Launch the main window.
varRequire.invoke(Symbol.create(BASIC_TEST_WIN_NAMESPACE));

} catch (Exception e) {
throw new ContractException(e.getMessage());
}

return CONTRACT_IGNORE;
}

Here is the main method. Before, calling the Clojure routines, we first load the Spring application context:

The purpose of the outer Spring BeanFactory is to load our inner ApplicationContext instances. This is the Spring related stuff that isn't needed to work with Clojure, but if you did need to work with your existing Java libraries, this is one approach to use.


import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.beans.factory.access.SingletonBeanFactoryLocator;
import org.springframework.context.ApplicationContext;

import clojure.lang.Namespace;
import clojure.lang.RT;
import clojure.lang.Symbol;
import clojure.lang.Var;

public static void main(final String [] args) throws Exception {
final BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance(BEAN_FACTORY);
final BeanFactoryReference bf = bfl.useBeanFactory("com.lightedit.clojure.LightApplicationContext");
// now use some bean from factory
final BeanFactory beanFactoryContext = bf.getFactory();
final IContractHandler contract = new BasicTestWinMain();
contract.executeContract(beanFactoryContext);
}

Spring and Clojure are loaded at the application start and we also set a Clojure variable with the Spring context as its value. This is so that we can access the Spring beans at any time within our Clojure code.

;; Java Code:
;; // Call require on our utility clojure code
;; // Set the variable spring-context for use in the clojure script
;; Var.intern(Namespace.findOrCreate(Symbol.create(BASIC_TEST_WIN_GLOBALS)), Symbol.create("*spring-context*"), context);
;;
;; Clojure Use of the Context Instance:
(. *spring-context* getBean "testWinProperties")

Basic Lisp Programming in Clojure:
If you haven't worked with a Lisp dialect then you may not be used to the simple syntax. But I can guarantee that the syntax is simple. Idiomatic programming with Clojure may not be simple and it may take a while to master but the syntax is simple. Here is the basic BNF form for lisp:

expression = '(' expression* ('.' expression)? ')' | SYMBOL | NUMBER

Basically, expressions exist between a matching left parenthesis and right parenthesis. Typically, the first token is the function or macro and the rest of the tokens are the arguments. In this example below, the arguments 1 2 3 are passed to the ADD function.

bbrown@houston:~$ clj
Clojure
user= (+ 1 2 3)
6
user=

Here is the syntax to define a function and then call the function with one argument.
user=> (defn abc [arg1] (println arg1))
#'user/abc
user= (abc "123")
123
nil

SWT (Standard Widget Toolkit) and Clojure

There are only thirty or forty lines of Java code and 700-800 lines of Clojure code (with source). The Clojure code is a simple SWT application that has a main text area and six buttons. Each button contains an event. On the event, a separate Java process is launched.

  • light/test/win/basic_constants.clj -- Global string and other constant definitions.
  • light/test/win/basic_gui_utils.clj -- SWT Gui utilities, open dialog boxes, etc.
  • light/test/win/basic_test_utils.clj -- Misc string, regex utilties.
  • light/test/win/basic_test_window.clj -- MAIN set of routines to launch the SWT window, build the six buttons and establish the event handlers.
  • light/test/win/global_objects.clj -- Global instances of the main SWT widgets (the shell, the display, etc)

basic_test_window.clj


The basic_test_window.clj Clojure source is where everything gets started for the SWT application. With the code below, even though the syntax is in Clojure, you would use a similar approach in Java to build the SWT window. Also, these are just code snippets, see the downloads below to get the full source.
            
(defn create-shell [disp sh]
;; Note change in 'doto' call, dot needed.
(let [layout (create-grid-layout)]
(doto sh
(. setText *Basic_Window_title*)
(. setLayout layout)
(. addShellListener (proxy [ShellAdapter] []
(shellClosed [evt] (exit)))))))

(defn create-gui-window
"Initialize the SWT window, set the size add all components"
[disp sh]
(init-gui-helper disp sh)
(let [gd (new GridData SWT/FILL SWT/FILL true false)]
(. search-box addListener SWT/Traverse find-text-listener)
(. search-box setLayoutData gd)
(. location-bar setLayoutData gd)
(. status-bar setLayoutData gd))
;; Final init, set the window size and then open
(doto sh
(. setSize win-size-width win-size-height)
(. open))
;; Debug
(loop [] (if (. sh (isDisposed))
(. disp (dispose))
(let [] (when (not (. disp (readAndDispatch)))
(. disp (sleep)))
(recur)))))

(defn main-1
" Application Entry Point, launch the main window and wait for events"
[]
;;;;;;;;;
(println "Launching Text Test Viewer...")
(create-gui-window *display* *shell*)
(let [o (new Object)] (locking o (. o (wait)))))

Button start-process listeners:


;; Listeners and Event Handlers for Compiling and Running the Tests
;; The event will spawn a script process that compiles the tests of interest

;; Invoke the compile process and log the output to the main window"
;; The following tests are available:
;; compile, runtests, singletest, singlemem, singlehprof
(defmacro def-start-process [test-type]
`(let [test-props-bean# (. *spring-context* getBean "testWinProperties")]
(println "Attempt to start process, single class =>" (.getSingleTestClass test-props-bean#))
(start-process [ *process-gentests-sh* ~test-type
(.getSingleTestClass test-props-bean#) ] buffer-1)))

(defmacro def-button-listener [test-type]
`(proxy [~'SelectionListener][]
(widgetSelected [event#] (def-start-process ~test-type))
(widgetDefaultSelected [event#] (def-start-process ~test-type))))

basic_test_window.clj - SWT Source for Invoking the Main Window

The JUnit Clojure Tests:




Here is a portion of the Win32 script/process to launch the JUnit tests. Just a reminder, the GUI tool's only function is to launch this script. The script then launches the JUnit Java process or compile process.

...
...
:compile
REM -- run suite for just a single test --
%_RUNJAVA% %JAVA_OPTS% -classpath "%CLASSPATH%" -Dlight.install.dir="%INSTALL_DIR%" clojure.lang.Script ...
goto end

:runtests
REM -- run suite --
%_RUNJAVA% %JAVA_OPTS% test.light_test_suite ...
goto end

:singletest
REM -- run suite --
%_RUNJAVA% %JAVA_OPTS% ... test.light_test_suite_single ...
goto end

:singlemem
REM -- run suite --
%_RUNJAVA% %JAVA_OPTS% -verbosegc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps test.light_test_suite_single ...
goto end

:singlehprof
REM -- run suite --
%_RUNJAVA% %JAVA_OPTS% -verbosegc -Xrunhprof:file=classes/hprof_dump.txt,format=a test.light_test_suite_single ...
goto end
:end
exit /b

There are two steps to work with JUnit, compile the JUnit test cases by using Clojure's compile function and then running the application as you would normally run Java bytecode. Compile and Run. This is the source for compile_tests.clj:
(defn main []
(println "Compiling Tests")
(compile 'test.light_sample_test)
(compile 'test.light_mergelogs_test)
(compile 'test.light_test_suite)
(compile 'test.light_test_suite_single)
(println "Done Compiling"))

(try (main) (catch Exception e (. e printStackTrace)))

(. System exit 1)

Here is the source snippet for light_sample_test.clj:. When the bytecode is built for this class, it will resemble a typical class built with the javac compiler:
;; Make sure that the 'classes' directory exists
(ns test.light_sample_test
(:import (junit.framework Assert))
(:gen-class
:methods [[testDog [] void]]
:extends junit.framework.TestCase))

(defn -init [_] ())

(defn -testDog [_]
(println "Welcome to Light")
(Assert/fail "Test not implemented"))

Application Usage:

Install: The best way to install and use the test GUI is to install all of the files into:

c:\usr\local\projects\testtoolkit (/usr/local/projects/testtoolkit on Linux) directory. For example, testtoolkit is LIGHT_HOME:

Z:\> cd "c:\usr\local\projects\testtoolkit"

Java Runtime 1.5 or greater is required.
WIN32:

In a win32 environment (Cygwin or through the Windows Command Line), the best way to launch Light is to execute the light.bat batch script.
Z:\> light_test.bat (or light_test.bat in cygwin)

Dependencies


Like a lot of Java/J2EE applications, this application requires a number of third party libraries. Spring, Clojure and SWT are the main ones. The libraries are already included in the download file, but here is a listing of the jar files and how they are used.

  • clojure.jar - Clojure programming language, full library (vers 200903)
  • octane_commons.jar - Jar file that includes the simple Contract binary and Bootstrap Clojure/Spring code. See the source listing below.
  • swt/linux/swt.jar - SWT jar for linux, Standard Widget Toolkit library.
  • junit-4.4.jar - Junit 4.4
  • spring/spring-custom.jar - Spring 2.5 library (contains only a subset of the spring libraries for use with this application)

Additional Source Code Modules


  • light_test.bat - Batch script for Win32 (Note: it is advised to use the hardcoded path, 'C:\usr\local\projects\testtoolkit')
  • light_test.sh - Batch script for Linux

  • build.xml -- Ant build script for building the Java bootstrap source
  • src/com/light/clojure/BasicTestWinMain.java -- Java source for bootstrapping Clojure and loading the Spring configuration
  • src/com/light/clojure/test/TestWinProperties.java -- Simple bean used with Spring, contains only one field. We use constructor injection to set the value.
  • src/com/light/contract/BasicContractHandler.java -- Simple design by contract oriented library
  • src/com/light/contract/IContractHandler.java -- Simple design by contract oriented library

Source Code

SVN Directory for Clojure GUI Application
example_clojure_swt.tar.gz - Source and Binary

References

clojure.org

[1] Clojure API Examples

[2] SVN Browsable Source for this Project

[3] http://java.sun.com/docs/hotspot/gc1.4.2/example.html- Diagnosing a Garbage Collection problem

[4] Most Comprehensive Java Perf Guide - http://www.javaperformancetuning.com/

[5] http://oreilly.com/catalog/javapt/chapter/ch04.html- More good performance tips.

[6] https://hat.dev.java.net/ - Heap analysis tool. This tool is included with JDK6.

[7] Java technology, IBM style: Garbage collection policies, Part 1

Contact me for additions to the entry or other comments:
Berlin Brown - berlin dot brown at gmail.com

Blog Entry Updates:
  • 4/4/2009 - Initial Blog Entry Version

----------