Plug-in Architectures Jeffrey Stylos User Interface Software, Fall 2004 Introduction Component architectures What are components good for? Being able to reuse standard components within your own applications Allowing applications to be architected and implemented more modularly Allowing applications to be extended (by plugins) after they are compiled and released What is a plug-in? For my purposes, a plug-in is a piece of software that extends or changes the behavior or interface of an existing, compiled application What are plug-ins good for? Extending an application’s functionality Changing the UI of an application (skins or themes) Extracting data from an application To connect it to another app For logging What are the issues with plug-in architectures? What sort of plug-ins can you create? What aspects of the original program can you override? How difficult does this make it to create the base application? How are the plug-ins created and installed? Are they compiled? How do plug-in authors debug their plug-ins? How you create an architecture that balance these different issues is an interesting research question My goals for this lecture Give an overview of several different examples of plug-in architectures and their capabilities and limitations Give you an idea of what resources and tools to use if you want to create one of these plug-ins Not to die from coughing Why you should care about plug-in architectures Writing plug-ins is a way to connect your research with real applications, making it more compelling Writing plug-ins is a relatively easy way to write software that can make your life easier Building a plug-in architecture into your project is a way to let other people improve your project for you Designing new plug-in architectures is a potentially fruitful research avenue DISCLAIMER This wasn’t one of the existing topics I picked it because I wanted to learn more, not because I was already an expert These slides suck I have a cough Overview Intro Emacs Mozilla Eclipse Skinnable apps Emacs Emacs "Editor MACroS“ One of the first runtime extensible systems Designed for text editing Used for everything Contains a core written in C The rest is written in elisp Emacs extensions Extensions are written in elisp Can provide new functions or replace existing functionality Most extensions are macros that provide some sort of automation when explicitly invoked Can also do things like change text formatting Can display images, but only in the context of lines of text Auto spell-checking (flyspell) It’s hard to: Write multi-threaded extensions (makes network programming difficult) Do arbitrary painting (assumes lines of text) Emacs extensions (continued) Everything loaded from initialization file To install an extension Set the correct paths in the initialization file Load the extension from the initialization file Can also manually load any lisp file, or even execute code as you write it How do you debug extensions? Because much of Emacs is in Lisp, can step through it Has a built-in debugging mode Extensions for more detailed debugging (Edebug) and profiling (ELP) Don't have to build Emacs to run or debug an extension Emacs examples [Show Tetris example] Mozilla Mozilla Several different applications Current code base provides Mozilla 1.8 Netscape 7.2 Firefox 1.0 Thunderbird 1.0 Different from old Netscape (which also provided some extensibility) Current extensibility features allow modification of the browser interface components (not just interactive webpage elements) Mozilla extensibility architectures XPCOM Heavier weight – supports C++ and other programming languages XUL / JavaScript User interface modification and scripting Also used for “themes” [XPConnect] Bridges XPCOM and Javascript [XPInstall] Installation and package management XPCOM Cross-Platform COM A cross platform clone of COM Multi-threaded, but no remote support (not DCOM) Used to create heavy-weight components that can be called by XUL and JavaScript elements Code can be cross platform, but has to be recompiled XPCOM (continued) Used to implement much of Mozilla’s core functionality XPCOM (continued) Uses the IDL (Interface Definition Language) to specify capabilities IDL compiles to C++ Connects to JavaScript As with COM, XPCOM programming uses lots of interface pointers §Bad: void ProcessSample(nsSampleImpl* aSample) { aSample->Poke(“hello”); } §Good: void ProcessSample(nsISample* aSample) { aSample->Poke(“Hello”); } Using XPCOM (Usually) needs Mozilla framework to compile Can be difficult to compile Needs the Mozilla framework to debug component Requires special tool to generate IDL specification Can use XPCOM for programming other than Mozilla plug-ins, but few do Debugging XPCOM components Effective when you debug all of Mozilla Tools for detecting memory leaks BloatView, Boehm GC Leak Detector, Refcount Tracing, Trace-Malloc, etc. High level overview of XPCOM Mozilla plug-ins Make a DLL that implements necessary methods (NSGetModule, etc.) Create a IDL specification Create an XPT specification from the IDL Put everything in Mozilla’s components directory XPCOM Examples Using XPCOM: var sound = Components.classes["@mozilla.org/sound;1"].createInstance(); if (sound) sound.QueryInterface(Components.interfaces.nsISound); IDL: [scriptable, uuid(1BDC2EE0-E92A-11d4-BCC0-0060089296CB)] interface mozIGPS : nsISupports { boolean Open(in string strDevice); boolean Close(); string Reason(in boolean bClear); readonly attribute double latitude; readonly attribute double longitude; readonly attribute double elevation; readonly attribute double gpstime; }; XPCOM resources High level information http://www.mozilla.org/projects/xpcom/ An Introduction to XPCOM http://www-128.ibm.com/developerworks/webservices/library/coxpcom.html I don’t know of any good tutorial for creating and compiling an XPCOM extension Mozilla Plug-ins: XUL and JavaScript Used to build the base Mozilla user interface What most of the available extensions are written in Uses XUL to specify the static layout of the UI elements Uses JavaScript to specify how each of the elements interacts XUL “zool” XML User-interface Language Initial ambitions of also being a language for richer webpages (sort of works now) Cross platform Can be used to create stand alone applications (with difficulty) XUL (continued) Uses “overlays” to add new interface elements to existing interfaces Easy to add a new button to an existing form Can also replace existing interface elements Uses CSS to specify many of the formatting elements of the UI How to write a XUL-based plug-in Write a .xul and .js file in Notepad Put in Mozilla’s extension directory Debugging XUL and JavaScript plug-ins Difficult – most common solution is trial and error Prints out red error messages on the UI There exists a debugging tool Venkman JavaScript debugger …but it hasn’t worked with Firefox or Thunderbird for a year or so Update: There’s a development branch that might work with some version of Firefox Example XUL code <?xml version="1.0"?> <!DOCTYPE window> <?xul-overlay href="file://src/HTML/moztests/sampleoverlay.xul"?> <window orient="vertical" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <box orient="vertical"> <box orient="horizontal" flex="1"> <text value="Sample text number ONE"/> <spring flex="1"/> <text value="Sample text number TWO"/> </box> <box orient="vertical"> <text value="Sample text number THREE"/> <text value="Sample text number FOUR"/> </box> <box id="extraStuff"/> </box> </window> Example JavaScript / XUL code function toggleContactsPicker() { var sidebarBox = top.document.getElementById("sidebar-box"); var sidebarSplitter = top.document.getElementById("contacts-panesplitter"); var sidebarState = sidebarSplitter.getAttribute("state"); var menuItem = top.document.getElementById("menu_showContacts"); var toolbarButton = top.document.getElementById("button-contacts"); if (sidebarBox.hidden) { sidebarBox.hidden = false; sidebarSplitter.hidden = false; if (menuItem) menuItem.setAttribute("checked","true"); if (toolbarButton) toolbarButton.setAttribute("checked","true"); ... Example XUL extensions [Show Firefox and Thunderbird extensions] [Thunderbird extensions: Contact sidebar Quote colors] Themes Uses the swap-ability of XUL elements to create plug-ins that change the appearance but not the functionality [Show theme examples] XUL and JavaScript resources Lots, high-level overviews, reference sites, and examples Because they are non-compiled languages, you can view the source of every current available extension XUL / JavaScript overview Powerful and flexible UI scripting Can override existing elements Can dynamically transform UI elements Provides support for separating formatting decisions into CSS files Provides support for internationalization by separating text strings into language files Don’t have to compile Hard to debug Can’t write arbitrary C code Potentially slow Break Eclipse Eclipse A modern Emacs Designed to have a very small core that loads independent components Written in Java, primary selling point is its included Java developing components “The Eclipse Platform is an IDE for anything, and for nothing in particular.” Cross platform Eclipse (continued) Designed for building IDEs People used it for other apps Remail, Haystack (new version) Now formalized: “Rich Client Protocol” Eclipse architecture Eclipse plug-ins All written in Java Found at Eclipse launch Heavier-weight than Emacs model – can’t dynamically swap plug-ins or write and execute code Include a “manifest” file Specifies visibility of included classes and methods Used to add information to the plug-in registry Manifest file example <?xml version="1.0" encoding="UTF-8"?> <plugin name="JUnit Testing Framework" id="org.junit" version="3.7" provider-name="Eclipse.org"> <runtime> <library name="junit.jar"> <export name="*"/> </library> </runtime> </plugin> Eclipse plug-in architecture Load-on-demand strategy makes it feasible to have many different plug-ins and still have reasonable performance “Extension points” make it easy for plug-ins to themselves be extendable Allows for multi-level extensibility (Most architectures only support a single level of extensibility) Uses “explicit ports” to make plug-in connections clear Plug-ins say what they can extend Helps support multi-layered extensibility Manifests help encapsulate plug-ins from each other (they can only use each other in specified ways) Again, helps multi-layered extensibility Eclipse plug-in architecture (cont.) Limitations: Extensibility points are tied to specific implementations Can’t have multiple swappable implementations of the same functionality Can’t have strict dependencies All components are optional Can’t say “this plug-in only works when this other plug-in is available” Reference: Evaluating the Eclipse Platform as a Composition Environment SWT and JFace Standard Widget Toolkit Really just a widget set JFace is the higher-level toolkit built on top of SWT Allows for portable plug-ins that use native widgets Usable outside of Eclipse Opinionated claim: Best Java widget set Supports widget extensibility by allowing Java extensions of native widgets Different types of Eclipse plug-ins Whole apps C++ IDE (CDE) Visual UI Editor (SWT/Swing Designer) Aspect oriented language extension (AspectJ) Profiler (EclipseProfiler) Sample Eclipse plug-in [Show HelloWorld Eclipse plug-in] How do you debug your Eclipse plug-in? Eclipse comes with tools to help build, run and debug Eclipse plug-ins Plug-in wizard Runs separate instances of Eclipse for developing and testing Provides support for the packaging of plug-ins EclipseProfiler plug-in Eclipse resources Many high level articles Most on eclipse.org Relatively active mailing list Archived on eclipse.org, (poorly) searchable For many things, only reference is the Eclipse source code Skinnable Apps Skinnable Apps Is this research related? Some history Remember Winamp 1? (That’s an mp3 player, by the way) Not intentionally skinnable Someone figured out how to modify the bitmap resources in the compiled Winamp executable Became wildly popular, then supported Winamp 2 skins Winamp 3 More than just changing bitmaps Let skin authors specify size and location of buttons, and simple scripting (MAKI scripts) Used an XML-based language to define the location of UI elements, similar to resource editors Winamp 3 skins [Show Winamp] Sonique (Another mp3 player) Flash-like graphic capabilities in a skin [Show Sonique] Skinnable Apps wrap up Natural evolution of a separation between UI and underlying functionality A form of end-user programming Many limitations as a plug-in architecture Difficult to trap events Limiting even just considering UI capabilities Conclusions Different plug-in architectures support different type of extensibility Plug-in programming is very different from regular GUI programming Never get a cough before you have to give a presentation Thanks! Good luck on homework 5!