Tuesday, March 13, 2007

Sun Tech Days (London): Day 1, Report 1 - First Impressions ++

It's a beautiful day outside. I've taken the tube to Green Park and walked past Buckingham Palace to Westminster Central Hall, venue for the Sun Tech Days 2007. I'm here for the Netbeans day....

...It's now 9:07 and we're waiting for the first session of the first day to start. First impressions? Good so far:
  • Wireless internet available across the board? - Check
  • Good range of geeks? - (Worryingly) yes
  • Free pens and t-shirts lobbed at us? - check. Also the old pre dot-bomb stress balls are back. I get one by answering a question. That's 3 I have now...
  • Wishing I had a Mac laptop with a fluorescent keyboard? - Yes
The only downside is the turn out. The room is not packed. There must be ~200 folks here. (I take it back. The place is busy now (10:00). Hot too) (Disclosure: I used to work for Sun. I don't now. I still have a die hard attachment to them however. Kind of sad really...)

The first session has kicked off... Octavian [Somebody] - The Director of Netbeans Engineering welcomes us and runs down some basics:
  1. It's looking good. Roman Strobl is to do the first session. That was not on the agenda sent out.
  2. First off is the Netbeans strategy. (also JRuby gets its first mention on a slide)
Apparently Netbeans is an:
  1. IDE
  2. Platrofm
  3. Community
Then we get some history and a sales pitch - NB works "out of the box" and we have our first dig (and only it turns out) at Eclipse ;-)

..."It's also fully supported - Sun are also selling piece of mind"

Now we have a Roadmap:
  • Netbeans 6 goes beta in May 2007. FCS mid Nov. Preview for JavaONE
  • NB 6.1 start mid October, release may 2008
  • NB 6 to support scripting and dynamic language support. AJAX and more heterogeneous language dev.
  • And exitingly at milestone 7 we got Ruby support.
What will we hear next? What's New and cool: Matisse. JRuby and BlueJ

Roman Strobl Demo 1 - Swing Application Framework and Swing Data Binding
To kick off he gets the crowd onside with a joke about the pain of GridBagLayout. He then does his first demo - Matisse and NB6's support for 2 JSR's: 295 (Swing data binding) - which allows you to bind a data source to a component and the Swing applcation framework (I don't know the JSR)

He then does a demo of both (note that this an the other demos are freely available at the Netbeans World Tour Wiki):
  1. New project type - Java Desktop application
  2. Choose application template - two are available now
  3. Select the db connection and table and columns
  4. Choose data view layout
  5. The NB IDE will then generate a simple application for you (entity class, and swing frame menu with icons, "about" box, actions and menus)
  6. Roman then shows the app running. If you resize columns and window. close and reopen and it remembers it. Cool
  7. We then see data binding: examing field properties and dialog pops with binding. Roman adds new component (slider) and resizes it. He then selects "bind", selects the binding in drop down in dialog and runs the app again.
  8. Roman says it has full CRUD support. Double cool.
  9. He then Creates a new record. (New car; a Skoda) and persists it.
  10. To examine the car he then drags a new bean (car pic) and bind to db again (colour, moderness).
  11. He runs the app again, moves the new "moderness" slider and the car shape changes. Getting even cooler.
  12. Roman points out that property change listeners are created automatically. If you change something and it just happens.
  13. Finally he adds a check box. (Roof window) , binds it to the picture and runs again.
Conclusion: "Swing data binding you can bind data very easily"

Now we look at the source:

Car.java has been created. Its a Java EE 5 entity class (POJO with annotations used to specify mappings.) Encapsulation and change listeners are automatically generated in code.

Roman also points out that the Swing Application Framework supports actions. If you add a button and link it to an existing action (or create a new one) it lets you set button, label, method name etc. in a single dialogue. - Impressive

All in all this is massively exiting. The only problem is that you can't try this functionality yet. It will be in the next NB milestone (8). There was a visible sense

Roman Demo 2 - JRuby
Roman asks who in the room uses Ruby? I'm the only developer in the room who admits to using it. (I get a free stress ball). That's interesting. I wonder what the response will be in a year's time?

He then asks who should care? - He brings up a table showing data from Tiobe. Java is #1. But it is not growing. Ruby is only language growing rapidly.

He points out that Sun recently hired the JRuby developers. He says the aim is to create a bridge between the Ruby and Java worlds. Time for another demo...

How do we get it? From the NB update centre. This demo will focus on the editing. He trails the fact that there will be more demos tomorrow in the Netbeans Extreme session.

We see:
  • Code completion (with RDoc) V hard to do. Can see docs inline
  • End block completion
  • CTRL-Shift-F reformatting (and to use 2 space indents - Ruby standard)
  • Regex has code completion too - Sweet!
  • If you add a string reference and if you have not declared it, the editor adds it for you.
  • Roman then adds a unit test . Unused variables are shown greyed.
  • Marking appearances also works.
  • In place renaming - Super cool. That produced a general sharp intake of breath...
  • Code completion on imports
  • Right click- run file.
Roman's done. He went down very well.

BlueJ (guys from Kent University) - Mike Kolling, Ian Utting
These guys work in the University of Kent Computing Lab. They have been working for a few years on BlueJ

They point out that BlueJ is a development environment. NB is another. They point out that how do you go about learning OO? It is a paradigm shift even if you can already code procedurally.

They introduce the debate around whether you should you use an IDE at all? Yes they say - just use an IDE which does what you want it to.

BlueJ was specifically designed to teach OO concepts. They estimate that it takes 18 months to make the mental model switch. Traditional IDEs do not support this. The size of things such as NB itself can be intimidating - the number of options etc.

But even if you have something like BlueJ how do you then move across to Netbeans at a later stage? With the help of Netbeans BlueJ edition. (There is also something for schools teching called Greenfoot - out of scope of this presentation)

Then they start the demo. BlueJ has a very simple UI. You start by opening a project and it's UML classes are shown on a central canvas. The IDE has four main buttons - New class, Extends, Uses, Compile

If you right click on a class you can create an object from the class and it appears in a new canvas below the main one. We can now see all the methods by right clicking on the object. There are some on our demo object (a shape) like "make visible", "move right" etc. If you click a method it runs. If you click one with a parameter then you must enter this via a dialogue. There are also packages

So you can use and inspect methods. You can also see all the values of fields an objects. You can move an object on the run canvas by changing its state (e.g. v. position) You then see the object move on the run canvas and its atttributes change in the object inspector in real time.

They point out that we have so far totally avoided the semi colons and "public static void main". Before the Java syntax we learn classes, objects and encapsulation. This is how to learn OO.

Then we finally drop down to code. All code is based around allocating behaviour to an object.

They then make the point that one of the hardest things to explain to their students is the difference between a class and an object. Looking at the code they frequently think it is both. But what you show on screen is what they will think about. If you want to show interacting objects, show them interacting objects.

They say that you should start with this to teach object orientation. But there is more. There is a debugger. You can still write and execute code. They use this at University level for 1 year. It runs on the standard SDK. There is no point which can be reached when you need to move up to a next IDE. It is a matter of choice.

They make a few more points. You can automatically invoke any public method stand alone. You need not hava a main method again. You can also round trip between code and diagram. If you create a class then the template code is automatiically generated. They also use it to teach concepts of unit testing. You simply create a test class which automatically creates a JUnit test for you. You then use BlueJ to record a series of UI interactions to use for the Junit test. E.g. yuo call a setter to set a value, and then a corresponding getter to see it was set and there is an assert box to check that this is correct. You then stop recording and then run the tests. You can see the green bar. Its just like a fully blown IDE. They note that you can also run just tests for a single class or even just a single method.

So that was BlueJ. What about Netbeans BlueJ Edition?

Picasso (paraphrased) - "Its not finished when you can't add anything else. Its finished when you can't take anything else out."

So where do you go from here? NB BlueJ is based on 5.0. Its like straight NB but with a lot fewer menu items, and panes. At this phase the confusion is still a problem they note. J2EE is cut out completely. Other stuff is present but switched off using the module system.

They also point out that this version understands BlueJ projects directly. They open a BlueJ project view (next to projects view) to demo this.

When first transitioning a student may want to move back and forward between Netbeans BJ and BlueJ for Java they say. It can do this. They can still go back to BlueJ at any time (e.g. to use the test recording)

Now we want to start to add some IDE features. This uses NB module management. They enable something using the standard Tools ... Module Management dialog. Initially they show that there is no refactoring enabled in BlueJ NB Edition. The refactoring menu appears straight away without NB stop/start.

They point out that this avoids the cognitive overload of not having menu items which you don't yet use. Again it avoids the "what the hell does public static void main mean?" question. If you don't want to introduce it yet, don't show it. But then you also want to add it easily when you do want to cover it.

They then add a "player" to their Zuul Game demo. There is now a BlueJ set of file types in the "New File" dialogue. We need to give our students the the boiler plate for free - don't give your students a blank page. In Java there is a lot of boiler plate they point out. A beginning student is not equipped to differentiate this from the important stuff. BlueJ templates are simply added to NB. They are sucked out of the BlueJ instllation so again synch is maintained with the other tool.

They conclude - "Allow your students to transition to their eventual IDE step by step."

Session 3 - Subversion and the Netbeans IDE
To be honest this session was pretty dull. It didn't help that the delegate came along in a suit and tie. How to lose a developer audience in one easy step... The interesting points are as follows:
  • SVN was developed for the web. Designed for distributed dev. SVN always sends only the deltas across the wire providing better performance than CVS which may send the whole thing.
Key Features:
  • Versioned directories which support versioned renames
  • Versioned metadata
  • Atomic commits (change set) - good for when your network fails
  • Global revisions
  • Support for both models (concurrent and block based) for parallel development
  • Support for WebDAV - the whole team can use it
  • Choice of network layers, back-ends and client applications
  • All files treated as a string of bytes - equally efficient with word doc or ascii file (over wire and back end)
  • Branching and tagging are not seperate concepts. SVN has more of a file-system-like paradigm. There are files which are on or off. You the developer decide to mark something as having a tag or being a branch. It is therefore far quicker than CVS to tag or branch a large project
  • You can easily diff two branches - Do a recursive diff between two version trees. Netbeans supports this in the UI, as does Tortoise
Netbeans plugin support
  • Merging branches support - there is a wizard dialogue
  • Searching history and diffing - again visually supported
Podcasts and webcasts:
  • http://submerged.open.collab.net
  • support in NB - http://www.collab.net/webinar14
Questions
Q: How easy to migrate to SVN?
A: Collabnet does a lot of work in this area. Problem is knee-jerk response is to want full version hostory migration. This is impossible. Also it takes a lot of effort. The question then is how far back in history do you go? Go to a stated point and then leave the rest in e.g. CVS. It is harder to do with Clearcase. The design is far more divergent (i.e. branches at the element level). How do I map it to SVN?

Java EE 5 - Did you get your tools with that? (Brian Leonard)
This session was an introduction to EE 5 but using NB as the demo IDE.
  • WS 2.0
  • JPA
  • JSF - now part of the spec.
Brian points out that the spec sprung from Hibernate, Spring and XDoclet. As specs evolve, they tend to get more complex. This took stuff out.

It leverages annotations, uses POJOs and dependency injection and relies on more and better defaults (effectively the Ruby "principle of least surprise" thing)

He notes that
  • Java EE5 is backwards compatible with J2EE 1.4
  • Deployment desciptors are still there if you need them. Gets over the "annotations are in code" problem. External edits to these files override annotations.
Brian asks "who here doesn't use Netbeans, and are just here to see what's going on?" (10-15% raise their hands gingerly). This is also interesting to see. The crowd is both a lot less a) synchophantic or b) hectoring than the crowds I'm used to when NB is mentioned. This is a good thing. Netbeans seems to be moving towards a mainstream acceptance.

The demos were very simple (thought they did go wrong because Brian had to borrow Roman's Czech laptop) and I won't go into detail here other than to make the following points which I found interesting:
  • If you just mark a POJO with @WebService then it will be a Servlet Web Service. It only becomes a Session Bean backed Service if you also add @Stateless or @Stateful
  • JPA 1.0 is not a persistence provider. It is just an abstraction layer. You are not tied to your persistence provider. I mention this as there is a common misconception that JPA is basically Hibernate / Toplink / etc. etc. depending on your heritage.
  • We see auto generating a basic JSF CRUD app with only an pre existing set of database tables. First we auto gen the Entity beans from the DB tables. Then we generate the JSF web app using the Visual Web Pack. Again this is a few simple steps in a wizard. All the code generated is standards based and ANT projects
[My laptop then runs out of battery...]

There were two more sessions after I ran out of battery. Roman went through a very swift overview of the extension packs available for NB. Profiler (interesting, load generation is coming in NB 6.0 with integration of JMeter), C/C++, Enterprise Pack. HE had to rush and little new was revealed.

Finally we had a talk and demo on the Mobile Pack. I don't know much about mobile development (though I have done some fiddling) but this was very impressive. We saw support for SVG, on device debugging, connecting mobile apps to Web Services, and how to develop your application for more than mobile platform at any one time (you can swap the platform you are coding from a simple drop down. The pieces of your code which will no longer work on the chiose platform are shown. You can add special comments to either remove this problem codewhich was demoed or provide alternative code blocks to do something different for your platform. Netbeans manages the complexities of all this from this point onwards.) It was very impressive.

Conclusion
Although we ran out of time I was very impressed in what I saw this morning. No demos were canned. Contrary to expectations they had flown in some of the real "rockstars" of Netbeans (Roman and Brian) and they delivered the goods. It is only a shame that they could not have used this in the marketing for the event. These guys might have managed to draw an even bigger crowd.

It's also good to see the UK getting a bit of Java love. Does this mean that Sun sees bespoke development becoming more of a big thing over here, closer to how it is perceived in the US? Possibly. They're certainly bullish about their offerings and competition (within the standards) is always good. More tomorrow. Including James Gosling.

Friday, March 09, 2007

Running JRuby built from the trunk with Netbeans 6.0

It's nice to use software in development. It's also nice to use it with an excellent IDE. What fun then that you can use easily use Netbeans 6.0 to both build and develop with the absolutely latest version of JRuby. Here's how.
  1. First you need to get Netbeans 6.0. You can download the dev build from Netbeans.org. NOTE: you currently need to get Milestone 6 or above so choose Netbeans Version "6.0" and Build Type "Daily". Get the latest "IDE" product.
  2. When it's downloaded, double click and install...
  3. You're not ready to go yet. You need to connect to the update centre in order to get the Ruby support. Click on Tools -> Update Center to start the process.
  4. From the available list of options select all the Ruby elements and install them.
  5. Now you need to get the lastest JRuby source. To do this you need to set up Subversion to point to the project's repository. Click on Versioning - Subversion - Checkout...
  6. Enter the JRuby trunk repository URL: svn://svn.codehaus.org/jruby/trunk/jruby and click "Next", and wait...
  7. When the code is checked out and Netbeans has scanned the classpaths it will ask you if you want to open the project. Answer in the affirmative.
  8. We're almost there. Now we need to build JRuby. To do this right click on the Ant icon in the "Projects" pane and select "build". Ant will build everything for you.
  9. Now set two environment variables. The first, a new one called JRUBY_HOME which should point to your base JRuby directory. Then add $JRUBY_HOME/bin to your path (%JRUBY_HOME%\bin on Windows)
  10. Time to get Rails. Open a command prompt and type: gem install rails -y --no-ri --no-rdoc
  11. Finally you need to point Netbeans at your JRuby binaries. Select Tools - Options. Select the "Miscellaneous" tab and expand the "Ruby Installation" node. Point each of the items at the binaries in your JRUBY_HOME\bin directory
That's it. Try creating a new Ruby project and then running it. You're off!

Placing your config.properties outside your application JAR

If you want to deploy your application as a JAR, and DO want it to be configurable via a config.properties file, but DON'T want folks to have to crack open your JAR to update it you'll need to do the following.

In the META-INF/manifest.mf file add the directory location (relative to the jar itself) of your config.properties file to the "class-path" attribute. E.g. if your file is going to be in the same directory as the jar, then add "." to the end. If it's going to sit in ./config, then put this in the path.

NOTE: Remember, manifest.mf files have a maximum line length. Go over it and things get confusing. For more information on JARs and manifests see the Sun guide.

Thanks to Rob Newsome for his help in figuring this out.

Wednesday, March 07, 2007

Friday, March 02, 2007

Ruby with Foxes...

I've been learning (J)Ruby with foxes... Now all I need is Rails with whales and I'm all set.

Thursday, March 01, 2007

Truncating tables in DB2

If you have a table full of data and want to just drop the lot you can truncate it, just as you can in Oracle. The command is:
db2= alter table [tablename] activate not logged initially with empty table

DB2: Finding the maximum / minimum / average value in a given column

db2= SELECT MAX ([your column to query]) FROM [your table to query]

Showing a Table's Foreign Keys with DB2 Control Centre

Might be obvious to some. Not to me...

  1. Start Control Centre and connect to your database
  2. Select "Tables" for your database from the tree in the left hand panel
  3. Right click on the table you are interested in in the tables panel on the right hand side and select the "Alter Table" option
  4. Select the "Keys" tab in the new window and voila.

Tuesday, February 27, 2007

DB2 Import Commands Failing With "transaction log for db is full" Errors

Trying to upload test data with the DB2 Import Utility. I have a .CSV file with 100,000 records in it. It used to work; then I added another column and now it fails with "transaction log for database is full" errors.

:-(

It turns out that it wasn't committing enough. In fact I didn;t know when I was committing at all. I discovered that the "sensible" defaults can sometimes not be so sensible. In order to explicitly set a commit count you need to add the following to your import command (highlighted in red):
db2 "import from [your_csv_file_name] of del commitcount 1000 insert into [table_name]([column A], [column B], [column C], ...)"

Wednesday, February 14, 2007

Using DB2 Load to Batch Upload Data (DRAFT)

UPDATE 1: I've since found out that although DB2 LOAD is quick, it's more complicated than the documentation implies. It also gets you into an inconsistent state nightmare really easily. I'm investigating DB2 IMPORT as an (slower but more reliable) alternative.

UPDATE 2: A DBA friend has just given me a command to use to list all the tables in DB2 which are in an inconsistent state. It is as follows:

select substr(tabname,1,30),status from syscat.tables where tabschema='[your schema owner]' and status='C'

On our current project we have the need to load large volumes of data into DB2. We also dont want to sit around for years while we do it with SQL files. We used DB2 Loader to speed things up.

Firstly we needed to create a csv file for each table where we were to load our data. Luckily we had a set of java classes which we'd used to generate our SQL files so we simply added some additional code to write the same information comma seperated. I'll not provide any more detail. It's kind of obvious what this means.

Next, we scripted our calls to the "db2 load" command so that all our table data could be loaded with a single command. An example script follows:

echo "Connecting to the database..."
db2 "connect to [your_database] user [db_user] using [db_password]
LOG="load.log"

echo "Loading data into mytable..."
db2 "load from [your_data.csv] of del replace into [mytable] (c1, c2, c3)" > $LOG
db2 "set integrity for mytable immediate checked" > $LOG

NOTE: It assumes that we are loading into a table called mytable as follows:
CREATE TABLE mytable (c1 VARCHAR(30), c2 INT, c3 CHAR(1))
and that the csv file looks like this:
Hello world, 1, Y
Hi again, 2, N

DB2 the Hard Way...

I'm having to get to grips with DB2. Here is a list of things I've learned the hard way so far...
  1. You don't put semicolons at the end of DB2 statements
  2. When doing lots of INSERTs put a COMMIT every 1000 or so. (As pointed out here)
  3. If you're uploading a lot of data consider using the DB2 LOAD utility. [More info on how to use it when I get it working]
  4. To get a nice graphical view of your data use something like SQuirreL or DBVisualizer (Update: don't try and use IBM's DB2 Connect, it leaves locks all over the place and locks in DB2 are pretty pervasive...)
  5. Don't try and do bulk uploads with triggers switched on
  6. Remember to create the statistics for your database tables (RUNSTATS SQL command)
  7. Find out what an error code means with db2= ? SQL-[xxx] NOTE: The angle brackets are part of the command
  8. Don't delete a load of rows all at once using "DELETE FROM..." - it'll go very slowly. Instead do in bunches of 10,000 rows. E.g. db2= DELETE FROM things WHERE things_id 900000; DELETE FROM things WHERE things_id 890000; etc; etc
  9. Or, if you can bear it, drop everything and start again from scratch...

Blog Entries I Would Write, Had I the Time...

I keep thinking of blogs entries I would like to write. Get things out of my brain and down on a page (of sorts). If I ever get round to it, my current output would include:

  • What I'd do with an Open Source Second Life Universe - There are a million uses I can think of for a virtual Second Life. None of which I'd ever get the chance to try out myself. Maybe I could write about them instead...
  • Tips for a First-Time-Java-Project - If I knew then what I do now, I wouldn't have made a bunch of mistakes.

  • Building JRuby with Netbeans and Testing it against Oracle - I have barely fiddled with it, let along built and ran test suites against it but then this is a wish list...
  • A Java Mobile version of my Expenses Tracker app (and get a decent phone to run it on)

Problem is, I never seem to have the time... Perhaps I should cut out all the dodgy Italian gore films I keep getting sent from LoveFilm?...





powered by performancing firefox

Saturday, February 03, 2007

My First Maven Plugin: A Unit Test Packager

I've just written my first Maven 1.0.x plugin. It's a monumentally simple affair but does what it needs to do quite elegantly; that is to take the Unit tests for your project and zip them up (along with your project's dependencies, the required Junit jars and some auto generated shell scripts) so you can run them anywhere. I don't have any personal hosted space to provide the actual plugin jar but here's the jelly code as a starter:


There's only one configurable (and that's because I ran out of time). You need to set the following property: suite.class.name= [the name of your test suite class]

[BTW, If anyone out there wants to offer me some place to host this I'd be dead greatful. Its a tiny litte jar. Tiny.]

EJB 3.0 Outside the Container, Inside the JVM - Part 3: Wrapping the Model

Welcome to part three of my blog on using EJB3.0 / JPA and Derby inside the JVM. The previous parts can be found here and here.

We're almost ready to go. However, we still need to wrap our domain model with a facade in order to manage interactions with it and prevent any JPA specific code creeping outside the model boundaries. We can do this by placing a session bean in front of our Claim POJO. (Why a session bean when we're not really going to use this within a Java EE container? Aha! Maybe something will come along in a later posting...)

We'll start by creating a new POJO class called ExpensesTrackerService. To make it a Stateless Session bean we simply the @Stateless annotation. We also need to add the following dependency to the project so that we can get the imports needed:

Now we need to provide a means to address and manage the Claim entity. In JPA this is via the EntityManager which we obtain via an EntityManagerFactory


Now that we have an EntityManager we can use it within our CRUD methods. Here:

Here:

And here:

Now all we have to do is build our maven project (run the jar:install maven goal) which will also copy the resulting jar containing our wrapped model to the repository. In the next entry we'll use it from within our Swing client

EJB 3.0 Outside the Container, Inside the JVM - Part 2: Configuring JPA Declaratively

Welcome to part two of this blog entry introducing using EJB3.0 inside the JVM. Click here to view the first part.

As we've seen, JPA can use our annotated POJO model to create a database for us, but first we need to give it some information on how to do it. We provide this information in a file called persistence.xml. Let's create a blank file with this name in {PROJECT_HOME_DIR}/expenses-tracker-model/
resources/META-INF/.
We also need to let maven know where this is so we add the following to our project.xml file:


This entry ensures that this file will be included on the build classpath.

Now lets add the content to persistence.xml. We'll start at the top:


The persistence-unit tag tells JPA about our (future) database. A single persistence.xml file can have mulitple persistence units but we will keep things simple and just stick to one. Attributes to this tag provide the persistence unit name (which we'll use to refer to it later in code) and the transaction-type. (We have the default). We'll only need the former as we'll see later on.

Enclosed within this top level is the tag which tells JPA which implementation will provide the actual persistence functionality - the "provider" tag. Our example uses the Toplink ORM tool but we could swap this to something like Hibernate simply by changing the contents of this tag.

Finally there is the tag where we declare our new entity class - "class". This tells JPA that we want it to be considered as part of this persistence unit. (Note: if you find JPA doing things you don't expect, check that you have listed all the classes you wish it to be aware of here. It can't work with what it has no idea about!)

Ignore the commented out tags. If you really want to know what they do then just google or yahoo! them.

This is all well and good but clearly my file is a little more complicated. Toplink will need some additional information in order to do its job and we can put this in this file as well. These go within the "properties" tags. You can see below that we use these to tell Toplink the driver class to use, the url for the database connection and well get to the third piece of magic later.

Monday, January 29, 2007

EJB 3.0 Outside the Container and Inside the JVM - Part 1: The POJO Model

NOTE: This is a more truncated version of an entry I started previously. The aim is to keep it simpler and to actually finish this it...

ANOTHER NOTE: I use Netbeans. It's not popular but I like it. If you don't have Netbeans you'll still be able to follow this series but won't be able to drag and drop a Swing UI in part 4 using Matisse. My heart bleeds...

EJB 3.0 and JPA 1.0 have made it easy for people like me (RDBMS-phobics) to persist our O-O domain models. What's more, Derby (aka JavaDB) has made it easy to have within-JVM RDBMS persistence that is transparent to the user of your thick client application. What follows is a simple example application I wrote to learn some of the basic concepts (and also track my expenses claims)

Step 0: Setting up my project.

I like Maven; Maven 1.0.x to be precise. Before anything else I set up a basic maven project called "expenses-tracker-model" in the standard fashion:


You'll also need to manually get hold of the JPA and Derby Jars (toplink-essentials.jar, derby-10.1.jar and javaee-9.jar) and place them in your repository wherever you see fit.

Step 1: Coding the Domain Model

I like to model in OO land. My model is very simple - a single, serializable POJO class called "Claim" - which will eventually map to a single Derby table called "CLAIM". I create my java class and add attributes as follows:
private Long id;
private String refNumber;
private String projectCode;
private String description;
private Date dateFrom;
private Date dateTo;
private String status;
private Date submitDate;
private Date paidDate;
private Long totalClaimed;
private Long totalFromCurrentAccount;
I now need to add the annotations which will allow JPA to work its magic. First I tell the class that it is an entity (i.e. will be represented in the RDBMS) with the following annotation:
import javax.persistence.Entity;
...
@Entity
public class Claim implements Serializable {
...
The compiler is now clever enough to know that, unless told otherwise, the attributes on this class will be represented as columns in our table. That's how EJB 3.0 works. It assumes the default unless you tell it different. Very handy.

The observant amongst you will realise that we most likely need a primary key. You're right. We need to declare which will be our primary key field and how we will work with it. This is done with the @Id annotation. The @GeneratedValue annotation tells JPA that we'dlike the RDBMS to auto generate our PKs for us (which makes things even easier at our O-O end):
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
...
/** Unique, datastore generated id */
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
...
Finally, because we have java.util.Date fields, we need to provide some extra information about these for JPA also:
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
...
@Temporal(TemporalType.TIMESTAMP)
private Date dateFrom;
We're nearly there. Another quick IDE aided step to encapsulate our attributes with some getters and setters and we're ready to go. You should now have something like this:
package com.andrewharmellaw.exptracker.model;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Claim implements Serializable {

/** Unique, datastore generated id */
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String refNumber;

private String projectCode;

private String description;

@Temporal(TemporalType.TIMESTAMP)
private Date dateFrom;

@Temporal(TemporalType.TIMESTAMP)
private Date dateTo;

private String status;

@Temporal(TemporalType.TIMESTAMP)
private Date submitDate;

@Temporal(TemporalType.TIMESTAMP)
private Date paidDate;

private Long totalClaimed;

private Long totalFromCurrentAccount;

/** Creates a new instance of Claim */
public Claim() {

}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getRefNumber() {
return refNumber;
}

public void setRefNumber(String refNumber) {
this.refNumber = refNumber;
}

public String getProjectCode() {
return projectCode;
}

public void setProjectCode(String projectCode) {
this.projectCode = projectCode;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public Date getDateFrom() {
return dateFrom;
}

public void setDateFrom(Date dateFrom) {
this.dateFrom = dateFrom;
}

public Date getDateTo() {
return dateTo;
}

public void setDateTo(Date dateTo) {
this.dateTo = dateTo;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public Date getSubmitDate() {
return submitDate;
}

public void setSubmitDate(Date submitDate) {
this.submitDate = submitDate;
}

public Date getPaidDate() {
return paidDate;
}

public void setPaidDate(Date paidDate) {
this.paidDate = paidDate;
}

public Long getTotalClaimed() {
return totalClaimed;
}

public void setTotalClaimed(Long totalClaimed) {
this.totalClaimed = totalClaimed;
}

public Long getTotalFromCurrentAccount() {
return totalFromCurrentAccount;
}

public void setTotalFromCurrentAccount(Long totalFromCurrentAccount) {
this.totalFromCurrentAccount = totalFromCurrentAccount;
}
}

Right, that's the dull part done. Now we can get to the fun part - using this POJO to auto-create our database. That's in the next post in this series...

Saturday, January 20, 2007

Kill Your Computer

I mean it. Kill it. It's probably on its last legs anyway. Then get a new one and see how much you've lost. Didn't I tell you to backup before you wielded the sledgehammer? Sorry.

My laptop died yesterday. What with a previous entry about how great life was with all your stuff online now was the time to test it out. Job 1: Dowload Firefox. Job 2: Get Google Browser Synch up and running. Job 3: Get my favourite extensions and I'm up and running.

Its interesting to me to see what else I felt I had to install to be productive. For me this was the following:
I was up and going in 2 hours (Slight aside: If I had Eclipse rather than Netbeans how long would this have taken? A lot longer). Now at th emoment I think that's pretty cool. What would really make my day would be if Google Browser Synch remembered which of my bookmarks were on my toolbar and what firefox extensions I used. Oh, and a web based version of Thinking Rock would be great too. I can but hope...

NOTE: If you want to kind of feel like what its like to lose everything just run Windows Cleanup - I lost loads of old files which MSFT deemed no longer important. :-( That'll teach me.

Tuesday, January 02, 2007

Running my Java 5 App on MacOS X

I've written a simple app for my wife in Java (using Netbeans Matisse). I've got an XP laptop which I use to develop on. Running it was simple within the IDE and I created a simple zip file containing my jar, the required libraries and the derby database files and a .bat file to make running it a double click affair. How hard could it be to move it to her Mac?

Being quite simplistic about it and having worked at Sun in the past (Unix is Unix right?) I thought I could create a simple .sh equivalent of the .bat file to protect my beloved from the intricacies of the "java" command. Before this I thought I'd just try out the command at the terminal to check it worked. Best practice you see...

Wrong. I kept getting errors about my jar files (all of them) not being excutable ("cannot execute binary file"). My first thought was that it was a Windows / Mac newline thing... nope. Corrupted JAR files?.. Nope. Then I found a blog entry about how my problem was common and you needed to wrap things in a shell script. I did, and then started getting all manner of even wierder errors (most likely due to my terrible korn shell skills rather than anything else). I was stuck but had the distinct feeling that there was a very simple solution.

There was. I had my classpath seperated with ";"'s. Macs don't like that (I'd forgetten that other unixes don't either - so much for my Solaris skills) and need ":"'s instead. Dammit. Now she runs like a dream (and looks sweet too with the default MacOS X liquid look and feel...

Sunday, December 24, 2006

MI6 Mashup

I saw Casino Royale last night and was very impressed; impressed in many ways (especially the Treasury Rep. - anyone who has worked (with)in the British Civil Service knows how close to reality this sometimes seems). But that's not what stuck me.

I was amazed at my reaction to the sequence when Bond has broken into M's apartment to salvage some information from a SIM card he has salvaged. When he plugs it in and some technical wizardry provides him with the location of the last SMS message sent (a suitably exotic Bahamas), the app providing the information had to me the feel of a nice looking mashup combining yahoo maps and some backdoor-access telco data. I even wondered if I could go home and do the same for myself. It reminded me of the (again just ahead of reality) "I know this it's UNIX" bit in Jurassic Park.

The future (as they say) is now. Or maybe a few months away. I wonder if they're really mashing things up down there next to the Thames...

Dim-neb-leh Annoying...

I did a windows cleanup last night in an effort to nudge my XP laptop into regaining some of the zip it has, of late, been lacking. When I then came to do a checkin to Subversion of some minor code changes I was confronted my error messages about missing .svn/tmp directories. Windows had helpfully removed evey one! I just had to go back through every directory, manually replacing them and then running svn cleanup. Dim-neb-leh annoying...

Friday, December 22, 2006

Netbeans VWP and My JPA1.0 Domain Model in Tomcat 5.5.17

I've been meaning to get this going for a while now and finally got round to it tonight. I have a domain model written using JPA1.0 annotations, Toplink for the implementation and MySQL for the RDBMS. I have it all masked off nicely behind a Session Facade and packaged into a simple jar. i want to call this from my Netbeans Visual Web Pack apps. Here's how I did it:
  1. Create the project making sure that the deployment target is the bundled Tomcat and not AppServer 9 (if you don't then you'll have to set up connection pools etc.)
  2. Add the domain model jar (which includes the persistence.xml file in the META-INF directory) to the new VWP project's libraries
  3. Also add the MySQL JDBC Driver and Toplink Essentials jars to the libraries
  4. Right click on the Application Bean in the Outline View and Add > Property and enter a name for your Session Facade variable and the name of the class
  5. Do this again for the field which you want to store your retreived info from the database (i.e. "username / String")
  6. In the constructor for the Application Bean initialise the Session Facade and then the storage field by calling the newly created facade to get the info you require from the database
  7. On Page1 Design View, drag a Static Text component onto the designer
  8. Switch to the Java view and in the prerender method set the text for the new component to be that which you just looked up and stored
  9. Hit deploy
  10. Et voila!

Thursday, December 21, 2006

Blog Tagged

[Think] I've been nominated![/Think]

[Do]Walk up to the stage. Time slows down. Sounds recede into the distance.[/Do]

[Think] I must be the exact opposite of the blogger type. Upon getting my first real link from a respectable source (Andy) via a game of blog tag and the click flow it may bring, I have no idea what to write (let alone who to tag). A voice is whipering "keep it simple. don't try to be clever. Definately don't get all puffed up about it". I'm not cut out for this kind of (web 2.0) world... Just read out the card...[/Think]

So the nominations for "Best Drunken Conversation Starter in a Starring Role (in my life) are...
  1. My personal myth states that I decided I didn't want to be a vet when no a hot day's work experience a sheeps cancerous testicle the size of a large mango was cut open in front of me and a pea green soup like substance cascaded out, followed closely by a barrelling smell of decay. But...
  2. I have no sense of smell (guess that puts number one into perspective). However, when something is really bad I can taste it (so yes, to answer the standard follow up question,I can taste)
  3. I love Italian Horror Movies from the 60s and 70s. Most of all I love the zombie pics (think zombie flesh eaters, virgin amongst the living dead, the beyond, the house by the cemetary, dawn of the dead etc.) and the stalk and slash grindhouse stuff (like profondo rosso, suspiria and five dolls for an august moon) but the greatest film ever made by the greatest director that ever lived is the birds.
[Think]That's all I can think of. All that are worth reading anyway. Now the hard bit, who to tag? Think of the blogs you read dammit!...[/Think]

And the winners are... [Do]Open envelope[/Do]
  • Stefanie Hollmichel at So Many Books
  • if:book (because it deserves traffic)
  • and finally David Cameron (more to see if he responds or not. [Think]I'll need to post a comment as I doubt he reads this avidly[/Think])

Friday, December 08, 2006

JavaUK Roadshow Linlithgow - Report

[I'd like to say I blogged this while I actually sat in the sessions; but that would be a lie. Good old pen and paper were the name of the day. I'd also like to point out that I used to work for Sun UK in the Java Software Team and as such am not the most impartial of witnesses]

Introduction
I attended the first (and hopefully not the last) JavaUK Road Show in Sun's Facility at Linlithgow, Scotland. The event was far better attended than I would have expected with nearly 40 delegates from both further education and industry. Spanning the whole day, the three major sessions covered "JavaCAPS, SOA and Web Services", "Moving Forward with Open Source" and "Free, Open and Innovative Tools for the Next Generation Web". Tying all these together was the concept of "the age of participation" - Sun's take on Web 2.0. I'll only cover the first session.

JavaCAPS, SOA and Web Services
This first session was tackled by Steve Elliot and provided an introduction to Sun's new Composite Application Platform Suite (aka CAPS) - in a nutshell their platform for SOA. While he (as will I) got onto product eventually it was very interesting to see how he framed Sun's take on the new flowering of internet technology buzzwords and concepts (generally lumped into "SOA" and "Web 2.0") in all their myriad forms and interpretations and used this to lead up to the pitch.

Just like in the dot.com boom of 6 years ago, it seems that Sun is again making a simple play to be the platform for this new web/network revolution. (Hands up who remembers "we're the dot in .com"? or the later "we make the net work"?) As a consequence, Steve started with an SOA "reality check" and explained what Jim Waldo (Sun employee and creator of Jini) has called the "Highlander Principle" - i.e. "there can be only one". A more apt title would be the "Highlander Fallacy" as his point is that this is a misconception. SOA, he explained, could be implemented using a variety of technologies, from Web Services (the current flavour of the month) to CORBA, RMI, Jini, DCOM, Raw Sockets etc. etc. The point being that there is a clear difference between architecture (the "A" in SOA) and implementation. He made it clear that Sun will continue to play in them all, and it is important not to get too pedantic about how it is done.

However, to narrow the field, he staked the Sun colours to the mast and said that their end was the enterprise end (where, for example, things like transactions are important). There was little attempt to define in detail or discuss the nature of the "S" - Service.

He then moved onto the alphabet soup that is "Web 2.0" and introduced a take which was all his own but very much in the Sun tradition of iconoclasm - "Dictionary Abuse" aka "All your words are belong to us". He went on to discuss the positioning of this on the Gartner Hype Curve before distilling it down to the concept of "The Age of Participation" summarised by a nice diagram of the world in "1.0" with a cloud with a large arrow coming down to the stick men (content access) below and a tiny one going back the way (content generation), complemented by the "2.0" could which has a even larger down arrow, but now also far larger up arrow.

Aside: Why the jump from SOA to Web 2.0? To be honest it made sense at the time but is a little stilted in the retelling. I think the best way to explain it is that Steve was trying to make things (and therefore by association Sun) cool and relate to the audience. Anyway, I digress...

The general 2.0 landscape laid out, Steve went on to link things up and discuss Sun's take on a (web) service, or more accurately how they can provide a platform for your service. The service was represented as a red blob (he stated he was keeping it simple). He introduced the analogy of the Victorians being the first real users of the SOA - they wanted tea, they wrang a bell and waited for the result. They didn't care how the tea got made orhow it got to them. It was all about the interface contract and end result. The same went for the blob. It's supposed to be opaque.

After this uncontroversial and functional depiction of a service, he then moved on to the meta or non functional features of the same. "How do I combine it with other services?" he asked. "What About Security and Identity?" and "What About QoS and SLAs?" he went on. He pointed out that not all services, or interactions with them will need to worry about these problems to the same extent, but did highlight that Governance (versioning) of services was key. He returned to this later.

He then listed the key principles which Sun feel an SOA should embody:
  • Secure
  • Policy Driven
  • Orchestrated
  • Registered and Discoverable
  • Standards Based and Driven
  • Coarse Grained (services)
  • Self Described
  • (Mostly) Asynchronous
  • Conversational
  • Document Centric (as opposed to the old conception of them as XML-RPC focussed)
  • Reliable
Nothing too controversial there either and a nice lead into a teaser for the product meat - the middleware - which Sun are providing to support these key SOA principles: JavaCAPS. However before going into it Steve had one more topic to cover off (and another Sun favourite) the standards and specifications which wrap all these when doing SOA as an XML Web Service.

While we all know the list which I could reproduce here it is interesting to note the ones which were majored on. Namely the Liberty Alliance frameworks of ID-FF and ID-WSF, and most importantly the outcome of the Sun / Microsoft 10 year joint venture to provide greater .NET and Java interoperabilty. While you can find out more on the official sites, Steve was keen to stress that this was an engineering to engineering match up and something I tend to believe. (He showed some pics of Sun kit in the Redwood data centre.) It also seems to have been a meeting of equals (and a million miles from the recent announcements of the Novell / Microsoft love-fest) and was deifnately customer driven (they share a few blue chip customers in common who basically told them both to grow up). He then provided a quick overview of the output so far: Project Tango. This is provides greated interoperation between the Microsoft Windows Communications Foundation (WCF) messaging layer and Java EE Web Services. It was announced and demoed by Microsoft at JavaONE 2006 as WSIT ("Web Services Interoperability Technology"). So what does it provide specifically and how does it do it? Well, it adds richer protocol support, a richer security model and QoS support among other things but all without changing the JAX-WS (the latest incarnation of JAX-RPC) APIs. As a consequence you will be able to take advantage of these developments in your web services without having to change a single thing; it's all just extra configuration, not coding. Release is scheduled for 2007 on JavaSE 6 and JavaEE 5 with the Glassfish app server as the deployment platform. I didn't get a chance to ask if this would work on any other platforms.

Finally we moved onto a section entitled "The need for Business Process." Again the opening gambit was a classic Sun approach - via the standards. He explained that these days, to develop and expose a service is not enough. There is the need to compose and orchestrate a collection of these into something meaningful and useful. He mentioned WS-BPEL as being the current de-facto standard for describing long running and stateful business transactions which was "generally accepted by both the Java world and Microsoft." However, hand cranking BPEL is hard to do he said. It is an execution language only and not a modelling notation (i.e. that is visual). For this he said we needed BPMN whch layers on BPEL and will reach v.1.0 in 2007.

At this conclusion, finally a product appeared - Java CAPS Enterprise Designer. Its based on the Netbeans Platform (I think part of it has got into the free Enterprise Pack) and originated from the SeeBeyond acquisition. Its aimed at business analysts - all very drag and drop. To be honest, what we saw looked very nice and usable.

To tie this back to the main thread we concluded with a lightning tour of JBI. (aka JSR 208). Steve framed this by saying this was trying to do to SOA what Java EE did to the application server. This seemed sensible enough - all about how you provide a pluggable, core intergation system with seperate rules engines. He said that the orchestration engine will be BPEL, XSLT for the transformation engine and it'll first off interoperate with Web Services, MQ and FTP drops.

And that was it. To be honest I was pretty impressed. It was reassuring to see my alma mater pulling back from being everything to everyone and going back to what it knows best. There also seems to be a move to be "cool" again which is no bad thing. What with this, the open sourcing and the currently on tour Tech Days it seems they might just pull it off...

It's a Patriarchal Web (2.0)

My wife and I have finally got round to double barreling our names (long story but hers goes away entirely if she drops it, and there is a precedent for this kind of thing in my ancestry). I thought I'd go the whole hog, do it properly and change my email and all the places I've used it to sign up for things (that's a lot of places)

So I went to Google where I "live" online. I'd never really thought about having to do this before - not a thing guys do in a patriarchal society (not to mention a little wierd). I knew there'd be little chance of just changing the address I had (why not?) so I thought I could create a new address and then simply set up an auto forward or something. But to create a new address I had to "invite someone". To do this I had to create a temporary email address (good time to stake a claim on my new name at yahoo I rationalised), send them an invite from my existing gmail, accept, and then create a new gmail (or googlemail as it seems to be these days) account with my new, double barrelled name. Done. Fine. Quite a hassle, but fine.

OK, so now I want to have things "just work". It's optimistic I know but I take a lot of services from google (docs, calendar, blog, desktop, notebook, ...) and I want to be able to continue using them, but with my new name (/ email). After all, I didn't change it just to make my life more complicated.

So how do I do that? The answer seems to be "you can't". Everything I do I now realise is tied up to that same great email address-in-the-sky. My original, old one. It's damned annoying and seriously making me consider migrating to something a damn sight less monolithic. (I've already moved googledesktop to netvibes and am very pleased with the result). I mean it's "2.0" for crying-out-frikkin'-loud. What do I have to do? Wait until 3.0? I'm betting that if the web was created and run by women things would be a lot simpler (and maybe a little cuter too).

{Addendum 28/12/2006}
I managed to get it all done. As far as I know, I have now changed (or frigged) my online identity where ever it may lie to reflect my new identity. The Gmail thing definately sits in the "frig" category. I had to invite myself to GMail again, create a new address, and then set this in my old account as the primary address while setting a global forward and archive on the new account. Now as far as the outside world is concerned I have a new email. When in reality I've just "skinned" the old one. Still get access to all the archived mail and contacts. Sweet.

Friday, December 01, 2006

Maven 1.x and Google Web Toolkit

I'm fiddling with Google's Web Toolkit with an eye to using it to produce a new front end to a web app I've written. I'm a big fan of Maven and wanted to get my head round setting up a GWT project which runs as a maven project (and thenceforth within my IDE of choice - Netbeans). There is a maven plugin (actually there is one for Maven 1 and another for Maven 2) for GWT but the docs are a little sparse. I had a fiddle and soon got things going but I had a few problems along the way. Here's what I had to do (assuming you already have Maven 1.0.x installed):
  1. Download and install the current version of GWT for your platform. Instructions and binaries are here. Put the install directory in your path.

  2. Obtain the GWT plugin. This example currently only works with the 1.0 version. You need to get it from here and then after unzipping it cd into the expanded folder and run the command: maven plugin:install-now

  3. Then you need to get the GWT jar files (and .dll's) into your Maven repository. You'll find them in your GWT install directory. I copied them to a new ./.maven/repository/com.google.gwt/jars/ folder. I had to place gwt-dev-windows.jar, gwt-servlet.jar, gwt-user.jar, swt-win32-3235.dll and gwt-ll.dll in there to get this all to work fine. NOTE: You could get the jars automatically too but I was behind a firewall and too lazy to set up Maven to get through it.

  4. Now you can create your new GWT project. Create a directory (e.g. "./sample/") to house your project somewhere sensible, change directory into it and run the following command:applicationCreator com.mydemo.gwt.client.SimpleDemo.This will create you a source code directory ("./src/") containing a hello world-style GWT application and two scripts for compiling and running your app.

  5. Now we need to mavenise the directory structure. To do this change directory into ./src/ and create three new directories called java, webapp and test. Then move the auto generated com directory and it's contents into the new ./java/ folder. NOTE: We won't use the webapp directory this time, but it's where we would put things like the web.xml file if we had servlets as part of this application.

  6. Finally we need to create the required maven config files as follows which all live in the project root directory ("./sample/" in our case). NOTE: You'll need to edit the bits in red to suit your app and workstation:

project.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project>
<pomVersion>3</pomVersion>
<artifactId>mydemo</artifactId>
<groupId>com.mydemo.gwt</groupId>
<currentVersion>0.1</currentVersion>
<dependencies>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>user</artifactId>
<version>1.0.20</version>
<jar>gwt-user.jar</jar>
<type>jar</type>
<properties>
<war.bundle>true</war.bundle>
</properties>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>windows</version>
<type>jar</type>
</dependency>
</dependencies>
<name>GoogleWebToolkit and Maven Demo</name>
<package>com.mydemo.gwt</package>
<logo>/images/logo.gif</logo>
<inceptionYear>2005</inceptionYear>
<build>
<sourceDirectory>src/java</sourceDirectory>
<unitTestSourceDirectory>src/test</unitTestSourceDirectory>
<!-- Unit test classes -->
<unitTest>
<includes>
<include>**/*Test.java</include>
</includes>
</unitTest>
<resources>
<resource>
<directory>src/java</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
</project>

maven.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:j="jelly:core">
<preGoal name="war:war">
<attainGoal name="gwt:compile"/>
</preGoal>
</project>

project.properties:

maven.war.src=src/webapp
google.webtoolkit.home=C:\Program Files\GoogleWebToolkit\gwt-windows-1.2.22
google.webtoolkit.runtarget=com.mydemo.gwt.SimpleDemo/SimpleDemo.html
google.webtoolkit.compiletarget=com.mydemo.gwt.SimpleDemo
google.webtoolkit.logLevel=SPAM

That's it, you're ready to go. Just run the maven target "gwt" and you'll see your app in the google debugger.

NOTE: This borrows heavily from an introduction to the maven GWT plugin created by Rober Cooper. His article on O'Reilly can be found here and the google code project for the plugin is here.

The Itinerant Techie's Kitbag

In my job I get sent to many different places to do many different things. However, wherever I go, there are some basic tools and resources that I need to have access to . Tools which, when I first started, were all located on my laptop, or even worse my home PC. Over the last year, and mainly by stealing things I see other people using, I've built up a browser based kit bag which allows me to free myself from my thick client and become as flexible as possible. The goodies are:
  • Email - Simple really, but I used to use a thick (Thunderbird) client to my web mail. Recently web UI's (with the dawn of ubiquitous AJAX) have become very rich. Sign up for something like google mail or yahoo mail and learn the keyboard shortcuts. Oh, and keep your personal emails out of your work mailbox. Makes separation easier when you leave! If possible, add a widget to your shiny new web desktop (see below) so you can see what's in your inbox without having to have the page open. Oh and learn to use labels.
  • Calendar - Have one, and one only. Again, I used to use my Outlook calendar. Then Google came along with one which integrated perfectly with my GMail. Get it to send you reminders. Same as the webmail, if possible add the widget to your new web desktop (see below) to see your calendar in miniature.
  • Contacts - Again, put them in one place. Upload them all to your webmail service. GMail lets you upload CSV files which you can dump out of your thick mail client. Whenever a new contact comes along, make sure you add them.
  • RSS Feeds - Get yourself a web desktop such as Google IG or Netvibes. Make it your home page. Create yourself some tabs to keep things organised and subscribe to all your RSS feeds in one place.
  • To Do List - Using the web desktop mentioned above, find the To Do List Widget and add it to your front page.
  • Post It's / Short Notes - Like when you have to take notes during a phone conversation - phone numbers and the like. Yet again, find the web desktop widget and add it.
  • Bookmarks - Free your bookmarks from your browser! Move them all to something like del.icio.us. Now you can get at them from everywhere. And you're sharing them too. If you're interested in a freinds bookmarks, add the RSS feed for their del.icio.us page to your web desktop.
  • Research Jottings - Start doing research on the web, using the web. Get a Google Notebook account and start sharing what you collect.
  • Writing Documents and Spreadsheets - Stop doing them locally with Excel and Word and then sending out various copies and trying to merge in all the changes when you get them back. Get a Google Docs and Spreadsheets account and collaborate!
  • Publish Information - If you have come across something you think others can make use of, publish it. Get yourself a blog for free and start letting others know what you know. Then incorporate their feedback.
  • Instant Messaging / Web Conferencing - Collaborate across great distances for free with Google Talk or Skype. Get a headset to speak rather than type, web cams to see who you're talking too and shared drawing boards with uSeeToo. Store your Skype contacts centrally with Skype v.3.0.
  • Podcasts - Subscribe to your favourite podcasts with iTunes. Charge up your iPod before you hit the road and keep up to date with all the news and tunes you need while away from your desk.
  • Pics - Finally, it's nice to share your pics. There are loads of cool and free photo sharing tools out there such as Flickr!, Google Photos, or PhotoBucket. Get your freinds to join too so they can see the private pics you don't want the world to see. Maybe even get involved in some groups and see what others are doing.
  • Disk Storage - This is something I don't yet use, and it's rumored that Google are working on a Google Disk. If you have any recommendations for a web disk, leave a comment and let me know.
Well, that's it. It's worth saying that you can make integration with all of these tools far easier by employing the browser plugins and extensions which many of these tools make available or have been provided by nice third parties. I use loads with Firefox 2.0 and have buttons for deli.icio.us, right click to blog something, quick toolbar access to Notebook and a "new mail" notifier. This kind of breaks the model as you to have these installed on a machine, but they're nice to come home to after you've been using someone elses system for a while.

Oh and one more thing, if you can control what you install on your local systems and it's Firefox try Google Browser Synch. This means that all the Firefoxes you use can have the same remembered passwords, search history etc. Very clever.

If anyone has any other options, comments or things to add, please add a comment.

Tuesday, October 17, 2006

JAXB, JIBX and Reverse Engineering XSD from my Java Object Model

I've got the requirement to output the contents of my object model in a readable fashion. What could be more readable than XML which led me to JAXB. The onyl problem is, with JAXB you start with the schema and go in the other direction. Step up to the mark JiXB. This allows you to go the other way and was very simple to get up and running.
  1. First step was download the bits and "install" (i.e. unzip) them (the "bits" I used were the core libs plus the utils. In my case "jibx_1_1.zip" and "jibxtools-beta2.zip"
  2. Copy the jibx-genbinding.jar and jibx-genschema.jar files from the tools zip file to the ./lib directory of your main JiBX "install"
  3. Open a command line and change directory to where your compiled classes are (NOTE: not the java source files as jibx uses introspection with the class files to do it's work. If they are in a package structure, make sure you are at the root of the package structure so that the cp declaration in the following command works. Otherwise you'll get a JiBXException about classes not being found)
  4. Auto-generate the binding file ("binding.xml") for your classes by running the following command:
    • java -cp . -jar /home/myexampleuser/jibx/lib/jibx-genbinding.jar com.myexample.ClassA com.myexample.ClassB
  5. I had warnings at this stage about references to interfaces or abstract classes:
    • Warning: reference to interface or abstract class java.util.Set requires mapped implementation
  6. I'd gone outwith the standard example on the website. Time to hit google... It turns out that out-of-the-box JiBX can handle some java.util.Collections fine like ArrayLists which my model also used but java.util.Sets (I'd used HashSet) were a little more troublesome. I needed to edit the newly created binding.xml file each time a Set-based relationship was found as follows:
    • Original: <structure field="mySetOfAObjects" usage="optional">
      </structure>
    • Updated: <collection field="mySetOfAObjects" factory="com.myexample.ObjectB.hashSetFactory">
      <structure type="com.myexample.ObjectB" usage="optional"/>
      </collection>
  7. You'll have noticed that I seem to be calling a method "hashSetFactory()" on ClassB. This is the case, and it won't be there already. You need to add a static method to this class as follows:
    • private static Set hashSetFactory() { return new HashSet();}
  8. You'll now be able to run the second command which will generate your xsd schema for you based on your new mapping binding.xml file:
    • java -cp . -jar /home/myexampleuser/jibx/lib/jibx-genschema.jar binding.xml
  9. This will then generate you the xsd schema file you have been looking for all along.

Monday, August 21, 2006

Imagining Using the Portlet 2.0 (JSR 286) Early Draft 1 Spec Release

I've done some projects which have used JSR 168 Portlets in the past. When I saw that the first public released draft of the new spec was out I thought I'd take a look. Here's my imaginings of how things would have been if we'd used this spec instead...

Lets describe my imaginary app. (The standard kind of portler app I've worked on.) The setup is simple. There are three portlets. A “search” portlet and two content portlets: “films” and “actors”. You can use the search portlets single search field, coupled with a radio button selection of the search type (c.f. google) to search for either actors or films. The results of your search are displayed in the same portlet as a clickable list.

Once a result in this list is clicked, wiring passes the actor or film id to the relevant portlet, which retrieves and displays the relevant content. If the other content portlet currently displays content, then a “reset” wire from the search portlet tells it to clear its contents.

Finally, content displayed in the actor portlet includes a list of films which they have appeared in. Clicking this link passes the film id to the films portlet which again retrieves and displays the relevant content. On this occasion there is no need to reset any other portlets. This functionality is also present from the films portlet to the actors portlet.

Clearly this is not at all possible using JSR 168 portlets alone. We were deploying to Websphere Portal Server 6.0 which gave us the ability to "wire" portlets together which were on the same page (inter page wiring has been added since then). This wiring was pretty darn complex (i've blogged about it before now) but once we got it going, we were able to get the kind of behaviour described above. In our case, even though we had all our portlets in a single war app, we passed all our parameters (such as film and actor ids) as request parameters and the wiring allowed an action in one portlet to call the processAction() method in another before all the following doView(). We only used the sessions for portlets to store their individual state, not to share it.

So how would things change if we now wanted to change to Portlet 2.0? Well the first point I'm happy to make is that we still have binary backwards compatability with 1.0 portlets. This means all our portlet code would still work. However, as the wiring was all proprietary, we would have to do something new to regain this functionality.

This is where the new "Portlet Co ordination" model comes in. The new spec (as I understand it) has added the concept of events which can be "thrown" (my terminology - almost in the same way as exceptions or events which are listened for in Swing apps is the impression that I get). These are then handled in an additional phase in the request action handling - rendering cycle which occurs after the relevant processAction() method is called, but before all the doView(), doEdit() etc. calls are made to generate the page fragments. As with wires, you can set attributes in the event (as standard types or even XML which is marshalled with JAXB - nice and flexible) which can then be picked up by those portlets which have elected (declaratively in the portlet.xml - again, nice and flexible) to react to specific
goings on which have happened (not only as a result of user interaction, but also emitted from the portal framework itself (c.f. pp. 75) The spec indicates that portlets can send what are termed "dynamic" events which are not declared in portlet.xml or, more usually static "declared" events. Finally I should note that a portlet can throw more than one event per processAction() call. Something which made things even more complicated with Websphere wires.

Clearly this is brilliant. How do we do it? Well, there's a new lifecycle interface for our portlet classes: javax.portlet.EventPortletInterface. This provides a new method which we must implement: processEvent(). To reinstate our old wired portlets, we need to take the Portlet classes we'd written, add the implementation of the interface, do some fairly hefty refactoring to move a lot of the code in many of the portlets processAction() methods to the new processEvent() method, declare our sending and receiving of events in the portlet.xml file and then deploy. Hooray! The complex WSDL for the exports and imports of data which WebSphere used for wiring is no longer required.

The final beauty of this new model is that the portal will now be happy to dynamically propagate any events as requested during operations. No more intervention is required after a successful deployment. (This is a vast improvement on WebSphere wiring jungle which would be remembered after subsequent deployments, but if you wanted to change a wire, you had to undeploy the entire portlet application and remove your portal pages again, then redeploy, put the pages back and then re wire using the admin GUI. If things still didn't work, then you'd have to undeploy, destroy and then repeat again. This wasted a lot of time.)

You should have guessed that I'm very happy that this has been added to the 2.0 spec. But while I do admit that it does seem a vast improvement on the way I have described above, I fear a few tricks have been missed in keeping this simple. Firstly, one of the few things I did like about the wiring method was that the wire effectively allowed you to call processAction() on one portlet, set a request parameter which would tell the wire to then call the processAction() on another portlet. It made sense to me and did not mean I had to understand (and debug) an increasingly complex class flow. Indeed, there could be multiple calls (as I outlined above where a click in a search result would get one portlet to display some detail and the other to reset itself) and each would follow the same route, initiated by the same original interaction from the user. The point I'm trying to make is that I'm not entirely convinced that there is a requirement for another portlet method, and its associated interface to implement. What is so vastly different between "actions" and "events" which means that they have to be handled separately?

Portlet development, even in the simplest sense is more complicated that it is with servlets - and rightly so, due to the slightly more complicated request - (action - render) - response cycle. But the aim should be to keep a sensible level of simplicity, otherwise potential developers will be driven away and the spec under used. Something JEE is only just recovering from. Consequently, it seems to me, that were the two new concepts of Portlet Co ordination and Shared Render Parameters (see below) to be linked and allow the proposed mechanism to call the processAction() methods rather than the additional processEvent() methods. The associated benefits of bookmarkable URLs (see below) could be leveraged and the present processing mechanism would be maintained. Code which was written for 1.0 could be simply updated (or in my case, little new would have to be done, we could just replace the wires with the new entries in portlet.xml to let on about who did the sending and who the receiving. Sorted.

Which brings me onto my second and final (and far shorter) area of feedback. I've already discussed what a nightmare getting the WebSphere wiring to work could be. It certainly seems vastly simpler with the "auto wiring" in the 2.0 spec, and the necessary xml configurations in portlet.xml are vastly simpler than the previous WSDL nightmare. But are the configurations necessary at all? Why do we still have to hack XML? - EJB3 showed us that annotations and sensible defaults can get us a great deal. I would also like to see the same sort of support in Portlet 2.0. Perhaps this is a way of implementing the (possibly necessary complexity) which led to the additional processEvent() step. As with EJB's, the Home, RemoteHome, and other interfaces are still there, it's just that the developer never needs to think about them, unless they choose to.

Before I close, I'd like to mention a few more quickies. Firstly, support for Java 5 - excellent - but why no support for JEE 1.5 rather than 1.4? Surely this would be an ideal to piggy back on what looks to be a storming, remarkably simplified and vastly more usable spec. The fact that the JPA can now be used outside an EJB container is a vast improvement. If portlets could then simply use this for the "M" in their MVC (we just used Hibernate and POJOs when we did our development) then everything done would be far more futureproof and allow portal implementations to run on Web Container only platforms.

Secondly, it is also very welcome to see the ability to share session state and render parameters. The possibililty of bookmarkable portlet URLs is an attractive one and will greatly increase usability and greatly simplify trying to handle the ever present threat of a user pressing the dreaded "back" button. The ability to share parameters outside the current portlet application is also a great improvement on a previously frustrating and seemingly arbitrary restriction.

All in all, I think this is a very promising looking 2.0 spec. I for one look forward to doing more portlet development in the future and coming up with even wilder ways to try and push the limits of what it can do.

NOTE: I haven't commented on the proposed AJAX or WSRP support. Both would be most welcome however and help the spec to be relevant to an even wider audience.