Monday, June 8, 2009

Is Javaless Java reaching critical mass?

There is a lot of talk about how this is possibly the last JavaOne, as Oracle is about to buy Sun out.

However if you look at what everybody was at talking about at JavaOne you can't but help get the idea that JavaOne is an anachronism any way, this trend seems to involve:

- JavaFX.
- Groovy.
- Scala.
- JRuby.
- Honourable mentions for Clojure and Jython.

It's hard to miss the lack of Java here...

Ok so people are interested in other languages in the JVM, however interest doesn't necessarily translate into use.

This brings me to my question: have alternative JVM languages gone mainstream? can I go to my client who is still trying to get COBOL out of their system and confidently sell him on one of these alternative languages?


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Monday, June 1, 2009

Enterprise Scala Beans

This is a "hello world" tutorial to show how to get a Scala class configured to run as an EJB 3.0 inside a JEE app server, in this case Glassfish V2.

Why exactly are you doing this?

Well mostly to see if it's possible, one of Scala's benefits is the fact that it runs on a Java Virtual Machine with Java interoperability as a feature, this would allow developers to make use of Scala's additional language features to create a little more concise code and still make use of an enterprise's existing investments in JEE.

First up.

To create EJB3.0 beans, a language will need to support the following:

- A compiler which compiles to standard Java classes (with the actual implementation bean using the standard no-args constructor for instantiation).
- A construct which can map logically and physically to a Java interface in order to support the EJB's local and remote interfaces.
- Annotations (although you could get away with ejb-jar.xml but that sucks) in order to integrate into the EJB container.

Huh?! you need interfaces! Scala doesn't have interfaces!.

Scala does not have interfaces per se, however it has traits (basically interfaces which allow implementation of methods). As it turns out Scala compiles the basic type skeleton specified by the trait into an interface.

Now with that out the way here's the code:

First we define the Trait which will serve as a remote Interface, for our example we are going to define a simple trait called ITest:

package net.jexenberger

trait ITest {


def doStuff(x: String) : String;

def hello() : Unit = {
System.out.println("hello world");
}


}

This trait has one unimplemented method and one implemented method (this is to illustrate that you don't lose the functionality of traits with Scala when you have to work in a pure interface world).

Secondly we define the actual implemention of the trait ITest in a class TestBean as follows:

package net.jexenberger

import javax.ejb._;
import javax.annotation._;

@Stateless { val name="ScalaTestBean", val mappedName="ScalaTestBean" }
@Remote {val value = Array(classOf[ITest])}
class TestBean extends ITest {

@Resource
var ctx:SessionContext = null

def doStuff(x : String) : String = {
"hello "+x+" called with "+this.ctx.toString()
}

@PostConstruct
def postConstruct() : Unit = {
System.out.println("Post Construct called");
}

}

Note the following about the implementation:

Firstly you will see that annotations are defined almost exactly the same as in Java, however the annotations have been "Scalafied" to look more Scala like with the use val and functions and of course Arrays, as illustrated by the @Remote usage above the class declaration. Finally we also inject the java.ejb.SessionContext object as an instance variable ctx and a @PostConstruct method; postConstruct(), this is to test that we can map Scala variables and methods directly to Java methods and variables in order to utilise the EJB container's dependency injection mechanism and to integrate into the EJB lifecycle.

We can now package the bean into a standard java jar (with META-INF/ejb-jar.xml if required), it can then be deployed as part of an EAR or indeed as a standalone EJB application. I built and packaged the project using Maven's standard maven-ejb-plugin and the Maven Scala plugin (org.scala-tools.maven-scala-plugin).

Finally we write a remote client to invoke the Scala EJB:

package net.jexenberger;

import java.util.Properties;
import javax.naming.Context;

public class JavaTest
{

public static void main(String[] args) throws Exception {
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");

Context ctx = new javax.naming.InitialContext(props);
ITest instance = (ITest) ctx.lookup("ScalaTestBean");
System.out.println(instance.doStuff("world"));
instance.hello();

}

}

Note that is a straight Java class, used to illustrate that the EJB could still be consumed by using straight Java code, also note that ITest is recognised as a standard Java interface.

The output produced by by running the client is:

net.jexenberger.personal._ITest_Wrapper@4a1c06a1
hello world called with ScalaTestBean; id: [B@12d9e34

And on the server we get:

[#|2009-06-01T13:13:12.538+0200|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=23;_ThreadName=p: thread-pool-1; w: 9;|
Post Construct called|#]

[#|2009-06-01T13:13:12.541+0200|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=23;_ThreadName=p: thread-pool-1; w: 9;|
hello world|#]

And there we have it. An EJB 3.0 compliant Scala Enterprise Bean!

A final note on packaging and deployment:

Scala obviously requires its supporting runtime and libraries, in order to do this, you will need to package and specify the dependencies in an EAR or copy it into a location in your app Server. In Glassfish the easiest thing to do is copy scala-library.jar to [Glassfish home]/lib/endorsed.


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Thursday, May 28, 2009

First iPhone application: iBoredom

Yes this is a shameless punt...

But hey, if you like it, buy it

It's and iPhone app called iBoredom, the perfect companion for when you are bored...

It aggregates sites with a random content feature like Stumbleupon and wikipedia and allows you to randomly browse content, almost like a remote control.


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Wednesday, May 6, 2009

A Groovy DSL for working with the filesystem.

I've recently come back to the idea of using Java as a shell scripting tool. There are a couple of reasons for this; firstly Java is familiar with all my developers, secondly Java's startup time has seriously improved with the 6u1x series of the Hotspot VM, finally Java has a brilliant dynamic language which slips over core Java in the form of Groovy.

However there are still some problems; the most immediately obvious is the fact the shell scripting often involves a lot file manipulation and calling of external processes, tasks which involve a lot of navigation around the file system. 

Unfortunately Java has never had a chdir() function, so that means you have to work with everything as an absolute file path, often resulting in some nasty string based code.

Fortunately Groovy can overcome this with it's ability to create Domain Specific Languages. We can use these features to map to standard file system concepts.

Lets take the following bash script. This script creates a directory in the home folder, downloads and unzips a contrived application called myapp into the directory and then creates a shortcut link on the desktop:


# create directory in home
mkdir ~/myapp
# change to directory
cd ~/myapp
# download myapp.zip with wget
wget http://www.myapp.com/download/myapp.zip
# extract myapp.zip using unp
unp myapp.zip
# delete myapp.zip
rm myapp.zip
# change Desktop in home
cd ~/Desktop
# create shortcut and append an entry to the executable to myapp
> myapp.desktop
echo "Exec=${HOME}/myapp/myappExecutable" >> myapp.desktop

While we couldn't map this exactly in Groovy we could at least do something similar, this is what I came up with:

//create the my app directory in home
myAppPath = (~Path + "myapp")
//download and extract
myAppPath.exec "wget -q http://www.myapp.com/download/myapp.zip" .exec "unp myapp.zip"
//delete myapp.zip
myAppPath - "myapp.zip"
//create a pointer to myApp executable
myAppPath/"myAppExecutable"
//create shortcut in Desktop folder
~Path/"Desktop"/"myapp.desktop" >> "EXEC=${myAppPath}"

How would we accomplish this in Groovy.

First we define a class called Path with the ability to ability to build up a path via an append method and a toString method to create a string representation of the path:

public class Path {

Stack pathStack;

Path {
pathStack = new Stack();
}

public append(String element) {
pathStack.push "element"
return this
}

public String toString() {
//code to build up the path from the stack
.....
}

}

Now we use Groovy's operator overloading feature to be able to add write pathInstance / "aPathelement", to do this we simply implement the method div on the Path class:

public div(String element) {
return append element;
}

Next we want to be able to quickly get an instance of Path which points to the home directory quickly. I wanted to map this to Bash's '~' home folder expansion. Fortunately we can implement this by overloading the bitwise operator on a static method on the path object:

public static Path bitwiseNegate() {
return new Path()/System.getProperty("user.home")
}

This allows us to write ~Path to create a Path instance to point to the home folder.

Next we want to be able to easily add a new folder to the existing Path instance and then point the Path instance to the new directory by overloading the + operator by implementing the add method:

public Path plus(String element) {
this / element
f = new File(toString())
if !(f.exists()) {
f.mkdirs()
}
return this;
}

Now we need to implement an exec method to execute processes in the directory specified by the Path instance:

public exec(String command) {
//test that the path is a directory
...
command.execute(new File(this.toString(),null)
return this
}

We also need to be able to delete the file by overloading the '-' operator by creating a minus method:

public Path minus(String element) {
this / element
f = new File(toString())
f.delete();
return this;
}

Finally we want to be able to easily write to a file, we can map to to the unix ">>" shell command which is normally used to route a processes std.out to an existing file (kinda what we are trying to do). We can do this by overloading the right shift operator by implementing the rightShift method:

public Path rightShift(String valueToAppend) {
f = new File(toString())
if (!f.exists()) {
f.createNewFile()
}
f.append valueToAppend
return this
}

And there we have enough to implement the script example. It is however worth noting that the Path class is far from complete. For example another common task would be to list the contents of a directory and filter via a regular expression, so we can add a method each which takes a regex and a closure to handle each file as a Path instance:

public each(Pattern p, Closure c) {
new File(toString()).each {
if (p.matcher(it).matches()) {
//..clone current path
Path newPath = ...
newPath / it
c.call(newPath)
}
}
}

now you can write:

~Path.each /foo/ {
//do stuff with it
}

However Groovy allows you to call a method as a string literal for example to call x.toString() you could use x.'toString'(), furthermore we can intercept method calls to methods that don't exist, and enhance this a little and rewrite the former as:

~Path.'/foo/' {
//do stuff with it
}

To do this we implement the invokeMethod to handle the non existent method:

public invokeMethod(String name, args) {
if (name.startsWith("/") && name.endsWith("/") {
//strip out regular expession and create Pattern object and assign to 'createPattern' variable
each(createPattern, args[0]);
} else { //blow up
}
}

So there we have it. Of course this class is not complete, we can add additional methods to do additional operations such as iterating through the elements in the Path instance. Furthermore we might be able to further enhance the class by utilising Groovy's Meta Object Protocol.

A full Listing of the Path class can be found here.


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Friday, May 1, 2009

Java and Oracle, the real question.

So unless you've been living under a rock, you know that Oracle is buying Sun. And of course one of Larry Ellison's motivators to do so is to gain control of Java.

Feelings on how this will affect Java run the gamut from "Blissfully happy" to "The end is nigh".

The press seems to look at Java aspect of the acquisition regarding the product overlap and how little money Sun made off Java. They also seem to view Java as purely an enterprise play, This is an incredibly narrow view as makers of everything cell phone apps to desktop apps to Blu-ray applications will happily attest to.

Java is not a product in the traditional sense of the word, Java is more a community marketplace centered around the Java technology as opposed to a shrink wrapped product.

Java's real value IMHO is then in it's vast reach both in the general development landscape and the vast community of programmers, not so much in the IP or the source code that makes up the JVM.

My question is then if Oracle realizes this.

Community is something that Oracle has not traditionally had to deal with.

Oracle has always been a product company focused on generating healthy margins of all of it's products from a set of clients with deep pockets.

It is now in a position where it will need to support and grow a community of Java users which provide little or no tangible benefit to Oracle's bottom line.

There are many examples of this.

One such example is Glassfish which overlaps with Weblogic and seemingly has no place, however Oracle is now in charge of the JCP and as such has to provide reference implementations for the specifications somehow. Glassfish currently fulfills this role. They could maybe use Geronimo or even JBoss but in a space that will eventually commodotize, it might a bad idea to promote a competitor. Oracle may decide to cripple Glassfish purely to be used for reference but then the fact remains that they have to expend resources on a piece code which makes them no money in order to support the Java community.

Another is the fact that the Java community also consists of companies that compete directly with Oracle. Oracle as the Java shepard must now support these competitors: most notably IBM; the 800 pound Gorilla of the Java community. Strategically it's better for Oracle and IBM to jointly run Java even as competitors lest they both cede a great deal of the Enterprise market to Microsoft. Oracle must therefore keep IBM happy, potentially even spend money to keep them happy in order to preserve the status quo. It must also do the same for it's smaller competitors to expand the reach of Java as far as possible.

Finally Oracle now enters into strange new markets through Sun's acquisition. Oracle's never had any presence in places like the embedded market and now must do work for people who make such strange things as cell phone applications and software for set top boxes, many of whom will never even see an Oracle database or an Oracle App server. Oracle must now keep them happy potentially at margins which don't quite resemble what they make on 11g CALs together with the reality that there is little chance to sell other Oracle products.

No doubt Oracle's shareholders will want Larry Ellison to make good on Sun's purchase but to fit Java into the way Oracle traditionally does things is probably not going to work and might very well end up killing Java.


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Saturday, December 20, 2008

It's recession time and Sun has the best recession kool aid.

So you're a CIO and you have several projects to deliver. The only problem is that you've had your budgets slashed.

What is a CIO to do....

Well I don't know if anyone has noticed but one of the coolest recession friendly enterprise software stacks around is being offered by that company we all love to hate: Sun Microsystems.

Consider this:

Sun has a really cool application server which is fully buzzword compliant in the form of Glassfish. Besides the fact that its pretty scalable with old Grizzly, it comes with a rock solid ESB and messaging system, A decent compatible web service stack, and on top of that it is dead simple to administer. And then of course lets not forget the awesomeness that is Glassfish 3.0.

Now Java and JEE can be a little heavyweight, but that's no problem, Sun supports Ruby and Ruby on Rails and has a Ruby interpreter that really rocks in the form of JRuby, and the best part is that you can run it on said application server. And If Ruby is not too your taste, don't forget Groovy and Grails, and soon Python with Django, and if you really want to go exotic there is Scala and Lift. All using it's battle tested core runtime environment otherwise known as Hotpsot.

Of course now you need to save your precious data in a database. Databases of course tend to be notoriously recession unfriendly. Once again Sun provides a proven lightweight solution in the form of MySQL.

Finally no system is complete without a little bit of User interface. Sun provides a good web stack with Glassfish, however you wanna got fat. No problem, JavaFX now provides a good fat solution.

So now you have all the libraries and runtimes, what about an IDE. Once again we have Netbeans, an increasingly one stop shop for doing development, besides doing Java and C++ it does Ruby, Groovy, Scala, JavaScript, PHP and it's newest addition: JavaFX, all with a simple easy interface and allows you to get up and running very quickly.

It's also worth mentioning that Sun also offers a slew of other tools, everything from a continuous integration server in Hudson to an identify management system in the form of OpenSSO, and countless other products.

Once you have all that together, you need an OS to run it all on. Once again you have the increasingly interesting looking OpenSolaris, or it's commercial brother Solaris, which once it's all said and done, is still one of the best OSes on the planet.

Now what is really cool about this whole stack is that everthing I've mentioned here is either open source or free, with support contracts available. If you wanted you could download all individual components and not cost to you, that's right no cost. How recession friendly is that.

But wait there's more, since you've saved all this money on software, why not look at some of Sun's hardware, which includes everything from fast Opteron servers to those Sparc boxes with like a gazillion CPU cores. Then of course there are those Jaw dropping ZFS based Open Storage systems.

So there you have it: If you need to get some bang for your buck, have a look at Sun: your one stop shop for all things EIS.

There is unfortunately one small little caveat...

Sun either isn't interested in dishing out it's kool aid, or is trying too, but no one seems to understand where to get some.

My employer recently bought a whole stack of stuff, and based on what they where looking for a stack like the one I presented here would have appealed to them. All Sun would have had to do, is bundle it up under the banner of a product suite and do some old fashioned selling.

The worst part is that I don't think the Sun people understand what they have. When you watch a Sun presentation you get bombarded with Sun's entire portfolio of products, the only problem is that they present them as a mass jumble of vaguely related products which simply overloads the presentee with information. There's no common theme to say: this is the value proposition we are giving to you.

Now I don't represent Sun in any capacity, but I would find it incredibly sad to see a company that does so much cool stuff fold, and see all this cool stuff potentially disappear.


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Sunday, August 10, 2008

A simple MP3 Player in JavaFX

This is pretty much my first attempt at JavaFX and after looking around I wasn't able to find much about using the media player capabilities of JavaFX so I decided to create a simple MP3 player to basically get up and running with JavaFX.



So, for a start what does JavaFX give us in terms of media APIs.

Well the JavaFX SDK contains the javafx.scene.media package which contains the classes for using media within your application.

This package consists of the following classes:

  • Media : This class wraps a media source, i.e: in this case the location of the MP3 file.

  • MediaPlayer : This class provides functionality to drive the playback of a Media instance.

  • MediaError: This class represents an error that occurs during media playback.

  • MediaTimer: This class allows you to execute actions at an interval during the playback of media.

  • MediaView: This class is a visual component for displaying your media in the case of video.


  • For the purposes of this blog I'm only going to focus on the Media class, MediaPlayer class and MediaError class since these are enough to create a very basic MP3 player.

    Media Playback using the MediaPlayer class.
    So the first thing to do is create a most basic MediaPlayer instance:

    var player =
    MediaPlayer {
    repeatCount:MediaPlayer.REPEAT_FOREVER
    onError: function(e:MediaError) {
    display = e.message;
    }
    };


    You can see here that I've set two attributes: repeatCount and onError.

    The repeatCount attribute indicates if the media should loop or play once and then stop. The values for repeatCount are defined as constants on the MediaPlayer class, I've selected MediaPlayer.REPEAT_FOREVER in order to loop playback.

    Note: if you leave out repeatCount, playback will not occur (and no error is thrown either if you don't set it, which led to a rather annoying few hours for me).

    The onError attribute sets a closure (anonymous function) which gets executed when an error occurs. The closure is passed an instance of MediaError to indicate what happened. In my example I simply set a variable called display, which I bound to a Text node in the UI.

    Controlling the MediaPlayer class.
    The next thing we need to do define a method to control your player. MediaPlayer has two methods on it which allow you to control it: play() which starts or resumes playback and pause() which allows you to stop (but not reset) the current media playback in the player. For my example I wrote a very simple Button which stops and starts my MediaPlayer instance based on the button's state and the player's state:

    Button {
    enabled : bind enabled
    text: bind text
    action: function() {
    if (text == "Stop") {
    player.pause();
    text = "Play"
    } else if (player.media != null and text == "Play") {
    player.play();
    text = "Stop";
    }
    }
    }

    Nothing very fancy here, when the Button is clicked in Playing state I call player.pause(), if it's in Stopped state I check firstly that there is media available for the player and then that the button is in a state for me to start playing.

    Creating a Media instance for the MediaPlayer class
    The last thing really left to do is select some media for playback. Now the JavaFX SDK doesn't wrap all of the Swing API, only a select set of components which you can find in the javafx.ext.swing package. Most notably it's doesn't wrap any of the standard Swing dialogs including javax.swing.JFileChooser. The good news is that's it's easy to call JFileChooser from within JavaFX code. Once again I used a javafx.ext.swing.Button to call my code to select media and set it in my media player instance:

    var fileBtn: Button
    component:
    fileBtn = Button {
    text: "File"
    action: function() {
    var fc = new JFileChooser();
    var mp3Filter = new ExtensionFileFilter();
    mp3Filter.addExtension("mp3", "MP3");
    fc.addChoosableFileFilter(mp3Filter);
    var result = fc.showOpenDialog(fileBtn.getJButton());
    if (result == JFileChooser.APPROVE_OPTION) {
    var fFile = fc.getSelectedFile();
    display = fFile.getName();
    var file = fFile.toURL().toExternalForm();
    file = file.replaceAll(" ","%20");
    if (file != player.media.source) {
    player.pause();
    player.media = Media {source:file};
    text = "Play";
    enabled = true;
    }
    }
    }

    }



    This code basically calls a JFileChooser which selects .mp3 files from the file system using a simple javax.swing.filechooser.FileFilter instance FileExtensionFilter - which I wrote for my purposes - to get all the .mp3 files in the file system.

    Note that when you call showOpenDialog() on the FileChooser you have to pass in a java.awt.Component instance. The Button class does not implement this even though it's wraps a Swing JButton component. However Button does give you a method getJButton() which returns the underlying JButton instance, which you can use to pass to the FileChooser.

    Finally once you have the select .mp3 file, the last thing you need to do is create Media object and pass it to the MediaPlayer instance. The Media class has an attribute: source which is a string URL pointing to the location of the media. the Media object will also only accept escaped URLs, which java.io.File.toURL() does not do. This means you have manually escape the URL string before you pass it to the Media object.

    And that's it really, the full source code for my player is available here.


    Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks