Stubbisms – Tony’s Weblog

February 18, 2009

Fighting Scala – Scala to Java List Conversion

Filed under: Scala — Tags: , , — Antony Stubbs @ 2:42 pm

Apparently this is going to be addressed in Scala 2.8, but until then there’s an annoying little detail when dealing with Java libraries (in my case, Wicket), from Scala. That being that methods requiring java.util.List types cannot be called with scala.List types.

The offending code:

val issues = List( 1, 2, 3 )
new org.apache.wicket.markup.html.list.ListView(wicketId, issues) {...

3

Causes this compilation error:
error: overloaded method constructor ListView with alternatives (java.lang.String,java.util.List[T])org.apache.wicket.markup.html.list.ListView[T] (java.lang.String,org.apache.wicket.model.IModel[java.util.List[T]])org.apache.wicket.markup.html.list.ListView[T] cannot be applied to (String,List[String])

There is a collection of implicit conversion functions for going from java.util.List to scala.List in the scala.collection.jcl.Conversions object, but not go go the other way around. These functions look like:

object Conversions {

implicit def convertSet[T](set : java.util.Set[T]) = Set(set)
implicit def convertList[T](set : java.util.List[T]) = Buffer(set)
implicit def convertSortedSet[T](set : java.util.SortedSet[T]) = SortedSet(set)
implicit def convertMap[T,E](set : java.util.Map[T,E]) = Map(set)
implicit def convertSortedMap[T,E](set : java.util.SortedMap[T,E]) = SortedMap(set)</code>

implicit def unconvertSet[T](set : SetWrapper[T]) = set.underlying
implicit def unconvertCollection[T](set : CollectionWrapper[T]) = set.underlying
implicit def unconvertList[T](set : BufferWrapper[T]) = set.underlying
implicit def unconvertSortedSet[T](set : SortedSetWrapper[T]) = set.underlying
implicit def unconvertMap[T,E](set : MapWrapper[T,E]) = set.underlying
implicit def unconvertSortedMap[T,E](set : SortedMapWrapper[T,E]) = set.underlying

}

22

With some friendly advice, I created the following conversion functions to do the conversion, including 2-dimensional (lists of lists) lists.

implicit def convertScalaListToJavaList(aList:List[String]) = java.util.Arrays.asList(aList.toArray: _*)
implicit def convertScalaListListToJavaList(aList:List[List[String]]) = java.util.Arrays.asList(aList.toArray: _*)

11

The obscure notation (aList.toArray: _*) is required as described in section 8.8 Repeated Parameters page 188 of the Programming in Scala book:

“This notation tells the compiler to pass each element of arr as its own argument to echo, rather than all of it as a single argument.”

and in 4.6.2 Repeated Parameters in The Scala Language Specification Version 2.7:

Furthermore, assume the definition:
def sum(args: Int*)
val xs = List(1, 2, 3)

The following applications method sum is ill-formed:
sum(xs) // ***** error: expected: Int, found: List[Int]
By contrast, the following application is well formed and yields again the result 6:
sum(xs: _*)

To cut the story short, it is required because the asList method accepts variable number of object arguments, but we are passing in a single list object. The : _* tells the compiler to instead pass in each element of the list individually, so that it looks like varargs. And as suggested by someone on the channel, it is consistent, if obscure, notation. When you read it, keep in mind that variableName: ObjectType is normal notation in Scala for specifying the type of a declared parameter. So instead of a concrete type, we are specifying “any” type ( ‘_’ ), “any” number of times ( ‘*’ ).

Not so bad eh? ;P

Advertisements

December 25, 2008

Aaaaand we’re done.

Filed under: General, Java — Tags: , , , , , , , — Antony Stubbs @ 4:09 am

Just under 4 months ago, I left New Zealand, heading for The Netherlands (Holland) to take up an invitation to work on Portal technology at Componence. This has taken me to Armin van Buren in Belgium, Lviv and Kiev in Ukraine, Munich and the Oktoberfest (thanks Stefan! I am sooo coming back next year) and I trip to Oslo, Norway to visit an old university friend.

Oh and in the Netherlands I found an 80,000 EURO TV. Nice.

That's 80,000 EURO$, 194,025 NZ$, 112,000 US$

That's 80,000 EURO$, 194,025 NZ$, 112,000 US$. I think the ones sitting next to it there are 40" TVs - they look small eh?

On my way over to Europe, I went through San Francisco which was really cool – while I was there I snapped some fan-boy pics:

Motorcycle tour of the Google campus

Motorcycle tour of the Google campus

And now, here I am, in Melmo Sweden, enjoying the beginnings of my holiday with old family friends from Australia. Like a flash, my contract is over. It all stemmed from my seemingly innocent comment on a blog from a core member of the Wicket team. Just goes to show, if you open yourself to opportunity and put yourself out there a bit, you never know what will happen.

I had a few posts planned regarding this, but this has been a very busy trip with lots of new aspects of life to get used to. Now that my ‘proof’ is complete, I shall re-balance things a bit and get a whole lot of draft posts out onto the blog.

I left my job at IBM to follow my passions…

I left my job at IBM in New Zealand before I found this contract. There are a few reasons why I left, but they are pretty much summed with with saying that I felt I could progress in my career at a pace more suited to my liking if I left. One of those aspects was working overseas. Buy me a beer and I’ll tell you the whole story.

What I really want to do is work on new technology, not simply the application of.

Ever since I was young I wanted to work on satellites at NASA which is not really the typical childhood dream. But working on Play Station 4 would suffice 😉

My Work on Wicket Portlets

One major aspect of my work here was completeing the Portlet 2.0 specification JCR 286 implementation in Wicket. Wicket of course being one of the Top web development frameworks today and a pleasure to work with. All the work sits under the Wicket issue WICKET-1620.

JavaDoc

When I came on the scene, Portlet 1.0 support was complete, with the help of Apache Portal Bridges and work on Wicket resource serving support was mostly complete. The first daunting task however, was completeing the documentation for nearly the entire existing Portlet support in Wicket. This was a big learning experience and a deep look into Wicket internals (which btw, made me a bit nervous about my upcoming event implementation task). This was mostly completed in WICKET-1875, with the a lot more additional javadoc included in my patches for WICKET-1620.

Events

It was pretty much decided that I wasn’t going to try and do anything at this stage with the public render parameters part of the spec, and was going to focus on the Events system. This was a much bigger task than any of the other parts of the Portlet 2.0 spec, and a lot more complicated than I expected.

However, in the end, I think I came up with a pretty nice solution. After some false starts, I ended up implementing with custom

  • WebRequestCycleProcessor
  • AbstractBehavior
  • BehaviorRequestTarget

aptly named

  • PorletWebRequestProcessor
  • AbstractPortletEventListenerBehaviour
  • PortletEventRequestTarget

This really fits into Wicket superbly well, a testament to the sophisticated, yet reasonably straight forward (considering the problem domain) extensibility of Wicket. Bravo.

The patches are sitting with the issue, and now that I have some extra time, I will massage them some more and I’m confident that they will be in Wicket 1.5. Included with the patches is also a simple example application.

Known issues with the implementation at this stage are:

  1. Issues around events in response to events
  2. Resource URL’s being generated for links, in some cases, instead of Action URL’s.

On my second to last day at Componence, I gave a presentation to the company on the work I had done. Posted below are two small sections of that presentation (Keynote is lots of fun) which show the gist of it.

Basic flow of code through the events sub-system

Basic flow of code through the events sub-system

Triggering an event is merely a call into the Portlet API and letting the hosting Portal take care of the rest.

The basic steps for receiving a Portlet event are as follows:

  1. Wicket receives an event request – this is like a normal HTTP request (or a Action request in Portlet speak – so to speak 😉
  2. Wicket calls into the custom (registered) PorletWebRequestProcessor.
  3. The PorletWebRequestProcessor checks the context is an Event Request – otherwise the processing is delegated to the parent.
  4. The Request Target is resolved to the custom PortletEventRequestTarget.
  5. During the normal Wicket request processing, at the appropriate stage, calls into our PortletEventRequestTarget the processEvents method from the IEventProcessor.
  6. Inside this method call, we search through the page’s component tree looking for behaviours attached to components which extend the AbstractPortletEventListenerBehaviour. The search performed is a depth first recursive search. I have a niggling feeling that this could perhaps be improved somehow.
  7. When found, the event name is checked to see if it matches the name of event the behaviour is registered as wanting to subscribe to.
  8. If they match, we call into the behaviour, passing in the Event.
  9. Hey presto!

In hind sight it all seems a little simple now 😉 But of course I have come out the other end a much wiser and learned man – gotta love the opportunity to learn from Open Source! So my current view is of course, biased.

wicketevents-code

Code example of using the events API

I’m very proud of the work I’ve done on Wicket and am very excited to see it make it into trunk. As I said before, the next step is to polish up the patch and remove extra unneeded code (it’s pretty big), so that the core guys can review it properly.

A snapshot of the end of my talk at Componence about Wicket et al

A snapshot of the end of my talk at Componence about Wicket et al

What’s Next

I’m meeting up with my girl friend soon on the 28th of December in Amsterdam, after which we’re off to Paris for new years, then tripping around Europe for January.

During that time, I am sure we will find our selves with some time to relax and so I thought that time might be useful to finish the several draft articles I have waiting in my blog queue (19!). They are all nagging at the back of my mind…

Hopefully this stint will lead onto more exciting work at and maybe even some more presenting and teaching – I am still eager to make anyone who wants to learn, sit through my Scala presentation ;), even if I haven’t used Scala since I wrote the thing!

I still have aspirations of consulting, teaching, traveling, experiencing and working in other parts of the world and of working at Sony Computer Entertainment of America. But not to worry – they are still in the queue.

Until next time – peace out.

The crazy Kiwi.

Update

Good news – as of my latest patch submition, “Issues around events in response to events” has been fixed!

The example applicayion now includes two links – one that triggers an event, and one that triggers an event which will in turn trigger another event within the same request cycle.

Create a free website or blog at WordPress.com.