Sunday, 28 December 2008

Scala, Ant

An example of building Scala applications using Ant and the Scala Ant tasks:

In the complete Ant build file given below, the key lines are:


<taskdef resource="scala/tools/ant/antlib.xml">
<classpath>
<pathelement location="${scala.home}/lib/scala-compiler.jar" />
<pathelement location="${scala-library.jar}" />
</classpath>
</taskdef>
Which loads the task definition

scala-library.jar defines Scala tasks for Ant, these are:
  • scalac
  • fsc
  • scaladoc

Note: The Scala library scala-library.jar must be present in the Java class path. The actors and dbc libraries are available as separate JAR files: scala-actors.jarand scala-dbc.jar.


Example build.xml

// LJB 28-12-2008 - basic scala Ant build
<project name="Scala test" default="build" basedir="../">

<property name="base.dir" value="${basedir}" />
<property name="sources.dir" value="${base.dir}/src" />
<property name="build.dir" value="${base.dir}/build//classes.tmp" />

// take scala ant libs from scala installation, assumes SCALA_HOME is set to home of scala in env vars
<property environment="env"/>
<property name="scala.home" value="${env.SCALA_HOME}" />

<target name="init">

<property name="scala-library.jar" value="${scala.home}/lib/scala-library.jar" />

<path id="build.classpath">
<pathelement location="${scala-library.jar}" />
<!--<pathelement location="${your.path}" />-->
<pathelement location="${build.dir}" />
</path>

<taskdef resource="scala/tools/ant/antlib.xml">
<classpath>
<pathelement location="${scala.home}/lib/scala-compiler.jar" />
<pathelement location="${scala-library.jar}" />
</classpath>
</taskdef>
</target>

<target name="build" depends="init">

<mkdir dir="${build.dir}" />

<scalac srcdir="${sources.dir}"
destdir="${build.dir}"
classpathref="build.classpath"
force="changed">

<!-- <src location="src" /> -->
<include name="**/*.scala" />
</scalac>
</target>

<target name="run" depends="build">
<java classname="test.Test"
classpathref="build.classpath">
</java>
</target>
</project>




Project directory structure:

/build
/build/build.xml
/src
/src/test.scala


Example "hello world" Scala test program


package test

object Test {

def main(args : Array[String]) {

println("Hello world")
}
}


If you type ant run in the /build directory, the application is compiled and run, giving "Hello world"...


References:

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


.

Saturday, 27 December 2008

Scala - object, singletons, classes and constructors

Today, a simple example by way of explanation of the basic constructs of OO in Scala.

Things to note:
  • Scala does not use static methods, in this sense Scala is more purely OO than Java.
  • The equivalent is achieved using object singletons and companion objects.

The following code example demonstrates:

  • Use of object singleton and "main" application entry point
  • Declaration of new objects
  • Declaration of new class
  • Class primary constructor
  • Declaring fields
  • Declaring alternative constructors
  • Use of override keyword

Example Code:

package test

// object declares a singleton (like Java static)
object Test {
// the usual main, takes an Array[String] of arguments
def main(args : Array[String]) {

var myClass1 = new MyClass(5, "Louis") // using primary constructor
var myClass2 = new MyClass(10); // using alternate constructor

// access public field value
println("myClass1.value1 = " + myClass1.value1)

// output using overriden toString
println("myClass1 = " + myClass1)
println("myClass2 = " + myClass2)
}
}

// define MyClass and its primary constructor (Int, String)
class MyClass(v1 : Int, s1 : String) {

// these are fields (public)
def value1 : Int = v1
def string1 : String = s1

// this is an alternate constructor (calls primary constructor)
def this(v1 : Int) = {
this(v1, "hello")
}

// can override toString like in Java, note no return statement required + the override keyword
override def toString() : String =
{
"MyClass: (" + value1 + ", " + string1 + ")"
}
}

Wednesday, 24 December 2008

Scala, an introduction

Scala - "Scalable Java": a new Language which combines both Object Orientated and Functional programming paradigms.

Scala is an extension of Java and runs on the JVM. Scala draws from languages such as Java, Smalltalk, Erlang and many others.

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

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

Installation, using the IzPack Scala installer jar, run: java -jar scala-x-installer.jar


Scala - main features:
  • Integrates with Java (is an extension of Java), and shares libraries and primitive types
  • Compiles to Java byte code - runs on JVM (also can be run on .Net)
  • Imperative and functional support
  • Object Orientated (classes, objects)
  • Functional (functions as first class objects, referential transparency)
  • Statically typed
  • Type inference (more concise code that looks more like Dynamic/duck typed, but has the benefits of static / strong typing)
  • Supports closures and function literals
  • Concurrency model using Erlang Actors system (a 'safer' concurrency model)
Scala can be run stand alone, using the command line interpreter - using the "scala" command.

Scala also has plugin support for NetBeans, Eclipse and InteliJ


Syntax Overview:
  • Type inference means most type declarations can be omitted (but can still be explicitly declared).
  • Variables are defined as name : type rather than type name as per Java
  • Semicolons are often optional
  • Does not specify or define operators. +-*/ etc are valid method names are defined as such for appropriate types
  • var and val keywords - val declares a constant type (like Java's final, not reassignable), var declares a variable that can be reassigned. val, like var can still be mutable however, if the type is mutable.
  • Functions, declared using def keyword. e.g. def myFunction(x: Type1, y: Type2) : ReturnType
  • Pre and post increment/decrement (i++, ++i, i--, --i) are not supported, use i = i + 1 or i += 1
  • Recommended indentation is 2 spaces
  • Imperative for loops not supported, the functional equivalent, a for Expression is used instead
  • Arryays are indexed using (n) not [n]
  • Type parameters are specified using [type]. If both type and index are used, the ordering is [type](params)
  • Scala supports infix as method calls. e.g. 1 + 2 is equivalent to 1.+(2) where + is not a special operator, but a regular method
  • Applying () to an object (recipient) is equivalent to calling .apply() on it. e.g. myThing(i) is equivalent to myThing.apply(i)
  • The receiver of an = operator is equivalent to calling .update. e.g. myThing(i) = value is equivalent to myThing.update(i, value)
  • Method association is by default to the left, unless the method ends with a colon : e.g. 1 + 2 applies + to 1 giving 1.+(2) whereas x :: y applies :: (cons) to y, giving y.::(x)
  • The List type supports ::: (concat) and :: (cons, prepend), both apply the operation and return the resulting new List
  • Arrays are always mutable, lists are always immutable. Sets and maps can be either, the default is immutable (from the trait scala.collection.immutable) but the mutable equivalents can be imported from scala.collection.mutable
  • The -> method provides Implicit Conversion. e.g. x -> y is x.->y which returns a key/value tuple containing x as the key and y as the value

Some simple Functional examples:

Print all command line arguments, using foreach, passing println function:

Verbose:
args.foreach((arg: String) => println(arg))

Type inference on arg:
args.foreach(arg => pringln(arg))

Concise:
args.foreach(println)

The last example is a shorthand that can be applied when a function literal cosists of one statement that takes one argument - known as a Partially Applied Function.


For Expressions:

Replacing imperative for loops, the syntax is of the form:

for (arg <- args)
println(arg)


Note: In the above for expression example, arg is a val (final/const) not a var, and a new val variable is created for each "iteration".

or

for (i <- 1 to 30) ...


Declaring Arrays:

Very concisely:

val myArray = Array("value1", "value2")

defines a string array (type inference) of size 2

This is equivalent to:

val myArray = Array.apply("value1", "value2")

where apply is called on the Array Companion Object

More Verbosely the array could also be declared more traditionally as:

val myArray = new Array[String](2)

or even

val myArray : Array[String] = new Array[String](2)

but the former concise approach is the Scala recommended way, the later hints at the underlying Java roots.

Lists:

Defining new lists is easy with the cons method, as follows:

val myList = 3 :: 2 :: 4 :: 5 :: Nil // Nil is the Empty List, also so is List()

Note: The Nil (empty List) is needed so that working from right to left, the :: method is defined on Nil, which first gives Nil.::(5) returning List(5) which then gives 5.::(4) resulting in List(4, 5), and so on. Without the Nil there is a syntax error as :: (cons) is not defined on 5 (which is of type integer).


Examples:

Factorial ! - Simple factorial, defined in a functional way:

def factorial(value : int) : int = { if (value == 0) 1 else value * factorial(value - 1) }

scala> factorial(10)
res15: int = 3628800


Triangle Numbers:

def tri(x : Int) : Int = { if (x == 0) 0 else x + tri(x-1) }

scala> tri(4)
res14: Int = 10


Scala for scripting:

Scala scripts can be run using scala myscript.scala

Additionally, Scala can be used as a self contained scripting language by invoking the scala command line interpreter with the script, as follows:

On 'nix platforms

#!/bin/sh
exec scala "$0" "$@"
!#
println("Hello world, hello " + args(0))

Don't forget to give the script execute permissions (chmod +x myscipt)

Execute: myscript Louis

A similar thing can be achieved on Windows...


Scala with build systems:


With Ant:

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


With Maven:

http://scala-blogs.org/2008/01/maven-for-scala.html


Further Resources:

Books:

Artima book (excellent): http://www.artima.com/shop/programming_in_scala released 17th Nov 2008, by Martin Odersky, Lex Spoon, and Bill Venners.

Source code for book examples: http://booksites.artima.com/programming_in_scala/progInScalaExamples1EdV6.zip

Browse book examples: http://booksites.artima.com/programming_in_scala/examples

OReilly Programming Scala: http://programming-scala.labs.oreilly.com/


Blogs:

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

Blog on Monads: http://james-iry.blogspot.com/2007/09/monads-are-elephants-part-1.html


Articles:

Java refugees: http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-1


Build tools:

SBT: http://code.google.com/p/simple-build-tool/


Interesting Blog about Scala and Lift (using Maven and Jetty).

http://scala-blogs.org/2007/12/dynamic-web-applications-with-lift-and.html


SIDs (software improvement Documents):

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


Monads:

http://projects.tmorris.net/public/what-does-monad-mean/artifacts/1.1/chunk-html/ar01s04s04.html

http://vimeo.com/8729673


IRC channel: #scala on irc.freenode.net


(Also (unrelated): pastie - http://pastie.org/ is handy for pasting those odd snippets of code around on the internet/IRC).


Interesting blog about Scala type-safe SQL / DB - SQuery - http://szeiger.de/blog/2008/12/21/a-type-safe-database-query-dsl-for-scala/

Updated (13-09-2009): Came across this useful presentation: http://www.slideshare.net/astubbs/scala-language-intro-inspired-by-the-love-game?src=embed


99 Scala problems - an adaption of the 99 Prolog problems into Scala:

http://aperiodic.net/phil/scala/s-99/#p10


.

Sunday, 21 December 2008

PCWiz Mac OSX under VMware (2.0)

(Note - I do not condone the use of illegal / pirated software. If you're going to use Mac OSX, please support Applet and buy a license for the OS.)


Mac OSX can be run under VMware, using a special build such as the "pcwiz" version.

http://pcwizcomputer.com/index.php?Itemid=48&id=76&option=com_content&task=view
  • Performance is slow, but just about usable.
  • There's naturally no vmware tools at this time.
  • Networking can be made to work.
When it comes to the screen resolution, there are no drivers as such to adjust but the screen resolution settings can be modified - see here for further details: http://pcwizcomputer.com/index.php?option=com_content&task=view&id=31&Itemid=45


.

Saturday, 13 December 2008

OpenOffice (3.0) / UNO API

Recently a project needed some reporting enhancements (spreadsheet charts) for which Apache POI didn't provide the necessary support. So, after some exploration, I decided on using OpenOffice with it's API, in this particular instance it was OpenOffice 3.0m9 (latest at the tine of writing) and the UNO Java API.

www.openoffice.org

OpenOffice provides some very powerful tools, including Spreadsheets, Documents, PDF etc along compatibility with MS Office. In addition, OpenOffice is quite powerful at convertion document types and between versions. For example a MS word document could be loaded and then saved as a PDF.

OpenOffice - www.openoffice.org
Forum - http://user.services.openoffice.org/en/forum/
Wiki - http://wiki.services.openoffice.org/wiki/Main_Page (including good developer section)
FAQ - http://wiki.services.openoffice.org/wiki/Uno/FAQ

The OpenOffice suite comes with an SDK and the UNO API, supporting various languages, including Java.

SDK download - http://download.openoffice.org/3.0.0/sdk.html

The SDK/API is based on UNO (Unified Network Objects) which is an alternative/competator to COM, like CORBA etc, and allows the remote (out of process) communication and control of OpenOffice - "UNO is a component model that offers inter-operability between different programming languages, different objects models, different machine architectures, and different processes; either in a LAN or via the Internet."

Another acronym is URE - "Each component lives in a Uno Runtime Environment (URE). A URE is identified by the implementation language (e.g., C++, Java, Perl, ...) and the current process."

See here for more details: http://udk.openoffice.org/common/man/uno.html

When using OpenOffice on the server side to provide reports (in my case, as part of a web application), various SDK jars are needed along with a means to find the OpenOffice installation.

The Java jars needed are:
  • juh.jar
  • jurt.jar
  • ridl.jar
  • jut.jar
  • unoil.jar

I chose to include them in my web application WAR file.
This can create problems, because the classpath to the jars will not be where OpenOffice is installed, to work around this the Java classes from the SDK can be loaded and bootstrapped in the class loaded, but this is tricky when using a web app container. For convienience I made use of the useful bootstrapconnector.jar utility library. This library can connect to OpenOffice regardless of the location of the jars, it just needs a path to an OpenOffice installation, which I set as an ENV variable called UNO_PATH.

BootstrapSocketConnector - http://user.services.openoffice.org/en/forum/viewtopic.php?f=44&t=2520

I also made use of the OpenOffice plugin for Netbeans 6.5 to get a quick start developing the code, before moving to the production solution.


Some things to watch out for:

One problem I stumbled into. Installing OpenOffice for the first time on a remote Linux (CentOS) machine over a terminal, when I came to run the web application the program appears to hang. Some investigation with ps showed that soffice was being started, but that I was getting many instances, all apparently hung. I replicated the setup on a different Linux installation, this time one with a desktop / display manager. It was then obvious what was happening, the first time OpenOffice is launched, it prompts the user with a registration wizard! Oops.

So the solution to this is simple, pass an option when launching the OpenOffice process, this can be achieved conveniently using the bootstrapsocketconnect with something like the following:

// Create OOo server with additional -nofirststartwizard option
List oooOptions = OOoServer.getDefaultOOoOptions();
oooOptions.add("-nofirststartwizard");
OOoServer oooServer = new OOoServer(OOO_EXEC_FOLDER, oooOptions);

// Connect to OOo
BootstrapSocketConnector bootstrapSocketConnector = new BootstrapSocketConnector(oooServer);
XComponentContext remoteContext = bootstrapSocketConnector.connect();


.

Sunday, 7 December 2008

JSON, Java and JavaScript

JSON is so simple there's not a lot to say about it, but I thought it's worth putting up a few links and notes for reference.

JSON is JavaScript Object Notation. Whilst it could be called an Object Notation (a simple one), it's not tied to JavaScript, although it's early origins are from that language (ECMAScript, ECMA-262 3rd Edition). JSON is essentially language independant, like XML. JSON, like XML can represent data structures and data (self describing) but unlike XML, JSON does not support namespaces, schema and other more advanced features. JSONs key strengths are its simpicity and low overhead, terse message size.


JSON looks like this:


{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": 10021
},
"phoneNumbers": [
"212 555-1234",
"646 555-4567"
]
}


Where { and } contain the object, the properties are listed as "name" : "value" pairs. Objects can be embedded within objects and arrays are denoted using comma separated lists within []

So, special symbols (for escaping) are: {}[]:"

Main Site: http://www.json.org/

Simple JSON for Java: http://www.JSON.org/java/json_simple.zip http://www.json.org/java/simple.txt

Simple JSON for JavaScript: http://www.json.org/js.html

Wikipedia: http://en.wikipedia.org/wiki/JSON


JavaScript:

Basic suppport for converting JSON messages into objects (deserialisation) is to use the often best avoided eval function, as follows:

var myObject = eval('(' + myJSONtext + ')');

where the outer '(' ')' are necessary for the JavaScript language, not JSON itself.

Better (safer) still, various libaries are available, such as the Open Source version from www.json.org in json2.js

Which essentially is used like this:

var myObject = JSON.parse(myJSONtext, reviver);

var myJSONText = JSON.stringify(myObject, replacer);


Java:

Create a JSON string using org.json.simple.JSONObject:

JSONObject obj=new JSONObject();
obj.put("name","foo");
obj.put("num",new Integer(100));
System.out.print(obj);

The toString() on the JSONObject serialises the JSON object (map of name value pairs) to a JSON string.

JSON is simple, by design, so there isn't much more to be said on it.

One of the main things to watch out for is encoding/escaping messages so they are JSON friendly, I'll add more on that soon.

The following link may be useful when working with character escaping: http://www.the-art-of-web.com/javascript/escape/

.