Monday, November 30, 2009

Step Up or Shut Up

So we're at it again, sigh...

It seems that the same people are commiserating the tragedy of the commons at Eclipse, at regular intervals, over and over again. Complaining is not a very good way to get what you want - I know one thing or the other about this as a father of three ;-). Complaining may work once or twice, but if you keep repeating the behaviour, people will stop listening to you.



Normally, I would just sit these things out but this time I feel compelled to add some oil to the fire:
  • Diversity on e4: It is very easy to become a committer on e4 - that's one of the purposes of an incubator. Basically, all it takes is a believable email to e4-dev@eclipse.org that you would like to work on something in the context of e4, and you will be nominated as a committer. Still, IBM has most of the commits in the e4 project. Who do you think is to blame for that? IBM? Because it is investing in a project whose goal it is to bring innovation back into the Eclipse Platform?
  • Diversity on the Eclipse Platform: The last example I know of where people or companies wanted to contribute to the Platform but were not received with open arms is from about two years ago, when developers from WindRiver complained that their contributions did not make it into the Debug and Resources components. Where are we today? Both these components have committers from WindRiver, and Martin Oberhuber, a WindRiver employee, is a member of the Eclipse PMC. By the way, are those new committers contributing to those Eclipse Platform components full-time? No. (Just to be clear - I don't want to pick on WindRiver at all: I think it's great that they are in fact investing in the Eclipse Platform, even if it's just a little, when many other companies that benefit from the Platform don't invest anything at all.)
    So, if you'd like to contribute to the Eclipse Platform on an ongoing basis, and feel that you are not "let in", please speak up so that we can fix the problem. I am pretty sure that this problem doesn't exist, and that instead the problem is more on the side of those who decide not to contribute, than it is on the side of the existing committers.
  • Forking: As of lately, this is easier than ever. Eclipse projects are now mirrored as Git repositories, starting with those that are using CVS for the main development. Knock yourself out, and don't forget to make the source available if you are creating derivative works. However, I don't think this is going to be a solution to the "tragedy of the commons" problem. I do hope this will make it easier to create private branches when your development timeline does not align with the one at eclipse.org, and you need to just fix something now. I also hope it will make it easier for contributors in general to provide patches that don't go stale.
    By the way, the mirroring as Git repositories happened thanks to Denis and the webmasters at Eclipse, thanks to Shawn Pearce and the EGit and JGit team, and to a small amount thanks to Mike Milinkovich, the Eclipse Board of Directors, and your committer representatives on the board. If you are interested in details, see the bug Chris Aniszczyk opened on June 17th just after Doug Gaff and I were able to convince Mike Milinkovich and the Board (minutes) that it was important to make this happen.
  • The Foundation is doing concrete work to help: Mike has mentioned some of the things that are planned for 2010 on his blog: "a branded Eclipse forge hosted elsewhere (e.g. IP Policy free), Git support for the whole community and major improvements in hosted build and test at eclipse.org." I believe that the Eclipse Foundation staff, and Mike Milinkovich as the executive director, are doing a pretty good job, and they are also actively trying to get more involvement by other companies and individuals for core projects at Eclipse. The board of directors even made this a strategic goal for the Eclipse Foundation this past June1.
So overall, my comment would be "step up, or shut up". If you care about the future of Eclipse, pick a component or feature in one of the core projects that is critical for your use of Eclipse and help what you can. I would put at least the following in the "core projects bucket": Equinox, Eclipse Platform (with SWT, JFace, Workbench, Resources, Debug, Text, etc.), EMF, and GEF. If you think another project belongs in there, pick it instead and help there.

Now for the definition of "help", I would recommend that you focus on a narrow enough subpart so that you can follow along for the next little while (like, for example, a year). Spend some time on the newsgroup/forum, read and understand the code, watch incoming bugs, find out who is the current maintainer, contact them and let them know you are interested in helping, and so on. This does not have to take a lot of time, but there is probably a lower limit of perhaps one or two hours per week. Convince your manager that doing this is important for the company, since they have software products that rely on the component or feature in question. You can also argue that investing a little time will help improve your skills. In fact, the latter point is a motivation that works even if you don't have an employer, if for example you are a student, or self-employed, or just not employed at the moment.

What's in it for you? Potentially fame, when your name starts appearing in Eclipse source file headers, or in IP logs (which by the way are another good way to measure project diversity). You'll learn about "the eclipse way", the development process that allows us to ship on time and with quality, every year, for the last nine years. Finally, you'll have the warm fuzzy feeling that comes with ensuring the future of a core piece of technology that is being used by millions of users. Of course, you could help an Apache project, or Linux, or Mozilla, or on SourceForge or GitHub, but chances are (if you are reading this on Planet Eclipse) that your job indirectly depends on the future of Eclipse - not Apache, Linux, or Mozilla.


(Image © Zen Sutherland, http://www.flickr.com/photos/zen/241745451/sizes/o/, licensed under Creative Commons by-nc-sa 2.0)


1 You have to read between the lines for this, not sure if newer board minutes have more detail. The June board minutes state: "In discussing the strategic goals of the Eclipse Foundation, the Board indicated that diversity on e4 was of strategic importance to the Eclipse Foundation. In addition, it was important to continue to grow a diversified revenue model. As a result of the discussion, these two concepts were introduced into the Strategic Goals of the Foundation." Since a strategic goal that focuses solely on e4 seems a little odd, this has been generalized to apply not only to e4 but to other platform-y projects at Eclipse, I believe the wording is "Ensure adequate resources are invested in the core technology platform".

Tuesday, November 24, 2009

OpenSocial (iGoogle) gadgets in Eclipse

Some of you may have seen this already, in the e4 M2 new & noteworthy document: We are bringing Eclipse and the Web closer together. This work, a collaboration between Benjamin Cabé of Sierra Wireless and myself, is happening in the e4 project, which is the incubator area where we work on new technology, mostly for the Eclipse SDK 4.0 release planned for Summer 2010. (Some of the technologies developed in e4 may make it into the 3.x stream1 as well.)

Concretely, we are opening Eclipse for a whole new world of UI components called OpenSocial gadgets. You have probably seen gadgets in action already, on iGoogle homepages. You can find gadgets that, for example:
  • display your Remember the Milk to-do list,
  • show your Twitter feed (with updates every x minutes),
  • provide your GMail inbox,
  • show a calendar, or, most importantly:
  • display the "cat photo of the day". :-)
Normally, gadgets would be hosted inside iframes on a web page. A web page that hosts gadgets, usually with the help of some server-side infrastructure, is called an OpenSocial gadget container. Many social websites are OpenSocial gadget containers - in fact, it looks like every social website except for Facebook is an OpenSocial gadget container - for example iGoogle, hi5, LinkedIn, MySpace, orkut, Friendster, Ning, XING and many others. Check out the OpenSocial web site and scroll down for the full list. Most (if not all) of these sites use the Apache Shindig reference implementation.

In Eclipse, OpenSocial gadgets are hosted as views. This is what it looks like:



More information, including how you can contribute, is available on this wiki page. You can also download e4 M2 and play with it, or install the feature into a 3.5 or 3.6 build as described on the wiki page.

I think this is really exciting, and potentially an important part of the future of Eclipse. Here is why:

1. It makes it easy to add a new view (or editor) to Eclipse. Just write HTML, CSS, and JavaScript, and you don't even have to know that the gadget is going to be hosted in an Eclipse application. All the usual web arguments apply - zero install, all you need is a URL, proper sandboxing, etc.

2. It brings Eclipse and the "Open Web" closer together. Web UIs are becoming increasingly important, and who knows, we may at some point want to run a full-blown IDE in a browser. But until then, we need a way to take advantage of the web without losing everything that we already have - supporting the existing Eclipse plug-ins is important for the forseeable future. By bringing the web to Eclipse instead of bringing Eclipse to the web, we can get the best of both worlds, if we can ensure that gadgets can become first class citizens in a desktop Eclipse application. (See 4. for what I mean by "first class Eclipse citizen".)

3. It can make Eclipse more social. At this point, our implementation does not support the "social" part of OpenSocial gadgets, but if we added that support, it could serve as another integration point for plug-ins, similar to how the common resource model (projects/folders/files) is an important "common currency" for IDE plug-ins.

4. The OpenSocial specification could benefit, too. We have ten years of experience with Eclipse as a platform or, as I like to call it, as a client-configured mashup platform. Users can start with a minimal platform, add a whole bunch of plug-ins and get an application where individual pieces work together seamlessly. (OK, I admit, it's not seamless in some cases, things don't always work together well, and if you add an insane number of plug-ins, Eclipse is slow and bloated, but I hope you get the idea.) I honestly don't know which other platform has come as far as Eclipse has in terms of integration of heterogeneous components. If you look at examples of the kind of integration and seamlessness I list below, only the first two are currently addressed by the OpenSocial gadgets specification. Many of the other "integration points" that we offer in Eclipse would make sense for OpenSocial as well, if the goal is to support more than a bunch of independent gadgets that sit next to each other on a web page. Here is a partial list of what we call the Eclipse Application Services a.k.a. "the twenty things":
  • Editing preferences in a consistent way.
  • A common mechanism for localizing strings.
  • Providing and listening to the current window-level selection.
  • Being able to start long-running operations, with progress reporting and the ability to cancel.
  • Indicating unsaved changes and prompting to save on close.
  • Common undo and redo operations.
  • Persisting UI state (e.g. column widths, sorting, etc).
  • Error reporting.
  • Common dialogs for common tasks.
  • Contributing menu and toolbar items to a shared area (global menu or toolbar), or even to other views and editors in form of additional items in local menus or toolbars.
For the full list in draft form, and more details, check out the Eclipse Application Services wiki pages. Ignore the fact that most of these wiki pages describe API in Java - it wouldn't be hard to specify similar or equivalent API in JavaScript as well. We still have to find out how best to interact with the OpenSocial community, and if they would be interested in taking their spec to the next level as hinted at above.

On the Eclipse side, our plans for the coming weeks and months are roughly the following:
  • Complete and solidify our implementation, which currently has high duct tape content.
  • Investigate if we can reuse parts of Apache Shindig to make our job easier.
  • Offer Eclipse Application Services as so-called "features" that gadgets can (optionally) depend on.
  • Write example gadgets that show the kind of integration into Eclipse that we'd like to see.
Do you have an idea for a gadget that you would like to see in Eclipse? Would you like to join the fun and become an e4 committer to work on this with us? Let us know on the e4-dev mailing list if you would like to participate, or send me a direct email. Bugs and enhancement requests can be filed in Bugzilla.

Plain old comments on this blog are welcome too, of course. ;-)




1 - Similar to what Apache did with its httpd project and the 1.3.x and 2.x streams, we are planning two Eclipse SDK streams going forward - regular releases on the 3.x stream (3.6, 3.7, 3.8 ...) with a focus on stability, and a parallel 4.x stream with the innovative stuff.

Sunday, October 25, 2009

Adventures into web UI land

To explore how easy or hard it would be to write a UI component using web technologies, and then integrate it as a first class citizen in Eclipse, I reimplemented the PDE "site.xml" editor for the 0.9 release of e4, using HTML, JavaScript, Dojo, and CSS.

I thought it would be interesting to document the design decisions that I made for this. Since my experience with web UIs is somewhat limited, you should take the following with a grain of salt. I did, however, work on something that could be characterized as an "IDE in a browser" for over three years (2001-2004), so I don't consider myself a complete rookie. :-)

Note that I won't talk about integrating the web UI component into Eclipse, this posting is just about the actual web UI component itself. The Eclipse integration is a related, but different story, that deserves its own post.

Let's start with a screenshot of the original PDE editor. It has two panes, a tree on the left showing features and categories, and a bunch of fields on the right with which you can edit the currently selected object in the tree. Depending on the type of object, the right side shows different fields, for example feature environments if the selected object is a feature, or category ID, name, and description if the selected object is a category. To add new categories or features, there are some push buttons on the right side of the tree.



We should be able to achieve a very similar look and feel with a piece of web UI, after all, the "flat look" of the PDE editors was an attempt to mimic the look of a web page.

The first important decision I had to make was whether to generate the HTML, pre-filled with the data, on the server side. This has the advantage that the resulting HTML can be made to (somewhat) work even if the web browser displaying it has JavaScript disabled. You would probably use a server-side template engine for this. If you follow the link, you can see one of the disadvantages of this approach - there are a bajillion template engines to choose from. Good luck with deciding which one! ;-)

But seriously, I had other reasons for deciding to let client-side JavaScript fill in the data instead. For example, this approach scales better because the "filling in data" work is done on the client, with the server doing less work because it only serves raw data. Also, it makes it easier to handle dynamic changes to the data on the client side because there is only one way of turning data into populated widgets. Development and testing is easier because you avoid a complete layer of the cake - you don't need to restart the template engine or reload the template every time you make a change, instead you change the .html or .js file and reload the page in the browser. Finally, this approach quite naturally leads to an interface between client and server that could be used by other kinds of clients as well (you get an API if you decide to publish and maintain it).

Oh and I forgot, it wouldn't be buzzword compliant - to claim you're doing Ajax means that you have to use JavaScript and XMLHttpRequest, and to be RESTful means that the server should serve raw data.

I started with the HTML and CSS first, leaving the client-server communication for later. My first goal was to get the right kind of "look". Many things are easy to do in plain HTML, for example input fields and buttons, and the header area that says "Update Site Map". There were two things that are hard (or maybe impossible) with plain HTML: making the two panes resizable by the user, and displaying a tree of objects. I decided to use Dojo for these two things, because I had a little previous experience with Dojo, and because it had been IP-approved for use by Eclipse projects. Note that I didn't use Dojo widgets for buttons and text fields, mostly because I didn't like their Dojo-styled look and wanted the "plain" look that you get from plain buttons and plain text fields.

For the resizable panes with a draggable splitter between them, I was able to use a Dojo BorderContainer, which is configured like this:
<div dojotype="dijit.layout.BorderContainer" design="sidebar"
livesplitters="false" gutters="false"
style="width: 100%; height: 90%;">
The tree is created dynamically from JavaScript as follows:
myTree = new dijit.Tree({
id: "myTree",
model: model,
showRoot: false,
getLabel: function(item) { /* code to return the label... */ },
getIconClass: function(item, opened){
/* code returning a CSS class for the icon */
},
onClick: function(item,treeNode) { /* ... */ }
});
myTree.startup();
dojo.byId("tree").appendChild(myTree.domNode);
This creates a tree widget based on the model you are passing in, and puts it under the DOM node with the ID "tree". Of course, there is more code than what I am showing here, but I hope that the few snippets I am showing give you enough context to understand the rest.

I initially ignored the server part completely and just hard-code some example data right in the JavaScript. This allowed me to rapidly test and develop the web UI in a browser. Actually, make that "in all the browsers I cared about". During development, I kept Firefox, IE, and Safari open to make sure it worked in all of them. Some of the things you'd like to do in CSS, in particular with respect to layout, don't work quite the same in all the browsers. :-)

Here is the result, opened in a standalone web browser:



My next decision was about the client-server communication. I decided to use JSON as the data transfer format, because, as you all probably know already, "JSON has become the X in Ajax" (quote: Douglas Crockford). There was a more pragmatic reason, too: the version of Dojo that I used was a bit older and didn't support trees backed by XML data. With a little help from Dojo, you can make HTTP requests without having to worry about browser differences.

There is only one thing that is not obvious: if the web UI is in a file like "site-editor.html" that references the necessary CSS and JavaScript pieces, then how does it know its "input", i.e. which resource to operate on? Somehow, the web UI needs to get to know the full path to the site.xml file. One widely used approach for solving this problem is to (mis-)use the "anchor" part of the URL that the browser points at. So for example, if the browser's URL is http://localhost:9234/pde-webui/site-editor.html#/myproject/site.xml then it will request /pde-webui/site-editor.html from localhost:9234, followed by an attempt to find the anchor named /myproject/site.xml in the HTML. Even though it won't find this anchor, the document.location object will contain the full information. This means that our JavaScript code can just get the value of document.location.hash and then make a corresponding XMLHttpRequest to get data from the server, which it then uses to fill the widgets. Once you know about this technique (which by the way has some nice properties with respect to the back button and the browser history), you will start to notice its use in many existing and widely used web-based applications. Like for example, https://mail.google.com/mail/#inbox, or http://www.facebook.com/home.php#/bokowski?ref=profile :-)

By now, if you are still following, we have a client-side web UI consisting of some HTML, CSS and JavaScript, that will access a server over HTTP to get the data that needs to be displayed. Let's now focus on the server part.

Obviously, we need a place to serve our static .html, .css, and .js files. The canonical choice for this is to configure Jetty accordingly. I am instantiating my own instance of Jetty and instruct it to pick a port number for me. If I know that the web UI will only be accessed from the local machine, Jetty can be configured to only accept connections from localhost.

For the RESTful interface, I implemented a servlet that
  1. responds to a GET request with the data I need in JSON format, and that
  2. accepts PUT requests when the user wants to save changed data.
In reality, the servlet does a little more (like e.g. authentication), but this post is already pretty long and I need to gloss over some of the details to not bore everyone to death.

Let me just add one more thing - how did I implement the part of the servlet that converts the site.xml file into the JSON format I needed?

The most obvious approach would be to parse the XML as a DOM and then generate JSON based on that DOM. Instead, I decided to use EMF objects as an intermediate "format". My idea was that by using EMF, the example code could easily be adapted to any data model that's already EMF based, and XML files (assuming they have an XML schema) could then be considered a special case.

If you have an XML schema, you can let EMF create an .ecore file for you (using the New EMF Project wizard). For my use case, I chose to not generate any Java code from the .ecore file, because the code that generates JSON works on any EMF model, using generic EMF calls. This means that it should be very easy to change the schema, or even to use the same code for completely different models.

Just to be clear, if you know that the format of your XML never changes, or if you want to minimize the external dependencies of your code, or if you enjoy programming against the DOM API ;-), or if adding EMF as another "layer" disturbs you, it's perfectly fine to not use EMF. Maybe it would even make sense to use XML on the client side as well.

Overall, I was pretty happy with the structure that I came up with and think that it can serve as an example of how to approach the task of writing a web UI component. And now I'm looking forward to your comments, especially ones that explain how I could have made better decisions!