Thursday, December 24, 2009

Example: Building a Plugin

I've been reading Practical Eclipse Rich Client Platform Projects by Vladimir Silva. I've read the first two chapters and skimmed the rest (there are 10 chapters). The first chapter is called “Foundations of Eclipse RCP,” but it doesn't discuss RCP. There is an introduction to creating a plugin with eclipse, which is certainly something you need to understand before building an RCP application.

The book has a copyright of 2009 (this year barely) but uses Eclipse 3.4. I'm using 3.6M6, and eclipse has changed a bunch, specifically in the way one installs/uninstalls plugins. With 3.5 we started to use the p2 updated sites. Copying a bunch of plugins into your plugins directory is no longer the way.

It's disappointing that a book with a 2009 date is so out of date. I do want to stick with Eclipse 3.6 and figure out how to do these installations and navigate the new UI because 3.6 is where it's at.

Each chapter ends with a hands-on exercise preceded by a discussion of the tools needed for the exercise. Sometimes the tools discussion reads like a group of unrelated facts with code snippet examples. The examples often seem out of context ... yes, there's this xml or this java code, but how does it fit into a working application. The hands-on exercise is supposed to provide that context, but in my opinion seldom succeeds.

Now what I said may sound that I am disappointed in the book, but I'm not. As I've said, I've only read the first two chapters and skimmed the rest. I will read the rest. I want to know how to make a standalone RCP application, but my skimming seems to show how only to run that RCP application from within eclipse. Maybe not, we'll see.

I'm using a Mac Book Pro with Snow Leopard.

The Hands-On from Chapter 1

I struggled with this, but I think my issues were mostly due to me and not the book. I downloaded the source code. Just looking at it was not enough for me. I had to import the project into my workspace. Once I did that, I could build my own identical project.

I'm thankful that this first project is not trivial. It actually does show stuff that I think will turn out to be useful later in the book. Here's a quote that describes what the first exercise is.

... you will write a plug-in to embed a tiny Jetty web server that uses Equinox to define a simple servlet class that returns the headers of the HTTP request.

Sticking Points

Here are some sticking points I had. I'm not faulting the book on these points. When you read the book carefully, these problems are answered. 

  • The project doesn't come with a run configuration. Does it, and I don't know how to see it? I made my own.

When I tried to run this example, I got a permission denied error. I think this is because Jetty wants to start on port 80, but where that is specified I don't know. The way to fix this (and the book has a note on this, but says the note is specific to Linux and does not mention the Mac) is to add the following VM argument to the run configuration: -Dorg.eclipse.equinox.http.jetty.http.port=8080

I did not want to run as root (a bad thing). On the Mac, I don't know how to have eclipse run as root when I run by clicking my icon. I have to become root in a command line and start up eclipse from the command line.

  • I kept running the example as I changed things and got a “port already in use” error. I needed to click on that red Terminate button in the console window before trying again. Yes, this is something I should have known.

  • I didn't understand why I didn't see an osgi prompt in my console window (the prompt is osgi in lowercase). The way to fix not seeing the prompt is to add the Program argument -Console to the run configuration. This is actually mentioned in the book, but it says that Console starts the OSGi console. I was foolish enough to think that the Program argument -consolelog or the default VM argument -Dosgi.noShutdown=true did this. The book says that this VM argument is useful for examining the OSGi framework ... don't you need the osgi prompt for that?

  • I didn't see the output. Wow, guess what ... you have to start up an external browser and point it to http://localhost:8080/servlet. That servlet is the alias which appears under Extension Element Details, and it isn't the default.

  • I wasn't including enough bundles in the run configuration's target platform. I unselected all the bundles under Target platform and then selected only those I had included in the Required Dependencies under the Dependencies tab in the Manifest editor. The correct way to do this is to deselect everything under Target platform, ensure that only the correct workspace is selected and then click the Add Required Bundles button.

    It is beneficial to select the Only show selected bundles checkbox. There are (in my configuration) 375 possible bundles. They don't fit on the screen, and you have to scroll to see what is selected. This method shows that 23 bundles are selected, a lot more than those four that I put into the manifest.

How the Application Looks When It Runs

Here's how the application looks when run. I did an ss at the osgi prompt to display its registered bundles. At this prompt you can start and stop bundles. To stop ch01a_1.0.0, issue stop 27. To start it, issue start 27.

Here's the output from http://localhost:8080/servlet1. Yes, I changed my alias from servlet.




Here's how it looks from within eclipse.




 

How to Configure the Project 

  1. File -> New Project and choose Plug-in Project. I called it ch01a (my imported project from the source download was ch01). Even in Eclipse 3.6M4, you select the Eclipse version 3.5; 3.6 is not in the dropdown because 3.6M4 is still a milestone release.
  2. Click Next. I removed the .qualifier from thePlug-in version, just because it wasn't in the book's figure.
  3. Ensure that “This plug-in will make contributions to the UI” is unchecked.
  4. Click Next. The Manifest editor opens up.
  5. Click on the Dependencies tab and add the plugins: javax.servlet, org.eclipse.equinox.http.jetty, org.eclipse.equinox.http.registry, org.eclipse.equinox.http.registry, and org.eclipse.equinox.http.servlet. Note that the selection window that comes up is blank, but bundles appear when you type in the “Select a Plug-in” box.
  6. Click on the Extensions tab. Add the extension point org.eclipse.equinox.http.registry.servlets. A class name and alias appears on the right under Extension Element Details. Change the alias.
  7. Click on class. In the window that appears, type in javax.servlet.http.HttpServlet for the superclass.
 

The Source Code

I'm not going to show the code. It's not my code. It's available in the source code download from http://www.apress.com. Although the book recommends Apache Log4j, the example uses the Commons Logging service that comes with eclipse.

Good stuff to learn by reading it. There are two java files: Activator.java and Servlet1.java (the book has Servlet.java).

Other References

I found the link http://www.eclipse.org/equinox-portal/tutorials/server-side/ which is helpful. It has a similar but simpler example.

 | Eclipse