Home  >  

Potomac - Bringing OSGi Modularity to Flex

Author photo
| | Comments (14)
AddThis Social Bookmark Button

OSGi is taking over the Java world. The modularity features offered by OSGi have become so popular that it seems like all the major Java enterprise applications and frameworks have adopted OSGi or have plans to. Products and frameworks such as Eclipse (and therefore Flex Builder), Spring, Websphere, Guice, Weblogic, and JBoss all use OSGi. Even organizations such as NASA have adopted OSGi. So what is OSGi and why is it so popular? This article will try to answer those questions and introduce you to Potomac - the new OSGi inspired framework for Flex.

Understanding OSGi

OSGi is a dynamic module system. An OSGi module, termed ‘bundle’, is loaded dynamically as needed. A bundle also includes metadata describing the module including its dependencies. This allows OSGi to load all the necessary supporting bundles dynamically as well. OSGi applications are essentially collections of these bundles and their web of dependencies that are pulled together to provide one cohesive application. The bundles are lazily loaded and therefore OSGi applications are more scalable. This dependency metadata also allows OSGi bundles to be easily reused in multiple applications. Simply ensure that the new application contains the bundle’s dependencies necessary and you’re off and running. This is markedly different than the standard Flex module system.

Flex modules are designed to be used by only one application. They’re intended to be used only within the application project they’re defined in. There are techniques to allow modules to reuse code and have other dependencies but nothing on the level of OSGi. The ease with which bundles are reusable has resulted in a vibrant ecosystem of reusable open source and commercial bundles. This is evidenced by Eclipse. Eclipse is based on OSGi and Flex Builder is itself an Eclipse plug-in (and every Eclipse plug-in is an OSGi bundle). The OSGi underpinnings enable us, the average Flex developers, to have our Flex development tools and combine them with other OSGi plug-ins like the Eclipse Java development tools. Or perhaps you use PHP and the PHP development tools available for Eclipse. These are all OSGi bundles and the reason we can combine them is because the Eclipse platform is an OSGi container.

It’s possible to use the Flex module system to develop similar applications, but it’s not easy. For one, we must avoid using ModuleLoader. ModuleLoader is used when a module only defines one UI component. In these complex applications, modules never define just one UI component. Instead we need to use ModuleManager to load our modules. This seems easy enough until we start to dig into when and where we need to load our modules. If a module contains 10 or 20 UI components, we’ll need to ensure the module is loaded before the user opens any of those 10 to 20 screens. Now multiply that by 10 or more modules that might exist in a medium sized modular application. We can quickly see that our code will be littered with calls to ModuleManager and IModuleInfo#load(). And this doesn’t take into account the complex dependency structure that OSGi enables. We also don’t want to think about all the asynchronous code that will be necessary as each module load is an asynchronous call. These problems make us cry out for a modular framework that takes care of these details for us - something the Eclipse platform has been doing very successfully for OSGi.

Another benefit of OSGi is how it enables large team development. When developing large scale applications it’s very common to split the development across many teams. It becomes an absolute necessity to split development when the number of developers grows from 5 or 10 to 40, 50 or even 100 or more developers. It’s typical to assign these smaller teams one or more modules as their share of the work. But Flex Builder requires that all modules be defined in the main application project. The result is too many developers working in one project and a very fuzzy understanding of whose class files are whose. Developing these enterprise level applications requires that you define clear module boundaries and have your IDE help understand and maintain those boundaries. If only we could separate modules into their own Flex Builder projects, allow them to be referenced by the main application, and even share code with other modules in our workspace.

Enter Potomac

Potomac is the new framework that brings OSGi capabilities to Flex. It brings a new set of modularity features that allow modules to:

  • Be defined in their own specific project.
  • Declare their dependencies on other modules.
  • Be easily reused across different applications.
  • Be loaded automatically without ever needing to call ModuleManager.

Potomac was inspired by OSGi and the Eclipse platform. In addition to its modularity features, it also includes:

  • A custom metadata processor
  • Dependency injection

These features work in concert to create a framework that not only redefines Flex modularity, but also increases the productivity of the average Flex developer. Even if an application doesn’t require enterprise modularity, the team’s developers will benefit from the UI framework, metadata processor, dependency injection, and other time saving features found in Potomac.

Potomac Modularity

In order to provide the features necessary to support OSGi-like modularity, Potomac provides not just Actionscript and Flex code, but also a Flex Builder plug-in. This Flex Builder plug-in adds new capabilities to Flex Builder that, first and foremost, allows a developer to create modules in separate module projects.

A Potomac bundle, using the OSGi term for module, is created within a Flex Library Project. After the Potomac Flex Builder plug-in is installed, a new right-click menu option is available: “Add Potomac Bundle Nature”. When this is chosen, a regular Flex Library Project is morphed into a Potomac bundle project. The following new capabilities are added to the project:

  • A new automatic project builder that automatically compiles a Flex module SWF file in /bin.
  • A new bundle.xml file that contains all the metadata for the module.
  • A new metadata compiler that checks and marks errors in custom metadata declared by Potomac and by other bundles.

The automatic module compiler is one of the pieces that enable modules to be reused. Specifically, the compiler will include all classes selected for the library SWC into the module SWF. This differs from normal module compilation which only includes classes that are used by the module but not included in the main application SWF. This is a useful optimization but prevents a module from being used in applications other than the one it was compiled for. Generally speaking, the static linking that Flex Builder favors (the “Merge into code” link option) is diametrically opposed to a modular architecture. This is great to keep SWF file sizes as small as possible, but it sacrifices reusability.

Bundle XML Editor

The new bundle.xml file in a Potomac bundle contains the bundle’s metadata. Most importantly, it maintains the list of bundle to bundle dependencies. The Potomac Flex Builder plug-in includes a form editor to make modifying the bundle.xml easier.

When bundles are added to the dependency list, Potomac takes care of adding all the necessary entries to the build path. By adding a bundle dependency, a developer can immediately start making references to classes from that bundle.

The other data contained in the bundle.xml is the extension and extension point metadata. The extension and extension point mechanism is a way for bundles to ‘plug in’ to specific features in a very loosely coupled way. For example, if our application is broken down into a set of screens, we might create a screen extension point and a screen extension for each screen in the application. Extension points are a key component of the Eclipse platform and Potomac draws heavily from Eclipse, yet the extension mechanism in Potomac is quite different.

Extensions, Extension Points, and Metadata

In many of the popular Flex frameworks, metadata is starting to play a large role. This is also true in the Java world where they’re called annotations. The ability to annotate a class, method, or field and have that metadata processed by the framework has opened a whole new realm of possibilities. Potomac continues this metadata trend. To plug in to the UI framework, you simply use some new metadata tags. To request dependency injection you use an [Inject] tag. In fact, to do almost anything in Potomac, you use metadata tags. The reason for this is because extensions and extension points in Potomac are defined via metadata tags. Declaring a new extension point via [ExtensionPoint] actually creates a new metadata tag. For example, declaring [ExtensionPoint(id=”Screen”)] Potomac allows developers to provide extensions to this extension point via [Screen] tags.

Metadata Property Checking

This feature is so powerful that it’s become more than just an extension point mechanism as known in Eclipse. Metadata tags can be declared on classes, methods, or variables. The Potomac Flex Builder plug-in will do syntax and property checking on the metadata tags, and not just ones that are part of Potomac but also any custom metadata tags you define. Along with the compile-time checking, developers are also able to use the full reflection API that Potomac provides at runtime. Need to know where a tag was defined on a method or on top of a class? Need to know the function’s signature or the field’s datatype? All these details are available via the Extension class. It’s no longer necessary for developers to call the describeType() method and parse the returned xml.

These features have made the extension mechanism so broadly applicable that it powers features beyond the use-cases normally expected of extension points. Instead of just allowing developers to provide UI contributions, it can be used to provide all types of metadata processing. In fact, Potomac uses extension points to power some of the more generic metadata tags like [Inject] and [Handles].

The list of options and features available to developers declaring their own metadata extension points is too lengthy to describe here. For more details, head over to the Potomac site and read the documentation on extension points: http://www.potomacframework.org/documentation/extensions-and-extension-points.

Dependency Injection

Dependency injection, once such a new and exciting topic, has become somewhat taken for granted. Developers expect their frameworks to provide dependency injection in one form or another and Potomac doesn’t disappoint. As alluded to in the previous section, dependency injection is fulfilled via the [Inject] tag. Injection is provided on constructors, methods, and fields. Importantly, injection and class creation managed by the dependency injector is bundle-aware. In other words, a request to inject or create a class in another bundle will cause that bundle (and any of its dependencies) to be loaded. This is critical to how Potomac works and is an important difference from OSGi. OSGi uses Java’s customizable class loading mechanism to load bundles when a class from that bundle is referenced. Flex, or more appropriately, the underlying Flash player doesn’t support similar class loading customization. And even if it did, loading modules in Flex must be done asynchronously. There’s no way to interrupt a standard “new MyClass()” operation to wait for a module to be loaded. Therefore Potomac uses dependency injection as its ‘hook’ for loading bundles.

This might be starting to sound fairly complicated. But for typical development, these details are hidden from the developer. Developers simply annotate their constructor, method, or variable with [Inject] and it just works.

UI Framework

The UI framework uses extension points and dependency injection to take component contributions from multiple bundles to form the final cohesive application. In order to make this possible, Potomac breaks down applications into 4 main abstractions that are then made available as extension points. Those abstractions are templates, pages, folders, and parts.

Application Manifest Editor

A template defines the applications overall frame, branding, and navigation structure. An applications template is selected in the Application Manifest Editor. Today Potomac ships with one template though more will follow. You can also create your own if you wish. Ultimately we hope to have a community of third party templates similar to the prevalence of custom themes for web platforms like WordPress or Drupal.

A page is a primary subsection of an application. In an email application for example, we might break it down into multiple pages: one for email, one for the calendar, one for tasks, etc. How a user navigates to a page depends on the template. A template might choose to arrange pages in tab navigator or perhaps it might only show one page at a time with a button to move between pages. Some templates might define transition effects from one page to the next, others may be more Spartan.

A folder is a viewport or area within a page. Folders contain one or more parts. A folder can be represented by a set of tabs, an accordion, or practically any Flex container widget. When a page has multiple folders, they are separated by drag-able splitters.

A part is a UI component, typically extending from Canvas. There are no special requirements for what constitutes a part other than providing the one [Part] metadata tag, but parts can have quite complex features. For example, many parts may represent UI forms used to edit a specific object. Those parts may have a save lifecycle which can be managed by Potomac. Below is a sample of a simple part.

 
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" 
height="300">
	
     <mx:Metadata>
          [Page(id="email",title="Mail",icon="mail.gif")]
          [Part(id="inbox",title="Inbox",icon="inbox.png",folder="default")]
     </mx:Metadata>
	
     <mx:Button x="23" y="10" label="Button"/>
     <mx:CheckBox x="23" y="52" label="Checkbox"/>
     <mx:Label x="23" y="97" text="Label"/>
     <mx:DataGrid x="23" y="148">
          <mx:columns>
               <mx:DataGridColumn headerText="Column 1" dataField="col1"/>
               <mx:DataGridColumn headerText="Column 2" dataField="col2"/>
               <mx:DataGridColumn headerText="Column 3" dataField="col3"/>
          </mx:columns>
     </mx:DataGrid>
</mx:Canvas>

Among the key features of the UI framework is how it displays UI features like pages and parts before their bundles are loaded. Potomac uses the information declared in the metadata tag to show the part’s selector. For example, if the part is in a tab folder then the tab button is populated with the icon and title text from the [Part] tag. Only when the tab is selected will Potomac will load the necessary bundles and display the part. In practice this ensures bundles are loaded as lazily as possible. And this happens automatically, a developer building on Potomac doesn’t need to know the details. This same lazy loading approach is taken with all the different UI components including pages, parts, and high level menu actions. Nothing is loaded until absolutely necessary. Instead of a developer having to think and focus on the modularity plumbing in a complex application, he or she can just focus on the actual business problems and let Potomac take care of the rest.

One last significant feature of the UI framework is its customizability. It was already mentioned that you can create your own templates, but you can also create your own folders and page types. Ultimately, every piece of UI shown to the user can be swapped in or out with whatever best suits your application and your look and feel.

Conclusion

This has only been an introduction to Potomac. There are many more features and details that you can read about on the Potomac site: http://www.potomacframework.org. Potomac is still growing and in the weeks and months ahead more features will be added such as preference UI, a security subsystem, and other features for enterprise business applications. Hopefully, when you consider frameworks for your next Flex application, you’ll consider Potomac.

Read more from Chris Gross. Chris Gross's Atom feed chris_gross on Twitter

Comments

14 Comments

Cristian pascu said:

This sounds very exciting and interesting. I wonder where does this framework stands w/r to server side OSGi and also to e4 java to AS3 compiler.

Cheers,
Cristian

Chris Brind said:

You need to be careful about using the word OSGi which is a trademark of the OSGi Alliance. Basically, if your framework doesn't implement the OSGi specification then you shouldn't be using the trademark! And since this is a Flex framework, that's never going to be the case.

http://www.osgi.org/Main/TrademarkPolicy

Chris Gross said:

@Christian Potomac has no relation to serverside OSGi as Potomac is all Flex/Actionscript. There could be some integration work in the future perhaps.

Same for e4, no relation. Potomac is an attempt to bring those same goals to native Flex/Actionscript w/o any Java middleman.

@Chris I've been careful to avoid saying Potomac "is" an OSGi framework or container. Potomac is "like" or "inspired by" OSGi. If someone from the OSGi organization feels like we are infringing then I'm more than happy to change the way I'm describing Potomac.

Mehdi said:

Can it be used in a pure actionscript project -no flex-?
thanks.

Chris Gross said:

@Mehdi - Not currently. The core infrastructure that doesn't depend on Flex controls could, with some changes, be used w/o Flex. I guess if there was enough demand we could look at this.

Rex Sheridan said:

It would be neat to see this integrated with the Spring Actionscript project. Maybe you could standardize on the dependency injection and leverage off each other.

Chris Gross said:

@Rex - Yea there might be some neat integration we could do - but because of the way Potomac uses dependency injection (by determining where a class is coming from and then loading all the required bundles) Potomac will always need to be at the core of the injector.

Brett Coffin said:

Where does Potomac stands in regards to the new features of Flash Builder 4. I know FB4 allow the creation of modules specific to an application or "not" application specific. And can you run Potomac on a FB4 ?

Chris Gross said:

Potomac hasn't been tested against Flex4 or FB4 yet. Its something we're looking into.

AFAIK, FB4 doesn't add any more significant modularity features above FB3. Modules are still defined in application projects. You can choose to have an 'unoptimized' module but that is still leaves lots of class overlapping possibilities and doesn't provide any of the other benefits of Potomac #like the multi-layered dependencies, extension points, etc#.

I haven't read the entire article yet and intend to look into Potomac further, but wanted to point out that separate module projects are not unique to Potomac. We have always created modules in their own project when building modular apps. We simply create a Flex project and then change the root tag from Application to Module. You can prevent the overlapping class definitions by using the link reports features of mxmlc.

I am also curious (and maybe this is answered further down in the article) if its possible to use Potomac outside of Flex Builder. Can it be used from FDT, FlashDevelop, IntelliJ or the command line? If the Flex Builder plugin is a required piece that seems like a big stumbling block to automated builds and alternative workflows.

Chris Gross said:

Hi Ben - good point about module projects. I still believe Potomac provides features to make module projects dead simple w/o having to do some tricky configuration (and we also take care of pathing for you so two team members can have the projects in different paths).

The FB plugin is required currently. We're working on an Ant task for automated builds and I'm pretty sure you could use that in IntelliJ as well.

Tim McGee said:

Hi Chris,

Good read, thanks.

To Ben's point about simply creating modules in separate projects, what do you mean by tricky configuration?

Chris Gross said:

Hi Tim,

I think primarily pathing (which can be different for different team members) and also the link report options that people tend to use to prevent multiple modules from including the same classes.

regards,
-Chris

Will said:

Funny thing is Flex seems to have it's own system for managing module loading and dependancy, but nobody knows about it!

Leave a comment


Tag Cloud

Question of the Week: Dream App

If you had an unlimited budget and unlimited resources what application would you build and why would you build it?

Answer

Latest Features

Recommended for You

@InsideRIA on Twitter

Archives

  • Or, visit our complete archive.  

About This Site

Welcome to the premiere community site for all things RIA sponsored by O'Reilly Media and Adobe Systems Incorporated.