Development, Java @ 31 January 2007, “No Comments”

As part of our, seemingly unending, refactoring of Robonobo, we packaged the whole app into an applet. However, writing a UI in swing felt very un-webby, and would fail to integreate, visually, with the style of the site. We would also like our users to have the ability to be able to customize or rebuild their own UIs using simple standards. Luckily, however, applets have some very cool features that I only just learnt about, inlcuding LiveConnect (from whence XPConnect comes from). This provides a bridge between java and javascript, allowing me to call java functions from javascript and return real java objects to javascript.

Using this, we created an applet with no UI, that sits in a 0×0 pixel container, and a javascript support library which communicates and wraps the functionality provided by robonobo. All the UI can now be rendered using html, css and javascript, in a very ajaxian fashion.

There are a couple of gotchas though:

  • You cannot return primitive types such as int, float, etc. Instead you must use the object equivilents Integer, Float, etc.
  • Calling from javascript comes from an unprivileged thread, so despite your applet’s policy, it may well be denied permissions. You can simply wrap such requests on the java-side with an AccessController.doPrivileged()
  • Large applets can lock up the browser because the JVM and the jar are being loaded concurrently. This can be aleviated by splitting your applet into a smaller jar containing just the applet and interfaces, and the main jar containing the implementation. This way, the jvm and applet initialize quickly, and then do not block the browser when the second jar is downloaded.
Development @ 05 January 2007, “1 Comment”

I work for a couple of companies whose employees are distributed across timezones and countries and someone needs to write a bit of software to make this easier. Something like BoxCloud combined with Subversion. The idea being that all shared files exist on each individual machine and are synchronized when people come online. All previous versions of the documents are stored as well. A new file can be shared with everyone just by placing into a special folder on ones computer, which is monitored by the client.

Then, you need a Push-to-talk voip system. Often you dont need to have a full conversation with someone, but instead let them know what your doing, or that you have just updated a document, etc. A special key on the keyboard (maybe caps lock? put it to some good use) will enable you to say a few words to a person or to the whole team.

Development @ 27 September 2006, “No Comments”

I like PHP; its fun, quick and easy… most of the time. However, I have recently had the misfortune of attempting to make WordPress, Wikka Wiki and Vanilla work together. Although, individually, they are very powerful and superb examples of open source development, they suck at working with other projects.

Two things immediately struck me: 1) lack of a common templating system and 2) lack of a common authentication /authorisation system

Now, I don’t mean that there should be a single templating system used by all, but there should at least be support for a simple border template system. Such a system could let me define the basic outline, css, scripts, divs, etc and then nominate extention points, i.e. places in the template other systems can hook into and publish their content. HTML with some proprietry xml tags embedded could be transformed using XSLT into the project specific template format. Indeed, drivers could be provided to allow converstion to most popular templating systems.

Templating is a big issue with me, everyone has their own way of doing it. I do not agree with systems like Smarty that try to seperate the user from the structures of php in order to prevent them from embedding control logic in their templates. Of course, a developer shouldn’t be doing this, but this is a self-discipline issue, not a need to develop a non-standard scripting language on top of another, perfectly functional, scripting language.

The templating issue was overcome, if in a rather hacked manner, by reducing the templates of each project to the bare minimum, ie, no css, simple div structures, etc. A proxy-like service would then explode the head and body section and recombine it using a standard template. This could be seem as object-like inheritance of a standard template dom tree (similar to the concept of XUL overlays).

Although templating is an irritating issue, it is not quite as irritating as the authentication issue. Here we have three seperate projects, each with their own authentication system, and although some allow the easy application of your own code, quite why the community cannot make efforts to agree on a common authentication API, is beyond me.

PHP needs to be distributed with a set of APIs that cover these common problem areas. Additionally, if you want to include code from several projects into one, you NEED some form of namespacing standard. I would love to see some sort of PHP community standards effort that would lay down the law for such things. Projects built to these specifications would automagically behave well together and allow coders to get on with writing Cool Shit rather than hacking a project’s ludircrously over-complex templating system.

Following on from yesterday, I needed to pass arguments to the window being opened. The data I needed to pass was quite simple, so I simply serialized it to JSON and then passed them as strings in a nsICollection (actually, a @mozilla.org/supports-array;1 collection of @mozilla.org/supports-string;1) and then just eval()’d the data within the xul window’s javascript.

This is a bit of a hack, but its probably the simplest way of passing structured data. What would be nice is a bit of code that would automagically serialize a bean to JSON notation… I’m sure there are many out there (This apache struts class looks promising)

Finally worked this out…

These pages are rather helpful: Mozilla’s guide to using proxies and XulPlanet’s description of the nsIProxyObjectManager

This interface defines a proxy manager. An instance of this manager is used to create a proxy for a particular object on which you wish to invoke a method. If you are calling from any other thread that which you initialized xpcom on, you will need to do this, and as far as I am aware, there is no trivial way of doing otherwise.

Anyway, the code to open a new window would be as follows. Note, this method assumes that there is already a constructed object called windowWatcher, which is an instanceof nsIWindowWatcher, see previous post for details.

 public void openWindow(String chromeUri, String name) {
nsIEventQueueService eventQueueServive =
(nsIEventQueueService)serviceManager.getServiceByContractID(
"@mozilla.org/event-queue-service;1",
nsIEventQueueService.NS_IEVENTQUEUESERVICE_IID);

nsIEventQueue eventQueue = eventQueueServive.getSpecialEventQueue(
nsIEventQueueService.UI_THREAD_EVENT_QUEUE);

nsIProxyObjectManager proxy =
(nsIProxyObjectManager)componentManager.createInstanceByContractID(
"@mozilla.org/xpcomproxy;1",
null,
nsIProxyObjectManager.NS_IPROXYOBJECTMANAGER_IID);

nsIWindowWatcher windowProxy =
(nsIWindowWatcher)proxy.getProxyForObject(
eventQueue,
windowWatcher.NS_IWINDOWWATCHER_IID,
windowWatcher,
nsIProxyObjectManager.INVOKE_SYNC );

windowProxy.openWindow(null, chromeUri, name, "centerscreen", null);
} 

The code here uses the service manager to get an instance of the event queue manager, which is subsequently used to retreive the main UI event queue. This is then passed to the proxy manager’s getProxyForObject method, along with the IID of the nsIWindowWatcher interface, the actual instance, and flag representing the type of proxy operation (async, sync, etc, see the xulplanet page for more info).

This method returns an instance of nsIWindowWatcher, which is actually a proxy which will inject events onto the UI thread for you. Then, just use the object as normal, sweet!

After poking around for some hours (then days) trying to find some useful information on how to use JavaXPCOM (which is a bridge between XPCOM and Java, formally known as Javaconnect) I stumbled across a few things as well as hacking together some understanding myself and through C++ examples of XPCOM usage.

We decided a while back to adopt an XML based protocol wherever possible, and moreover, RDF where appropriate. When communicating with a central server, this would use HTTP, so it seemed logical to use the same on the localhost. So, XUL uses AJAX, basically, to do asynchronous calls over HTTP to localhost, and retreives XML which is then passed into objects representing the returned resources. This way, we dont need to heavily integrate Java and XUL using XPCOM, and we allow other applications to be able to place nicely with the API over a well-known protocol and format. Anyway, this means that the only work JavaXPCOM needs to do is:

  • Start XPCOM using a XULRunner installation
  • Start an XUL window and pass control over to it
  • Be able to call javascript/xul events from java (to open windows, etc)

So to start with, we need to find an XULRunner install. As it stands, we will distribute a version with the installer, but JavaXPCOM contains code to easily find installed versions as well (this is actually documented on the JavaXPCOM site).

  1. Set the path the XULRunner directory, here we are doing it explicitly: File grePath = new File(new File(".").getAbsolutePath(), "platform/win32/xulrunner");
  2. Next create an instance of the LocationProvider LocationProvider locProvider = new LocationProvider(grePath);
  3. Initialize JavaXPCOM embedding: Mozilla.getInstance().initEmbedding(grePath, grePath, locProvider);
  4. Now we need to start an XUL application, so we get an instance of the XPCOM service manager nsIServiceManager serviceManager = moz.getServiceManager();
  5. Now we need to get the @mozilla.org/toolkit/app-startup;1 service: nsIAppStartup appStartup = (nsIAppStartup)serviceManager.getServiceByContractID("@mozilla.org/toolkit/app-startup;1", nsIAppStartup.NS_IAPPSTARTUP_IID);
  6. Get the nsIWindowWatcher interface to the above nsIWindowCreator windowCreator = (nsIWindowCreator)appStartup.queryInterface(nsIWindowCreator.NS_IWINDOWCREATOR_IID);
  7. Get the window watcher service nsIWindowWatcher windowWatcher = (nsIWindowWatcher)serviceManager.getServiceByContractID("@mozilla.org/embedcomp/window-watcher;1", nsIWindowWatcher.NS_IWINDOWWATCHER_IID);
  8. Set the window creator (from step 6) windowWatcher.setWindowCreator(windowCreator);
  9. Create the root XUL window: nsIDOMWindow win = windowWatcher.openWindow(null, "chrome://your-app/content/window.xul", "mywindow", "chrome,resizable,centerscreen", null);
  10. Set this as the active window windowWatcher.setActiveWindow(win);
  11. Hand over the application to xpcom/xul, this will block: appStartup.run();

Now, the LocationProvider is responsible for providing path(s) and file(s) that XPCOM needs. I have implemented a version that when the ‘ChromeML’ location is asked for returns an array of File’s, the first of which points to my own applications chrome folder, and the second of which is the xulrunner’s own chrome folder. This seems to work, but there are several issues:

  1. I do not seem to be able to open XUL windows (or in anyway interact with xpcom/xul) from another thread. Since this run() method on nsIAppStartup blocks, this is a bit annoying. I presume there is a way to run this loop manually, or hook into it so we can queue up requests from other threads to be invoked on the xpcom thread.

Ok, thats only one major issue for now, but I’m sure I will think of others. If anyone has any ideas how these problems can be solved, or how one may circumvent them, I’m all ears. Also, I know that this area is so bleeding edge it hurts, so it would be nice to talk to some other people doing the same things!

Development, XUL @ 10 February 2006, “No Comments”

Just a quick roundup of some interesting developments I’ve seen recently in the world of persuing elegant cross-platform solutions for media players. Songbird is a media player in the vein of iTunes that uses XUL

http://xullicious.blogspot.com/2005/06/xul-music.html  is an example of how to make a cross platform media player using gstreamer and directx for the application, and XUL for the front end.

Zap! is a XUL based SIP (ie, VoIP) client for mozilla.  Basically a cross-platform streaming audio tool using the PortAudio audio library.

Development, DotNet, XUL @ 20 December 2005, “No Comments”

Our choice of platform for MixIndex was .NET/C# since it was, at the time, going to be tightly integrated and specific to the Windows OS. However, with the pace of development of Mono and PortableDotNet over the last couple of years, most of the app will now run on any platform. Two key components, however, do not.

First, is the streaming audio library, DirectX is used on windows, but since this is quite well abstracted, it could be rewritten on a per-platform basis, not the best solution, but it is doable.

Second, however, is the UI, System.Windows.Forms is an ugly beast, and not supported very well by either of the two open-source dotnet runtimes, so a choice needs to be made.

After looking at WX.NET, a .NET implmentation of WX widgets, and GTK#, GTK+ bindings for .NET, I was begining to get dishartened by the hackish way they were all implemented. GTK# is just ugly on all platforms, rather than looking good on one or two. WX uses the native interface, but there are no decent, free/cheap, tools to help you, the ones that do are so clunky, they make me worried as to how the rest of the system is imlpemented. All in all, very underwhelming.

Anyway, I am now looking at XUL and its damn nice, clean, standards complient, cross platform and open-source. The XUL Runner is a standalone application for running XUL apps, which would be packaged into the apps installer, and then the XUL part can communicate with the ‘real’ application over SOAP, XML RPC, or whatever, enforcing a strict seperation of UI and Application. Stuff like localization is done through entities defined in DTDs, and styling is done through css, very very cool.

This is the tutorial I followed.

Development @ 19 December 2005, “No Comments”

Just a thought, wouldn’t it be nice if you could agregate rss feeds for events, and filter by location. Therefore, when I’m in Seattle in January, I could instantly see whats going down in the area, and when i return to the UK, I would then again see details for events in the London area.

Its quite interesting that the marketing world is begining to pick up on this, I for one would quite like an RSS feed from ticketmaster, say, complete with community tagging, so i could just get a feed of stuff I’m interested, based on my current location. The transition from being an irritating, ever-present, lowest-common-denominator-targeted, to useful, informative, open and transparent will make the early adopting marketing firms very very rich, they just need to become the first point of contact for such things.

No doubt, this will be Google; “Tell us your events on google base, and people can search based on their current location!”… Oh wait, isn’t this already possible?

DRM @ 18 November 2005, “No Comments”

Interesting article on Wired about the Sony We-Hate-Our-Customers fiasco:

http://www.wired.com/news/privacy/0,1848,69601,00.html

This makes me think (read: hope) that the future of DRM is a rather gloomy affair, based around mutual distrust between the consumers and the distributers, with the content creators cast to the sidelines.

Why cant they just embrace the inevitable and use it to their advantage? Surely the first to ‘Get It’ will go on to be very successful? The major expense for the record companies is the packaging, distribution and marketing of the material, not its actual production.  The internet, and perhaps more specifically, p2p removes this expense, in fact people will give up their own time/bandwidth to distribute the material for you.

The problem is about reimbursing the content creators for their hard work, but surely this can operate independently from the distribution? Why not adopt a model similar to TV or radio advertising where viewer/listener figures, and thus the revenue to be generated by the ads, is determined by statistically analyzing focus groups and sample households. This obviously isnt perfect, but another thing that the p2p networks gives us for free is statistics on searches and downloads (until they become darknets that is).

Just ask everyone to pay £50/year, or something, like a tv license, and this gets divided up between the agents representing the artists. Most will pay, but those that don’t are still giving something in their free distribution, archiving and ripping of material.

Ok, so its not perfect, but its better than installing spyware on your customers’ computers :P