Monday, March 31, 2008

Wrapping Custom Profiles as Rational Modelling Tool Plugins

Apologies to Les Jones for nicking a great deal of his blog post on creating UML Model Template Plugins as the basis for this. It's really good. Check it out.

UML 2 profiles are really powerful and useful things. Its very easy to create them and if you wrap them as plugins really easy to share them too. While there is a lot of information from IBM on how to create your own custom profiles, there is not so much on how to wrap them as plugins. Here's how to do just that using RSA 7.0.5...

We'll start by assuming that you already have a profile created in a seperate project and that you've released it. If you're unclear on how to do this, check out the tutorial from IBM - Comparing and Merging UML models in IBM Rational Software Architect, Part 6: Parallel Model Development with Custom Profiles. Note: Whilst this does also cover creating a plugin from the profile, it is aimed at RSA 6.0. Things have changed a fair bit since then (deprecated APIs, different wizards etc.)

We'll take this custom profile and embed it in an Eclipse plug-in with an two extension points: "com.ibm.xtools.uml.msl.UMLProfiles" and "org.eclipse.gmf.runtime.emf.core.Pathmaps". There is ample discussion of what these are responsible for in the IBM article previously mentioned. Under this extension you specify a directory which contains the profile, any images to be used for icons and shape images and a template definition file that pulls the whole thing together and provides some descriptive text.

1. Create a plug-in project
The first step is to create a new plug-in project (File-> New Project->Plug-in Development->Plug-in Project).

Give your project a name. It’s typical to keep the project name and plug-in identifier the same; you should also be aware that the plug-in identifier will need to be unique, so use a reverse domain name style of notation. I’ll use com.musicoftime.modelling.profiles.blog. The other thing you should do is untick the “Create a Java Project” check box. Now click Next.

On this second page, change the plug-in version from 1.0.0 to 1.0.0.qualifier. I’ll explain later why; for now just trust me, it’s plug-in development good practice to suffix the version number with .qualifier. Click Finish (you don’t need to change any other options so don’t click Next). You’ll be prompted on whether you want to change perspective to the “Plug-in Development perspective“. It’s upto you whether you do or not; if you’re unsure, select No.

2. Adding the extensions
Once the plug-in project has been created, the tool will automatically open the plug-in manifest editor, which allows us to make changes to the plug-ins that we’re defining. If you accidently close this, don’t panic, just right-click your plug-in project and select PDE Tools->Open Manifest. At the bottom of the editor are a number of tabs called Overview, Dependencies, Runtime, etc. The one we want is called “Extensions” so click that now.

From here, you need to click the Add button to allow us to add the two extensions we need. Untick the check box “Show only extensions from the required plug-ins” and in the “Extension Point filter” type “*umlprofile*“. Select the extension called “com.ibm.xtools.uml.msl.UMLProfiles” and click Finish.

You will get a prompt asking if you want to add some dependencies, you must click “Yes”.

You'll now be back in the manifest editor. To add the other extension, do the same again, but this time search using “*pathmaps*“. This time there will be two results. Select the extension called “org.eclipse.gmf.runtime.emf.core.Pathmaps” (the latter is deprecated) and click Finish.

Again you will get a prompt asking if you want to add some dependencies, you must click “Yes”.

You’ll now be back at the manifest editor again. Right click com.ibm.xtools.uml.msl.UMLProfile in the “All extensions” list, and select New->UML Profile. On the right the “Extension Element Details” will show the details you need to provide. Set the name value to be something like "Music Of Time UML Profile", set the path to "profiles/MusicOfTimeUMLProfile.epx", and set "required" to "false" and "visible" to "true". Select File->Save All.


You’ll now be back at the manifest editor again. To add the extension element details to the PathMap extension right click org.ecplise.gmf.runtime.emf.core.Pathmaps in the “All extensions” list, and select New->Pathmap. On the right the “Extension Element Details” will show the details you need to provide. Set the name value to be something like "com.musicoftime.modelling.profiles.blog.pathmap", and set the path to "profiles". Select File->Save All.

3. Create the resources
Right click the plug-in project, select New->folder. The folder name must be the same as the name we put into the template extension; so for us that’s “profiles“.

In this directory we need to put three things; a profile file (i.e. a .epx file) and any resources such as icons and shape images which it might need.

3a. Add the Profile
Next is the profile; as discussed, we already have one from the IBM article which we can copy. For this, I suggest opening a new view within the tool since the project explorer view tries to be a little clever by hiding the underlying model files. Although this is useful most of the time, it’ll be a pain for us right now. Therefore we’re going to use the Navigator view; from the top menu, select Window->Show View->Other… In the “type filter text” text box at the top of the dialog type “Nav” and you should have a single entry left, which is the Navigator view (in the General category). Select Navigator and click Ok.

In the navigator view, you can see the raw file system resources. Select your profile file MusicOfTimeUMLProfile.epx. To copy, just right click the model file and select “Copy” (or press Ctrl-C) and then right click the templates directory and select “Paste” (or select it and press Ctrl-V). (N.B. You can also copy it by dragging the model file onto the templates directory whilst holding down the Ctrl key - without the control key you’ll move it rather than copy it).

3b. Add the profile image resources (GIFs and SVGs)
If you have any profile image resources add them to the plugins directory too. Make sure that if you organised them in your Profile project using folders, you use the same structure here.

4. Test it works
To test that this works, we can either export the plug-in and test it in our installation (jump to the next section for that) or you can test it by ‘self-hosting‘. Although this is done from within the RSA tool, it does involve starting up a new running copy of RSA which means you’ll not be able to do this very easily if you’re using a memory contrained computer.

To do this we need to open the PDE’s perspective (Window->Open perspective->Plug-in Development). Now select Run->Run… then right-click “Eclipse Application” and select “New“. Now we select “Run” and wait for the new instance of RSA to open.

(Depending on the capabilities of your machine, it may take a couple of minutes to launch the new RSA instance.)

When it (eventually) starts, open the modeling perspective and create a new UML Model. Once you've done that, add your profile to the model by selecting it in the explorer and in the properties view selecting the "profiles" tab. Click the "Add Profile..." button and you should see your profile in the "Deployed Profile" dropdown. Click "OK" once you have it selected. You have applied your new profile to your model. Test it is working by creating an element in your model and applying a stereotype to it - the stereotypes from your profile should be in the list of options.

5. Export the plug-in

To be able to use the plug-in properly we need to export it so that we can deploy it within the tool. First we need to configure the plug-in’s build settings to indicate what needs to be exported. You need to be in the plug-in’s manifest editor (if you closed it, right-click your plug-in project and select PDE Tools->Open Manifest).

Select the “Build” tab at the bottom. In the binary build tree, click the “profiles” folder (you’ll notice that the resources within the templates folder are automatically selected.


Make sure everything is saved (File->Save All).
To export the plug-in you need to export as a deployable plug-in. To do this, from the menu select File->Export->Plug-in Development->Deployable plug-ins and fragments.

In the export dialog, make sure that the plug-in is selected. Enter a directory where you want the export to put the deployable plug-in and click Finish

After exporting, you’ll see that a “plugins” directory has been created under the directory you specified. Within this is a single jar file that contains your deployable plug-in.

Note that the name of the Jar file is the plug-in identifier followed by the plug-in version; although the ‘qualifier‘ part of the version has been replaced with a date/timestamp. This means that exporting the plug-in twice (mode than a minute apart) will create two distinct plug-in versions. This is a good thing and I’d strongly recommend allowing this. If this is something you really don’t want then either select a specific qualifer value on export (in the Options tab of the Export dialog) or remove the ‘.qualifier‘ suffix from the plug-in version.
To deploy this, copy the Jar file to \SDP70\plugins (i.e. for me C:Program Files\IBM\SDP70\plugins) and restart RSA.

If you’ve followed these steps, the new profile will now be available when you want to apply it to a model - honest.

6. Next steps
To make deployment easier within a team, you should strongly consider create an update site and hosting it on a development or departmental server - see Eclipse - How To Keep Up To Date.

Saturday, January 05, 2008

Ruby's Glorious Negated "if" - "unless"

It continues! More and more comfort and joy ... Behold:


Ahhhh! A warm hug from my Ruby code.

Thursday, January 03, 2008

Profiling Maven 2 Apps in Netbeans 6

I thought this might be more complicated. It wasn't. To use the Netbeans profiler with your Maven 2 project you simply need to add a single pair of parameters when running your java app. Call up the project's Properties dialogue, select the "Run" tab and add something like the following to the jvm args:

-agentpath:"C:\Program Files\NetBeans 6.0\profiler2\lib\deployed\jdk15\windows\profilerinterface.dll=\"C:\\\"Program Files\"\\\"NetBeans 6.0\"\\profiler2\\lib\\"",5140

This meant that now when I ran my app (F6) execution would wait for me to attach the profiler. Cue real time graphy goodness. Sweet.

Saturday, November 24, 2007

Sunday, November 04, 2007

Dear iPod Touch...

Dear iPod Touch,

We've know each other only a few weeks now and I thought I'd write and tell you how I feel. I must say I really love your interface, and the way you seem to be just the right size and weight. I also love some of your little idiosyncracies like the fact you understand enough to stop whenever I pull out your earphones, and oh! your glorious flick scrolling and pinch resizing. That really touches [sic] me.

(It's in fact so sweet that I'll forgive you making me scroll for hours and hours to find 'United Kingdom' in the countries list on (badly designed) website registration pages... oh, and the fact that your cousin; 'Old Shuffle' herself, had a really handy play/pause button always there when someone interrupted us while we were in full swing... and then there was that night when the clocks changed and you got so high on your own moonshine heaven knows what time you thought it was until my laptop reminded you. But no matter, nobody's perfect)

But it's not all sweetness and light. Why oh why can't I have Flash in your browser? And why can I only access paid for content with your iTunes and not also my lovely free podcasts? (your evil nemesis Zune can do just that by the way) And when will I get access to the lovely mobile gmail that others waxlyrical about? But most of all why wasn't your SDK published from the very beginning? I feel like you're holding back on me.

I must admit that I was eleated when you showed me Remember the Milk's lovely ode to you (even better than Facebook's but don't let them know that) but your browser doesn't support Google Gears yet so I can't go offline; and that, to be honest is my real problem with you. Where we now live (the UK), ubiquitous and free internet is just a little bit too far away to make you the rounded package I thought you would be when we started this relationship.

Perhaps, yes, it was the crazy insanity of that night in New York when we first met that made me forget there were such practical issues to consider. But I, in my crazy, over optimistic way thought we'd soldier on, and perhaps we can. But it'll be on slightly different terms. I'm home now and despite what you melodiously sing to me each day, we aren't in Silicon Valley any more and we're going to have to wait for the full power of the new age to reach us over here. I'm hoping we can have good fun doing it. Lets try shall we?

Thursday, September 20, 2007

WAS 6.0 - Setting PMI Logging Levels and JVM args with Jython

As previously mentioned, I'm in the process of getting ready for some NFR testing. The plan is that we will make some pretty heavy use of the PMI infrastructure in WebSphere Application Server 6.0.x. There is a bunch of information that it can let us have, I just don't want all of it. Neither do I want to have to manually log in to all of my servers and tick all the little boxes in the UI. Much nicer to have a Jython script to do it automagically (i.e. set my logging level to "CUSTOM", enable the modules I need, add the JVM arg for additional info and switch on the whole shebang)....:


Tip: Figure out your settings manually, then run the script up to the bit where it pumps out your current config (comment out the rest). Then copy and paste this output into your script. Then uncomment and run again against all the other servers you're wanting to configure.

Wednesday, September 19, 2007

Using Jython to Start and Stop TPV Logging in WAS 6.0

I'm trying to automate some WAS 6.0 logging for a bout of NFR testnig which is coming my way soon. The plan is that we will use PMI to get all the info we need and use the Tivoli Performance Viewer Logging functionality to save this to file so that we can view it out leisure after the fact. It might have been acceptable to start and stop logging manually if we were able to get access to the Web Admin Console but unfortunately this is off limits to us. I've had to write the following Jython scripts instead.

Start Logging:

Stop Logging:

Note: These scripts were a bit of a nigthmare to write because of the almost complete lack of documentation of the TivoliPerfEngine MBean. However some checking of the xml config files which WAS uses, some cross referencing with the manual UI version of the same steps, and a good dose of trial and error finally bore fruit. I should thank two of my collegues (you know who you are) who helped me with some pointers when I got stuck.

Wednesday, September 12, 2007

When did Netbeans 6 go Beta?

I usually pride myself on being pretty up on the latest builds of Netbeans. However it seems that the latest release passed me by. A colleague asked me if I had the latest Beta of 6.0. "Nope" I said and checked the site. Wherever I looked I could only see the latest Milestone (currently 10) but no beta. Then he showed me this link. Does this mean 6.0 went beta silently? Did I miss the announcement? What's up guys? Loving the new pastille icon though...

Friday, August 17, 2007

Aaaaaaarhg!

Why can't the Blogger compose tool realise when I've cut and pasted some html / xml / "something technical with characters html needs escaping" and
just escape them for me? Please?

CSS two and three column layout without absolute positioning (for IE, Firefox and Safari)

We all know it's best practice to use divs for HTML layout over tables and there's loads of examples out there of how to do it. The problem all the ones I found used absolute positioning or fixed width columns. I wanted to see if I could do it (or get close to it) without making these compromises. Here are the results.

Two Column Layout

Admittedly there are a few problems with this. When you resize the window below a certain size columns will jump into the left hand side of the screen. Not entirely like a table. Also the % widths cannot add up totally to 100%. I don't really understand why.

Also, please note that in this two column layout, you can only have one nav column plus the middle column on a page. If you have all three, the layout breaks. If you want both a left and right hand side nav column layout (i.e. a three column layout), you need to change the % widths to something like 25%, 40% and 25% respectively.

Table Layout Substitute
Finally, here's some CSS to use to replace tables when you've used them for things like laying out froms:

and here's an example of the 2 column layout plus the table substitute in use:

Again, there are a few problems, mainly around the content sometimes spilling when the windows are tool small but it works pretty well.

If you doubt this works, here are some screenshots of it on Firefox 2.0.0.6, IE 6.0 and Safari (all on Windows XP).

Thursday, July 26, 2007

grubby - a quick and dirty data generation tool

Over the past few weeks I've been open sourcing code from the last few projects I've worked on. It's firstly a set of classes providing random generation utilities plus some handy utility methods. These are available in a 0.1 release from the project website and you can use them now.

Building upon this, next I'll be working on a set of "data beans". The idea is that these will be simple POJO representations of a row in a database or a CSV file, capable of toString'ing themselves to CSV or a SQL insert statement and stored in collections which are self iterating (think ruby). If this sounds like your common or garden data model beans with a little extra functionality, you'd be right. Ideally, this component can leverage a from-schema generation tools based upon EJB 3.0/JPA 1.0 (such as Netbeans) so you don't have to write these yourself. These can be edited so they extend the grubby data beans abstract classes which provides the extra grubby functionality. To use, all you need to do is generate your beans, fill them with random data using the aforementioned generation utilities and then get them to toString themselves to the data upload file type of your choice - SQL or CSV.

Beyond this I plan to create a set of annotations to use so you can simplify the definition of the allowed values for an attribute and also specify the relationships between beans with ease. In addition, there will be a config engine so users can specify where input and output files are located and a set of common builders to reduce the need to implement some common elements entirely (e.g. Addresses).

So, if it sounds like this is something you might find useful, please go to the site and take a look. If you want the javadoc and other information, checkout the project source and generate the maven site (run the "maven site" goal). If you want to help, check out the code and have a look. If you have some comments, suggested changes or a patch, send me a mail. Enjoy.

Wednesday, July 18, 2007

Setting Trace Logging Levels in WAS 6.0 with JACL

I've recently had to change the trace logging levels in a WAS instance without the aid of the web UI. Here is the wsadmin JACL script which I used to do it:
# NOTE: Edit the following two variables for your environment
# They can be discerned from the path to your instance's bin directory
# The following shows the deployment manager ("dmgr") in the "myCell" node
set node myCell
set server dmgr

# Get up the variables required by the rest of the script
set svr [$AdminConfig getid /Node:$node/Server:$server/]
set ts [$AdminConfig list TraceService $svr]

# Modify the trace settings
# NOTE: Edit this settings string to reflect the settings you require
$AdminConfig modify $ts {{startupTraceSpecification *=warning=enabled:SystemErr=all=enabled}}

# Make the changes permanent
$AdminConfig save
To run it just save it as a file called set_trace_levels.jacl and run with the command:
./wsadmin.sh -port [SOAP port] -user [myWASAdminUID] -password [myPassword] -f set_trace_levels.jacl
NOTE: If you're on Windows, change "wsadmin.sh" to "wsadmin.bat"

Thursday, July 12, 2007

Overheard in I.T: "I am not a Number!"

Consultant #1: "We're a team. But we're a team of ... individuals..."
Consultant #2: ?!?!

-- Wardour Street, Soho, London

Apologies to Overheard in New York

Friday, June 01, 2007

Notes from JavaOne 2007 - The Semantic Web (BOF-6746)

This post is a tidied up version of the notes I took at Henry Story's BOF (BOF-6746) at the 2007 JavaOne variously entitled "Web 3.0: This is the Semantic Web" or "Developing Web 3.0". They are best read alongside the presentation. Henry moves fast...

Definitions
"PC era" - "The Desktop" (1980 - 1990)
"Web 1.0" - "The World Wide Web" (1990 - 2000)
"Web 2.0" - "The Social Web" (2000 - 2010)
"Web 3.0" - "The Data Web" -> "The Semantic Web" (2010 - 2020)
"Web 4.0" - "The NetOS" -> "The Intelligent Web" (2020 - 2030)

[DEMO] "Web 2.7" - Freebase. This is a Semantic wiki. It is all structured data. You can create classes of things. If I create a new film it will create a new film object and the information about it. I can also create my own classes. I am creating a database on the web

Pic: "It's Dog Simple - It's not complicated. Reality is complicated."

Web Architecture 101
  • URI (encompasses URLs and URNs) - "Universal Resource Identifier". This identifies a Resource. You might as well use URIs as they are
  • REST - "Representational State Transfer". A URL in a web browser can do an HTTP "GET" and a Representation of the Resource mapped by the URL is returned. A resource can return any number of representations.
  • Caching - The Web can cache Representations. If I call the same URL I get the same result.
  • Relations - REST consists of relations. RDBMS has limitations: relations are local, not universal. We want to webify the DB. If you add URIs to the Subject (e.g. "Tim"), Relation (e.g. the column name - "Name") and the Object (e.g. the row id'd by the Primary Key) we can get an Object with a "GET". You simply click on the URL to get it's meaning. Relations are now universal
  • RDF - "Resource Description Framework" - URI's exist to define Subjects , Relations/Properties and Objects
  • RDF with namespaces - Simplifies the URI's with @prefix. E.g. @refix foaf:
  • Syntax (how the URI strings combine to identify Objects) versus Semantics (how URI strings relate to the world - what they map to)
Advantages - Simplicity.
  • URIs are the only way to identify resources worldwide.
  • REST is the most scalable and simplest way to set up a universal info space.
  • RDF - you can't do it with less than a triple (Subject, Relation/Property, Object), it has syntax independence and is clickable (i.e. click the link) data
FOAF
FOAF is a simple ontology to describe friend of a friend relationships (Available today on blogs) - it is an example of a semantic dataset

N3
Another way to write down RDF data

OWL
Ontology Web Language - a set of resources which define things like classes, properties, the set of relations required to do something with an object in programming

DOAP
Description of a project (another ontology - we can use classes from different libraries. It is all in one uniform information space). This is being used today to describe OSS projects. Once informarion is explsed in this format it can be scraped and aggregated

Tools
There are ~500 Semantic tools, 50% in Java
  • DOAP integration with Netbeans
  • Protege - lets you define ontologies
  • TopBraid Composer - define ontologies and instance data
  • @RDF annotations in Java - there is a java.net project
  • Baetle - Bug And Defect Tracking Language
    • Uses - once you can track bug info from all OSS projects you can create bug hierarchies (e.g. "this bug from NB depends on this bug from Apache")
  • SPARQL - Semantic web query language. This is being stabdardised in the W3C. It looks a lot like SQL. If you have RDF data srored in a repository, you can then put a SPARQL endpoint in front of that. The data comes back as lists of RDF triples. You can query > 1 repository and then compare all the results by URI - the same URI means it is the same item. Therefore you don't need to refactor multiple databases together. You can get results back as simple XML(JSON)
  • RDF databases - The right way to do it is to publish data at URLs. You link all this information to see what new information you can get. To be meaningful, you need to know where the individual pieces of data came from to allow preferences of different data resources. "Reasoning". You can publish RDF onto a web page. Or you can publish it in an RDF database. There is a new class of DB to store this - "Triple Stores". These are more optimised for big lists of triples than an RDBMS
  • Semantic Wiki
  • Semantic Desktop - if all your data is all over your desktop and your web, the only way to keep track of this is to use URLs
Read More
http://blogs.sun.com/bblfish

Monday, May 28, 2007

Notes from the FindBugs BOF9231 at JavaOne 2007

NOTE: These are my incomplete notes from the FindBugs BOF at JavaOne 2007. I got in late due to the crush outside so missed the start of the session.

The latest release has some new(ish) features:
  • Annotations for @NotNull, @CheckForNull, @CheckReturnValue
  • JSR 305 (Annotations for Software Defect Detection) will standardise these annotations so that they can be used in multiple tools.
  • They will be released in a javax package
  • The EG has a google group for discussions and there is already unofficial output: annotated versions of standard libraries.
Using Findbugs to Compute a Bug's History
  • Findbugs can keep track of when a bug was introduced and when it was resolved. This is recorded in histotical data (xml format)
  • Bugs can be audted by a user and annotated in the history (e.g. must fix, not bug, etc. plus a free text area for more notes)
  • This functionality is integrated with various IDEs. (IDEA, Eclipse, Netbeans)
Ways to Use FindBugs
  • Command Line Interface
  • FindBugs Tool (a Swing UI)
  • Ant
  • Maven
  • Other IDEs
Using Findbugs Well
  • Run it every night or at least every build
  • The results of audits should be remembered (i.e. once a bug is marked, don't forget it)
  • You should be able to identify which bugs are new in the build and which have been there since the last release
  • You should be able to identify bug patterns which are of concern to your project
  • Google are using it and have a paper (which I can't find at the moment) describing their experiences and how to incorporate it into a production development environment
Future of the Project
  • There are currently 1.3 developers (as of the BOF)
  • There is a need to build a better OSS community
  • The "documentation sucks"
  • Mailing Lists
    • findbugs-announce
    • findbugs-discuss
    • findbugs-core
  • There is also a google group
Update - It seems as if FundBugs may be moving to GoogleCode for its hosting

JavaOne 2007 - Closures for the Java Language - TS-2294 and BOF-2358 Notes

NOTE: This is an aggregation of the notes I took from Neal Gafter's two sessions at JavaOne 2007 on his Closures for the Java Language proposal.

"Why add closures? Isn't Java complicated enough already?"
“ In another thirty years people will laugh at anyone who tries to invent a language without closures, just as they'll laugh now at anyone who tries to invent a language without recursion.” — Mark Jason Dominus

Goals of the Closures Spec Proposal
  • Provide concise "function" literals - without the pain of anonymous instances (i.e. anonymous inner classes)
  • Interoperate with existing APIs (esp. java.util Collections)
  • Solve problems which Anonymous Inner Classes can't - simplify
  • Enable control APIs (c.f. Scala, Ruby)
  • Wrapped code not changed
  • Function and aggregate operations
  • Write methods which act like new keywords (but only act like)
  • Simple but powerful
Definitions
  • A "closure" is a function which refers to free variables in its lexical context where a "function" is a block of code with parameters that may produce a result value.
  • A "free variable" is an identifier used but not defined by the closure.
  • "Control APIs" are API specific statement forms on a par with built in statements, like special methods.
Problems with anonymous instances
  • Verbose, extra wordy, clumsy, redundant - whereas closures are concise
  • They incompletely capture the lexical context - i.e. "this" and "toString( )" don't refer to what they ought; return, break and continue operate differently also, and you cannot use non final local variables
  • Consequently they force irrelevant refactoring
  • Control APIs are not possible - You cannot wrap arbitrary blocks of code
Specification
Syntax - Closure Expressions
{int x => x+1}
{int x, int y => x+y}
{String x => Integer.parseInt(x)}
{=> System.out.println(“hello”);}
Primary:
Closure
Closure:
{ FormalParameterDecls opt => BlockStatements opt Expression opt }
  • Creates an object which represents code of the body and the lexical context
  • Few restrictions - may access local variables and this and may return from the enclosing method
The closure conversion turns a closure into an instance of some interface
  • This provides interoperability with existing APIS
  • Means you can restrict the closures operations (but you must do this explicitly. It is not done for you by default)
  • If there is not target type, it will use the natural function type
Syntax - Function Types
{int => int}
{int, int => int}
{String => int throws NumberFormatException}
{ => void}
{T => U}
Type:
{TypeList opt => Type FunctionThrows opt }

{String => int throws NumberFormatException} is shorthand for java.lang.function.IO where
package java.lang.function;
public interface IO {
int invoke(A a0) throws X;
}
  • Function types are "ordinary" interface types with an invoke method
  • You can extend and implement them
  • They can declare variables, parameters, return types etc.
  • (There are no special type rules)
Syntax - Control Statements
withLock(lock, {=>
doSomething();
});
withLock(lock) {
doSomething();
}
ControlStatement:
for opt Primary ( Formals : ExpressionList opt ) Statement
for opt Primary ( ExpressionList opt ) Statement

Is translated to:
Primary( ExpressionList, { Formals => Statement });

Examples
1. Control APIs - Perform some operation while holding a java.util.concurrent.Lock
(a) Today:
void incrementBalance(int deposit) {
myLock.lock();
try {
balance += deposit;
} finally {
myLock.unlock();
}
}
(b) Using a proposed new closure-based API:
void incrementBalance(int deposit) {
Locks.withLock(myLock,
{ => balance += deposit; });
}
(c) Using the control statement syntax:
void incrementBalance(int deposit) {
Locks.withLock(myLock) {
balance += deposit;
}
}
2. Aggregate Operations - Make a new list by applying a function to each element of an existing list:
List parseInts(List strings)
throws NumberFormatException {
return Collections.map(
strings, {String s => Integer.decode(s)});
}
3. Interaction with existing APIs - launch a task using an executor
(a) Today:
void launch(Executor ex) {
ex.execute(new Runnable() {
public void run() {
doSomething();
}
});
}
(b) Useing a closure:
void launch(Executor ex) {
ex.execute({ =>
doSomething();
});
}
(c) Using the control statement syntax:
void launch(Executor ex) {
ex.execute() {
doSomething();
}
}
3. Interaction with existing APIs - Add a Swing listener
(a) Today:
void addListener(final ItemSelectable is) {
is.addItemListener(
new ItemListener() {
public void itemStateChanged(ItemEvent e)
{ doSomething(e, is); }
}
);
}
(b) Using a closure:
void addListener(final ItemSelectable is) {
is.addItemListener(
{ ItemEvent e => doSomething(e, is); }
);
}
(c) Using the control statement syntax:
void addListener(final ItemSelectable is) {
is.addItemListener(ItemEvent e :) {
doSomething(e, is);
}
}
New APIs
  • API specific control constructs - Collections (e.g. Map Specific iteration), concurrency (e.g. locking) and closables (e.g. resource streams closed automatically at the end of a block)
  • Aggregate operations. E.g.:
List list = …;
Integer sum = Collections.reduce(
list,
{Integer x, Integer y => x+y});
  • Functional primitives

Questions from the Audience
"How do you deal with the namespace issue?"
  • A closure is a method name therefore you have your own scope
  • Use an import statement - a closure is just an API method
"Have you thought of restricting the use of closures? i.e. a member variable which is a closure which extends a generic"
  • No, no one can determine what is and what isn't useful. Just because you can't think of a use case, doesn't mean someone else won't. The only reason you would do something is because you need to.
  • The proposal includes ways for all API writers to restrict how closures are used with them, but blanket restrictions would be trouble.
"How do closures get executed?"
  • The closure expression has parameter types, a return type, and types it uses within it. The compiler analyses this but does not go and impose this on the closure.
  • It works like overloader resolution - it picks which is most specific, therefore there is no type inference but there is a compatability rule.
"How do I pass multiple parameters?"
  • You don't need to. Everything outside the closure can be accessed from within the closure.
"How do we evaluate whether we should add 'this'? - and will it make Java simpler?"
  • It will make it easier to write and read. ("I'm hoping for a video with a Star Wars theme to help me decide") Java today is not the easy Java we had in 1999
Where Can I Read / Hear More?

Saturday, May 26, 2007

RESTful Web Services: JSR-311 (TS-6411) at JavaOne 2007

These are the notes which I took during the RESTful Web Services Technical Session at JavaOne 2007. Eventually the presentation audio will be available but until then this should provide a good overview of what was said.

Speakers: Paul Sandoz, Marc Hadley, Peter Liu

Definition
"REST" is the architectural style of the WWW. Note that "style" is not "architecture". Coined by Roy Fielding in his PhD thesis.

Tenets
Resources
- These can be considered as the Platonic ideal forms. They are identified by "Uniform Resource Identifiers" ( aka "URIs") and realised by "Representations" which are the equivalent of the shadows in our Platonic Cave metaphor.

Methods - Methods are how we interact with the resources. In the HTTP paradigm these are as you would expect GET, POST, etc. The key is that they are a small set and fixed for all resources. They facilitate the exchange of the representations.

Representations - Representations embody the state of a resouce r at time t. Therefore,you can see that there can be multiple, alternate representations of a given single resource R. It can be conceived of as a finite state machine.

REST vs. RPC
RPC
Few endpoints. Few nouns but many verbs e.g.:
musicdb.getRecordings("my_artist")
REST
Many resources, few fixed methods. Many nouns and few verbs e.g.:
GET /music/artist/my_artist/recordings
Caching
REST allows you to cache because caches can understand the semantics in the protocol. These are not embedded in the message as they are in RPC.

HTTP
HTTP is an application protocol. RESTful web services are "of the web". Don't hide / ignore elements in the network which help you - e.g. caches.

Why a Java REST API?
Lots of companies now offer them (Google, Amazon, eBay, etc.) to expose their services. Where both WS-* and REST APIs are offered, REST are more widely used. It is proposed that this is due to their simplicity (they are easy to consume with common web scripting scripting languages such as PHP) and ability to use web browsers for testing.

The current Java web APIs (e.g. the Servlet API) are too low level though they can be used to implement a REST Web Service. There are many opportunities to simplify development as there must be a better way:
  • High level
  • Declarative
  • Clearly maps to REST concepts
  • Takes care of the boilerplate code
  • Makes it easy to do the right thing
  • Provides a graceful fallback to a lower level API when it's needed
API Elements
Java doesn't really have a concept of a Representation or a Resource. If we try and code a REST servlet without the API we see that we would need to implement content negotiation (what form the Representation should take e.g. xml, text, etc.) and path parsing ( e.g. what Resource(s) have been requested ).

Automate Content Negotiation
Declare what content will be returned:
@ProduceMime("application/xml")
protected void doGet(HttpServletREquest request,
HttpServletResponse response)
URI Templates
Declare what method responds to which requests:
@URITemplate("/artists/{id}") public class Artist extends HttpServlet { ...
This means your container should only call this servlet when requests match this template. To take this one step farther we can combine and apply these annotations to a POJO:
@URITemplate("/artists/{id}")
@ProduceMime("application/xml")
public class Artist { @HttpMethod // Needed as we no longer implement HttpServlet InputStream getXml(@URIParam("id") String artist) { ... } @ProduceMime("application/json") @HttpMethod // Needed as we no longer implement HttpServlet InputStream getJson(@URIParam("id") String artist) { ... } @HttpMethod @UriTemplate("recordings") InputStream getRecordingsXml(@UriParam("id") String artist) { ... }
}
Declaring Resource Class Methods
@HttpMethod - The method name can then be anything with the default HTTP methods being taken from the annotated java method name. E.g:
@HttpMethod public XXX getXXX( ) { ... } @HttpMethod("GET") public XXX find( ) { ... }
Method Return Types HttpResponse - provide specialised subclasses for common types of response such as Redirect, Resource Creation, etc.

Representation - provide control of entity related headers such as media type, language, etc.

T - when a default media type can be determined. This is extensible via the SPI.
@HttpMethod
public Recording getRecording( )
Method Parameters
There may be multiple annotated with @URIParam, @QueryParam, @MatrixParam, @HeaderParam (flexible typing) plus zero or one of type Entity or T. E.g.:
@HttpMethod
public Recording updateRecording(
@URIParam("id") String id, Recording updatedRecording)
Deployment Options
  • Servlet and Java APIs for XML web service (JAX-WS) providers will be required by the JSR
  • The Sun Reference Implementation will also add support for Grizzly and the Java SE 6 lightweight HTTP server
  • Restlet support expected - for fall back if needed
  • SPI for other containers
Issues
  • Annotations vs. Classes and Interfaces?
    • Annotations are good for static information
    • Classes and Information are good for dynamic information
    • When to use? It is nice to replace a lot of logic with a nice annotation
  • Resource Lifecycle?
    • Per request, per session or singleton?
  • Container or API - what should go where?
    • Security
    • Filters / Guards
  • Other language support
    • Annotation support is difficult in JavaScript and Ruby
    • Low level APIs start to lose the benefits
Summary
  • High-level declarative programming model
  • REST concepts reflected in the API
  • Flexible typing, runtime takes care of common conversions
  • SPIs to extend capabilities
  • Pluggable support for types, containers, and resolvers
  • Flexible deployment options

Monday, May 21, 2007

JRuby on Rails - Agility for the Enterprise (TS-9370 at JavaOne 2007)

These are the notes I took on Charles and Toms talk at the 2007 JavaOne conference. The slides are also available and I'll link to the presentation when its up too, though for now, you have to put up with this...

"See how the other 8% lives"
Ruby is gaining in popularity and developer mindshare. This is largely due to the killer app that is Ruby on Rails (or "RoR"). JRuby is a Java implementation of the Ruby Interpreter (commonly referred to as "Matz's Ruby Interpreter" or MRI after its creator). Because Rails is written in Ruby, it is possible to run Rails apps on JRuby. Charles Nutter and Thomas Enebo have come to talk about it.

Charles started off life as a Java EE architect. Tom was a web app architect. Now they are both working on JRuby after having been hired by Sun. The aim is for it to become a first class language citizen on the JVM.

"What is Ruby?"
  • It's a dynamically typed language
  • It's fully object oriented
  • It is designed to be simple, productive and fun to use
  • It is interpreted (rather than compiled)
  • The original interpreter, MRI, is written in C (and is sometimes referred to as "CRuby" by the JRuby crowd
  • The implementation (which is open source) is the only specification (though this may change)
  • It was created to be "more powerful than Perl and more OO than Python"
Pure OO
Example:
7.class => Fixnum
There is also sweet syntactic sugar for literals:
  • For regex
  • Literal arrays on 1 line
  • Associative arrays / hashes
  • Strings: "foo"
Dynamically Typed
Ruby doesn't care about an Objects type, only about the operations which it can perform. Consequently it throws "no method error" runtime exceptions.

Modules
Ruby only has single inheritance. However it also includes Modules (also called "Mixins") which you can include in your classes to provide additional functionality. They are a mix between Java's Interfaces and Abstract Classes.

Blocks
Blocks (which are also referred to as "closures" in other languages) are methods that you can pass around your code and invoke when you want to. This invokation is on the end of the method call and means that you can remove repetitive code and defer things such as the logic of iteration to collections themselves, allowing them to call out to the block for the processing logic at each step.

They also allow you to internalise transaction code. E.g.
File.open(filename) { | file | line = file.gets }
In this example the file is autoamtically closed. You need not worry about this as a programmer.

It is for these reasons that closures are under consideration for inclusion in the Java language.

Meta Programming
In Ruby Classes and Modules are always open. This means that you can dynamically include them at any point. You can also provide dispatch methods such as method_missing which intercepts and safely handles calls to non existent methods. There is an equivalent const_missing variable.

"What is JRuby?"
The JRuby project was started in 2002 and is a Pure Java, open source implementation of MRI. It is aiming for full compatability with the current Ruby (v. 1.8). This compatability is the primary focus, over performance.

It integrates with Java via the Bean Scripting Framework, JSR-223 and Spring. It is supported by a growing set of external projects such as Goldspike and ActiveRecord-JDBC.

"Why JRuby over Ruby?"
  • Soon it will be faster (the team are working on a compiler so you can run your Ruby applications as JVM bytecode)
  • Scales better (it uses native threads whereas CRuby uses green threads)
  • Native unicode support (CRuby is working on this now, JRuby leverages Java)
  • Integration with the Java libraries (include "java")
  • Easier path into the enterprise - how? See below...
"Why JRuby over Java?"
  • Language features available now (blocks, modules, metaprogramming)
  • Ruby applications / libraries (Rails, RSpec, Rake, Raven, etc)
Ruby on Rails
Rails is a full stack MVC framework written in Ruby which is open sourced under the MIT licence. It was released in 2004 and was written by David Heinemeier Hansson. RoR books already outsell those on Perl. It has a single threaded, share-nothing architecture and ships with MacOS X Leopard.

Rails Precepts
  • Convention over configuration - Based on the philosophy of "why punish the common cases?" this encourges standard practices by making them as simple as possible. In many cases, there is nothing for the developer to do at all. This makes everything simpler and smaller
  • Don't Repeat Yourself ("DRY") - Everything in RoR is written with the minimum of repetition. Repeated code is hard to adapt, maintain and less agile
  • Agility - RoR apps run from the forst command you type. There is no configuration of your environment. This allows for true iterative development from the very beginning. You can show what you do and see your changes live
"Why use Rails?"
  • Greatly Simplified - There is a lot less code in a Rails app than a comparable Java Web App
  • Instant Applications
  • Growing and excited community
  • Small applications are trivial to create
  • Excellent language
"Why use JRuby on Rails?"
  • You can deploy to Java Application Servers as a self contained WAR (using Goldspike)
  • These java web containers environments are already pervasive - it is easier for an enterprise to switch their MVC framework than a whole deployment architecture. Therefore the barrier to entry is reduced
  • Broader, more scalable database support (with ActiveRecord-JDBC)
  • Integration with Java libraries and legacy services - leverage your existing APIs and services
Rails Project Layout
Each Rails project has the same layout (Convention over Configuration at work).
myapp
app
controller - the "C" of MVC
helpers - DRY extracted code from the other app elements
model - the "M" of MVC
views - the "V" of MVC
config - config files
db - db config and migrations files
lib - libraries
public - static html content
test - unit tests
You put your code in the controllers and views. There is no need to wire everything up unlike in Struts or JSF.

Rails Tools - CLI
# rails myapp - Creates a rails app with the above structure called "myapp"
# ruby script/generate - Generates the MVC, migrations and scaffolding etc for your rails app
Components
  • ActiveRecord - "ORM on steroids"
  • ActivePack - View/Controller
  • ActiveWebServer
  • ActiveMail - Mail support
  • ActiveSupport
The Demo
NOTE: What follows are my notes from the demo of pertinent points made. No attempt is made to convey the content of the demo as a whole)
  • We are running in Rails development mode
  • "Migration" - This is a DB agnostic way to specify a DDL in Ruby. They are versioned and allow for a replayable record of DB schema changes (hence "migration"). This allows a developer to save these to VCS and in the future set up the DB to a specific schema version
  • Rake is like make/ant but written in Ruby. It's not just for Ruby
  • # rake db:migrate - generate a schema on your DB for the migration chosen
  • Scaffolding - allows you to be up and running quickly. It generates the simple MVC components for an entity
  • Deployment to a Java Application Server (e.g. Glassfish)
    • Use goldspike to create a WAR file automatically which contains my application and all the libaries (Ruby and Java) which I need to run my Rails app.
    • war.rb is the config file
    • Library dependencies are drawn from maven
    • # RAILSENV=PRODUCTION rake db : migration - Change to production mode
    • # rake war : standalone : create - WAR up your app. This is all you need to deploy
"Why Run on Glassfish?"
  • Multithreading - when you run Rails in an application server extra JRuby servers spin up as you need them. In CRuby you need a "pack" of single threaded Mongrel web servers.
  • Pool DB connections (there is no DB connection pooling on CRuby Rails)
  • Access any JNDI API resource from your Rails app
  • Access any JPA datasource
  • Therefore this is a new way to do the front end of your Java EE application
Futures
  • Rubify the JEE platform APIs
  • Port the Ruby native libraries (some Ruby libraries are partially or wholly written in C and cannot be used with JRuby)
  • Mingle from Thoughtworks - Software tool to manage agile IT projects written totally in JRuby
  • ActiveJPA and ActiveHibernate