Implementing Dijkstra’s Algorithm in Ruby

Jerry Luk, Senior Software Engineer

Recently in a LinkedIn LED hack day, I got a chance to play around with data to analyze the social graph. In order to compute some results in real-time, I needed an efficient way to find the shortest path between two nodes in a graph and Dijkstra’s algorithm came to mind.

Dijkstra’s algorithm is a graph search algorithm that solves the single-source shortest path problem for a graph with non negative edge path costs, outputting a shortest path tree. This algorithm is often used in routing. Wikipedia

I searched on the web a bit, but I couldn’t find a Ruby implementation so I decided to write my own. It ended up being pretty easy to implement. I decided to post it here in case someone in the future wants to save 30 minutes or so implementing it. Please note that it makes use of priority queue library which is written by K. Kodama.

require 'pqueue'

class Algorithm
INFINITY = 1 << 32

def self.dijkstra(source, edges, weights, n)
visited = Array.new(n, false)
shortest_distances = Array.new(n, INFINITY)
previous = Array.new(n, nil)
pq = PQueue.new(proc {|x,y| shortest_distances[x] < shortest_distances[y]})

pq.push(source)
visited = true
shortest_distances = 0

while pq.size != 0
v = pq.pop
visited[v] = true
if edges[v]
edges[v].each do |w|
if !visited[w] and shortest_distances[w] > shortest_distances[v] + weights[v][w]
shortest_distances[w] = shortest_distances[v] + weights[v][w]
previous[w] = v
pq.push(w)
end
end
end
end
return [shortest_distances, previous]
end
end

Please let me know if you have any questions.

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

Twitterator: The GanzBot Chronicles

Jeremy Gillick.jpg

When Steve Ganz left to compete in the PDGA World Championships little did he know that he’d return to find a fast talking, “fashionably low-rate” robot built in his likeness; he may never take a vacation again! The “Ganzbot”, as we named it, was a collaborative effort from our Web Development team with participation from Jamie Still, Dennis Hengeveld, Scott Olson and me.

The robot reads quotes from the Ganzbot Twitter feed and an internal message queue that anyone in the office can submit text to. When he talks his face becomes expressive with moving eyebrows, lips synchronized to the audio and eyes that change color.

Ganz_and_ganzbot

The idea behind Ganzbot actually goes back several months when Bryan Haggerty and Steve were joking that he needed a robot to do his work so he would have time for meetings. But frankly, we just wanted to put it together to see Steve’s reaction when he returned and I think that alone was worth the effort!

That soon caught on and Ganzbot became an office joke until being realized as a real robot while Steve was away. But who’d have thought that Engadget, Gizmodo and Make would notice too.

Want to make your own GanzBot? Check out step-by-step instructions here.

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

JDBC Connection Pooling for Rails on Glassfish

Ikai Lan.jpg

In Light Engineering (LED), we’re known to be multilingual – depending on the project, we’ve been known to speak Perl, Python, Java, C++, Javascript and PHP, to name a few. Our weapon of choice is still Ruby on Rails, the popular MVC framework. Out belief is that Rails makes certain types of tasks easy, and others laughably trivial. That being said, LinkedIn is still primarily a Java shop, and for good reason. Java technologies are mature, proven, and all around solid. For this reason, LED has had a very vested interest in the development work that is going into JRuby.

We started a few months ago around the time JRuby 1.1.2 went live by switching some of our Rails applications to run on Glassfish. Using Warbler, we successfully wrapped our Rails applications into WAR files and deployed on Glassfish (we’ll probably write a more detailed tutorial of this at a future date). A WAR file is completely self contained application that can be deployed simply by copying to an autodeploy directory. No more Apache/Nginx reverse proxy, no more Capistrano, no more installing gems on a production container, no more of any of that madness. This was a huge win, and we broke out the champagne bottles.

But we weren’t done. We weren’t taking advantage of many Java technologies, most notably, we weren’t taking advantage of the JDBC connection pooling capabilities of the Glassfish application server for our MySQL database.

We started by reading this tutorial by Arun Gupta of Sun. The article is fantastic, but the one criticism I have is that it was written from the perspective of a master Java engineer that learned Rails, as opposed to that of a Rails engineer approaching JRuby.

From a high level, here are the steps needed to enable JDBC connection pooling for a Rails application running in a Glassfish container:

  1. Define a JDBC connection pool.
  2. Define a JDBC resource with a JNDI name.
  3. Download and install the MySQL connection adapter.
  4. Update database.yml to use JDBC.
  5. Configure ActiveRecord to disconnect after every query.

Believe it or not, there are only five steps. I have to admit, I was initially intimidated. Java allows so much power and flexibility that, to a novice, seeing a hundred configuration choices in the Glassfish admin web UI can be a deterrent. As it turns out, we only need to touch two parts of that UI. Let’s get started:

1. Define a JDBC connection pool.

Log in to your Glassfish application server. Expand Resources->Connection Pools.

Connection Pools - Ikai.jpg

Click new. You’ll be presented with three fields. The name is arbitrary, but you’ll need to know it later. Select javax.sql.DataSource as the resource type, and MySQL as the vendor.

New JDBC Connection Step 1 - Ikai.jpg

The next screen will have more options. Change the datasource classname to com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource

Under additional properties, there should be fields configuring the database connection. Set these as appropriate.

Edit Connection Pool - Ikai.jpg

2. Define a JDBC resource with a JNDI name.

JNDI stands for Java Naming and Directory Interface, and will allow us to create a standardized name for the JDBC connection pool we just created.

In the navigation pane, click through to Resources -> JDBC -> JDBC Resources. Click new.

New JDBC Resource - Ikai.jpg

In the drop down box, select the JDBC connection pool created in step 1. For the JNDI name, it’s accepted practice to name it jdbc/connection_name.

3. Download and install the MySQL connection adapter.

tar zxvf mysql-connector-java-VERSION.tar.gz
cd mysql-connector-java-VERSION
ant
cp mysql-connector-java-VERSION-bin.jar $GLASSFISH_HOME/lib

You may have to restart Glassfish for the install to work:

asadmin stop-domain DOMAIN
asadmin start-domain DOMAIN

4. Update database.yml to use JDBC.

In your config/database.yml file, we need to tell Rails to use the connection pool rather than directly connecting to the database. Here’s a snippet of our production configuration:

production:
   adapter: jdbc
   jndi: jdbc/polls
   driver: com.mysql.jdbc.Driver

That’s all you will need. Unlike standard configuration files, you do not need to specify things like the username, password or host because these are configured in the Application Server. I like this method because it means the engineer doing the deployment does not need to build the YAML file each time, check it in to SVN, or copy from a database.yml template with the production settings. It’s one less deployment step, and ultimately, one less item on the security checklist.

5. Configure ActiveRecord to disconnect after every query.

ActiveRecord maintains a persistent connection to the database. This is no longer necessary, as there is very little overhead in opening a connection to JDBC, which manages the connection persistence. We’ll need to disable this. I’m using code borrowed from Nick Sieger’s awesome presentation at RailsConf 2008:

# config/initializers/close_connections.rb
if defined?($servlet_context)
   require 'action_controller/dispatcher'

   
ActionController::Dispatcher.after_dispatch do      
      ActiveRecord::Base.clear_active_connections!
   end
end

You’re done! Now all you have to do is build the WAR file and drop it in Glassfish’s autodeploy directory.

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

Tech Talk: Steve Souders on Even Faster Web Sites

Jime Meyer

Last week, we were fortunate enough to have Google’s Steve Souders give a tech talk on Even Faster Web Sites, fresh on the heels of his presentation at OSCON in Portland two weeks ago.

Steve’s name likely sounds familiar to you; indeed, if you work in web development, you’d have to work hard to avoid benefiting from his research. Not only has he spoken often at such conferences as OSCON, Rich Web Experience, Web 2.0 Expo, and The Ajax Experience; he co-founded O’Reilly’s Velocity conference; he’s also the author of the book High Performance Web Sites: Essential Knowledge for Front-End Engineers and the excellent YSlow extension for Firebug. He credits a lot of his success to adopting Harvey Penick’s methodology of keeping a notebook handy and jotting down interesting observations, researching them further, and acting on the best ones.

The tech talk centered around Steve’s "Performance Golden Rule": 80-90% of the end user response time is spent on the front end (he uses a simple user-centric metric for dividing front end and back end load time: loading the HTML document is back end; everything after that is front end). This golden rule is clearly sensible for three reasons:

  1. There’s greater potential for improvement. Saving half of 90% is a much bigger win than half of 10%.
  2. Front end changes are simpler than back end. The techniques you’ll use (minification, consolidation, compression, etc.) take engineer days, not weeks.
  3. It’s a demonstrably effective approach. It’s not only been proven at Yahoo and elsewhere, you can likely make trivial changes to your own site and see the results immediately.

The first half of the talk was a discussion of the fourteen rules which are the basis of both his book and YSlow, which essentially automates measuring a web site’s performance against those fourteen metrics. Rather than recount it in great detail, I’ll urge you to get a copy of his book (via Amazon, O’Reilly’s Safari, or your favorite local bookstore) and read the Yahoo! Exceptional Performance Team site while you’re waiting to get the book in your hot little hands. Time and money well spent.

The second half was focused on Javascript and how it affects page loading. The load time of most modern web pages is 20-40% of the total load time, so reducing this results in noticeable improvement in page load speed. His key observations in this area are:

  • Most browsers load Javascript serially by default
  • Only about one-fourth of the Javascript functions that are loaded are actually needed before the onLoad event fires
  • It’s important to understand how element load order affects particular browsers (e.g. Firefox will block all parallel downloads while downloading stylesheets; Internet Explorer will block if you follow a stylesheet with an inline script)

Accordingly, the top items on his hit list are splitting the initial script payload, loading
scripts in parallel, and careful attention to placement of inline
scripts — all aimed at accelerating the firing of the onLoad
event.

I could go on in some detail about how to accomplish this, but you’d be better served to read Steve’s blog and watch some of the videos of his other presentations available on his web site. Instead, here’s a preview of the guidelines which are the beginning of his next book, some of which are also found on the Yahoo! Exceptional Performance Team site:

  1. Split the initial payload
  2. Load scripts without blocking
  3. Don’t scatter inline scripts
  4. Split dominant domains
  5. Make static content cookie-free
  6. Reduce cookie weight
  7. Minify CSS
  8. Optimize images
  9. Use iframes sparingly
  10. To www or not to www

Finally, you should have a look at Cuzillion, Steve’s tool for modeling web page elements and tinkering with how order affects loading. His slides from the tech talk cite it for examples, and I suspect his next book will, as well. Very useful as you’re trying find the delays in loading your web pages and understand what you can do about them.

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

LinkedIn Tech Talk: Brad Neuberg on Gears


Dhananjay Ragade, Sr. Software Engineer

On Tuesday, Brad Neuberg from Google’s Developer Program visited LinkedIn’s headquarters in Mountain View to give a presentation on Gears to the engineering department as part of our series of LinkedIn Tech Talks.

Gears is an open source project that enables more powerful web applications, and provides for a better user experience with a cross-browser plugin. Gears gets installed on a user’s machine (the same way any other plugin like Adobe Acrobat Reader does), and then provides a local database, worker pool, and a local web server.

Gearslide

The database is a full-featured SQLite DB which provides SQL queries, views, triggers, full text search, and the ability to store gigs of user data locally. The local server can allow you to run web apps offline by storing HTML, CSS, images, etc., but in managed, versioned bundles which can be downloaded in the background, and it does not get cleared when the user clears the browser’s cache. Using it is much better than relying on the normal browser cache. The worker pool gives you the ability to send tasks for background processing off to Gears, so that JavaScript code can be run asynchronously without blocking the main script running in the browser. This is perfect for dealing with any number crunching, long DB queries, or communication with remote servers. Google has more information in their API docs.

Afterwards, Brad stayed around to discuss how different engineering groups at LinkedIn could use Gears to give our users a better user experience and more powerful features.

Although we don’t have Brad’s talk at LinkedIn online for you to see, here is another presentation on Gears that Brad gave at Google I/O 2008.

I’m impressed with Gears and some of the demos, and real applications like Remember The Milk that I’ve seen using it. I’m sure we could make use of this technology to dramatically improve the user experience for many LinkedIn users in areas like the homepage, network updates, address book, and corporate solutions.

NOTE: This entry was published with Brad Neuberg’s permission.

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

OSCON 2008 and Web Frameworks of the Future

Matt Raible, Lead UI Architect

Last week, I attended O’Reilly’s Open Source Convention (a.k.a. OSCON) in Portland, Oregon. This was the 5th year I’ve attended (and spoke) at OSCON. I really like the diversity of open source projects and languages discussed at this conference. You can find always find good sessions on Perl, PHP, Python, Ruby and even Java. Of the many sessions I attended, the ones I learned the most from were Google XML Pages by Harry Heymann and Laurence Gonsalves and Even Faster Web Sites (PPT) by Steve Souders. If you didn’t get a chance to attend OSCON this year, you might try watching OSCON in 37 minutes by Gregg Pollack. This is a video where Gregg asks many speakers to summarize their talks in 30 seconds or less.

On Wednesday, I presented my talk titled Web Frameworks of the Future: Flex, GWT, Grails and Rails. I was inspired to do this talk when I first heard of SOFEA (Service Oriented Front End Architecture) and SOUI (Service Oriented UI) last fall. These acronyms suggest the same type of architecture; one where the backend serves up data (via SOAP, REST, etc.) and the frontend handles page flow, navigation, etc. SOFEA was created by Ganesh Prasad, Rajat Taneja and Vikrant Todankar in their "Life Above the Service Tier" paper, while SOUI was created by Nolan Wright and Jeff Haynie in a couple of blog posts.

To do research for this talk, I created two different versions of the same application. One was with Flex and Rails and the other was with GWT and Grails. While I didn’t complete the application before the talk, I do plan on continuing to work on it in my spare time and will hopefully have something to show later this fall. The application I’m creating is called "Rich Resume" and will allow you to edit and publish your resume online quickly and easily. If everything goes well, I’ll add the ability to import your LinkedIn Profile to get started. As far as my progress on the application, I was able to finish both backends with Grails and Rails in under 25 hours. Both framework’s out-of-the-box dynamic scaffolding didn’t support one-to-many relationships very well, so I did have to tweak some things. With Rails, I was able to use ActiveScaffold to solve my issues. With Grails, I had to generate Controllers and then manually tweak them to add one-to-many and REST support.

As far as Flex and GWT, I found them both easy to get started with. I got bit early by GWT’s Same Origin Policy, which made it difficult to develop the frontend and backend on different hosts. After moving the GWT app into Grails (using the GWT Plugin), things went much smoother. I was disappointed to find that GWT doesn’t support REST too well, but there seems to be many folks that share this same sentiment and quite a few solutions are being developed (for example, Restlet-GWT). While Flex allows for cross-domain communication, I was disappointed to find it doesn’t support zero turnaround (save/refresh) outside of an IDE. I’m sure over the coming months, I’ll develop a greater sense of affection for these frameworks, but I also think it’s important to note first impressions.

Below is my presentation for your viewing pleasure.

view on slideshare |
download

In October, I’ll be presenting a similar talk at the Colorado Software Summit. This time, I’ll be using Appcelerator to build my Rich Resume application. It should be a good show, especially since my colleagues Yan Pujante and Ikai Lan will be speaking. If you want to learn about how they’ve enhanced LinkedIn’s applications and architecture, you won’t want to miss their talks.

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

Xobni and LexisNexis integrate with LinkedIn

Taylor Singletary - LinkedIn

The LinkedIn Intelligent Application Platform is all about surfacing LinkedIn where you need and want it most. Writing or reading an email? LinkedIn should be there, providing context between you and your contacts.

Xobni is an ideal remedy to the pursuit of context — and now with Xobni’s LinkedIn integration, you can find out everything you need to know about a contact before hitting that Send button: The company they work for, their profile picture, and the rich metadata about your history with them.

Leveraging LinkedIn’s Public Profile API, Xobni surfaces the relevant information you need to know, when you need to know it. You can download Xobni’s Outlook plugin here; it makes a great companion to the already indispensable LinkedIn Outlook Toolbar. Make the most of it for you and your contacts: update your public profile and upload a photo today!

While LinkedIn is of use to workers of any profession, some industries are more specialized than others. Are you a lawyer looking to hire on outside counsel? Your LinkedIn network should be easy to tap for recommendations, insights, and inquiries.

LexisNexis‘ legal services directory, martindale.com, is already a premier online destination for lawyers to connect with other lawyers. Now with LinkedIn integration, it helps you find trusted legal professionals by telling you "Who You Know" at a given law firm. Research, evaluate and select legal counsel with confidence— leverage your LinkedIn professional network in your time of need. This is just the beginning of what will be an exceptional integration between LinkedIn and LexisNexis.

The best part of it all is that the more you establish yourself on LinkedIn (by completing your profile, making those meaningful connections, etc…), the more you can benefit from your LinkedIn experience across the web. At your finger tips, no matter where you are, LinkedIn is everywhere these days. Stay tuned to find out where we’ll pop up next!

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

LinkedIn Tech Talk: Kevin Brown on Shindig

Matt Raible, Lead UI Architect

Last Thursday, Kevin Brown visited LinkedIn’s Mountain View office to do a presentation on Shindig, an OpenSocial Reference Implementation. Below are my notes from his talk.

In September 2007, Google started thinking about Social APIs. Google Gadgets would be better with access to Social Data … but that’s just Google. It was recognized that this is something that many others would like access to. OpenSocial was announced in November 2007. It’s an open standard for developer platforms that has a strong emphasis on “social” data. It’s based on gadgets which is now covered by The Open Social Foundation.

In November, many Googlers started working on a Google Code project based on Java and iGoogle. However, there was too much proprietary code. In December, Brian McCallister of Ning created an ASF Proposal for Shindig. It was a rough port of iGoogle but with Ning’s PHP code. This turned out to be a great starting point. It immediately got interest from Google, Hi5, MySpace and others. While most committers are still from Google, there are 12 developers that work on it full time and they’re adding 2 committers each month. Shindig is a Java/PHP implementation of OpenSocial. Open Campfire is an Apache-licensed .NET implementation that hopes to eventually merge into Shindig.

Shindig has extensive use of existing open source components, including Abdera, Jakarta Commons, Guice, ICU4J, OAuth.net, and JSON.org. It’s largely well tested (developers use TDD), especially for the newer code. There’s a heavy emphasis on DI (Guice helps tremendously) and the builds are done with Maven (Apache recommendation, Kevin hates it).

3 Parts of Shindig:

  1. Gadget Rendering: Fetches/parses gadget XML documents. It also provides a robust proxy to implement gadgets.io requirements (including OAuth and Signed Fetch). It acts as a “glue” between JavaScript libraries, remote sites and social data. It’s built for medium to large deployments and has robust HTTP support. Lastly, it’s very flexible so all major components can be replaced.
  2. Social API: Handles RESTful API calls and interacts with social data. It provides a backend for opensocial.* JavaScript APIs. It’s mostly a serialization/de-serialization layer that delegates to your social data. Currently evaluation two implementation options (Dave Primer’s AtomPub version or JSON version – lengthy explanation on shindig-dev). Currently, developers are creating an entirely new version because of REST and its JSON support. REST has a lot of issues when it comes to JSON. It works great with AtomPub, but AtomPub has too much verbose XML.
  3. Client Code: The first issue that comes up with client code is Security.

For security, iframes cover most of the problems. Cross-domain communication requires special effort – gadgets.rpc has to be implemented using a variety of techniques: window.postMessage in HTML5, document.frameElement in Firefox and window.opener in IE (still in development). Retrieving third-party data is covered by OAuth and Signed Fetch. Getting OAuth / Signed Fetch credentials can be done by passing an encrypted blog of data to the server and treating it as a cookie equivalent. Caja is the future.

Caja (pronounced ka-ha) makes it possible to run third-party JavaScript alongside existing code. It’s not quite ready yet, but significant process has been made. It has limited support in Shindig today, which requires “taming” JavaScript APIs and DOM testing.

Summary

Full support for 0.6-0.8 gadget rendering specification (both versions). Full support for 0.6-0.8 JavaScript APIs. REST mostly done (both versions, PHP is closer). Deployed (or in progress) on many sites: Orkut, hi5, iGoogle sandbox, Hyves, CyWorld, Ning and hundreds of others. It has a very active mailing list and they’re very interested in finding folks with more Maven experience to help out.

The project’s next priority is a stable release. Shindig 1.0 will be OpenSocial 0.8 Compliant. It must have full support for REST. The Java and PHP implementations should be released around the same time. Priority #2 is graduating from Apache Incubator (goals are currently on target). One of the main things they need is more committers, especially those that aren’t from Google. Priority #3 is future enhancements, including:

  • 0.9: “proxied” content type
  • 0.9: OpenSocial templates
  • HTTP Performance Improvements
  • “out of the box” shared caching
  • More social data implementations (e.g. JDBC)
  • Better Documentation

We have many more Tech Talks planned in the future at LinkedIn. Please stay tuned to this blog to learn about new and exciting technologies that we’re learning about.

NOTE: This entry was published with Kevin Brown’s permission.

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

OSGi at LinkedIn: Integrating Spring DM (Part 2)

Yan Pujante, Co-Founder and Distinguished Software Engineer

In my last post I talked about how the Spring-DM extender automatically recognizes new namespaces. In this post I’ll talk about how to configure the extender itself. First let’s talk a little bit about fragments (since it is the mechanism used by Spring-DM).

What is a fragment?
A fragment is a special kind of OSGi bundle. By itself a fragment does not do anything: it cannot be started (it is illegal to have an activator for a fragment). A fragment needs to be ‘attached’ to another bundle called the host bundle. You define a fragment bundle by adding a special header in the MANIFEST:

Fragment-Host: <Host Bundle Symbolic Name>

This is what it looks like in the Equinox console:

39	ACTIVE      org.springframework.bundle.osgi.extender_1.1.0.m2	            Fragments=5555	RESOLVED    com.linkedin.kernel-core.lispring-osgi_1.0.1.SNAPSHOT	            Master=39

55 is a fragment bundle and it attaches to its host 39. The header is defined like this:

Fragment-Host: org.springframework.bundle.osgi.extender

Note that you can have more than one fragment attached to a host (but you cannot have a fragment attached to multiple hosts).

What is the use of a fragment?
Once a fragment is attached to its host, it behaves like if it was part of it. Conceptually, the behavior is similar to what you would obtain if you were to unjar the host and the fragment, and recreate a unique bundle made up of the content of the 2 separate bundles (including manifest headers). It allows to attach behavior and resources to a bundle.

For example if you use the method Bundle.findEntries("META-INF/", "*", false) before attaching the fragment then you will see only the content of the META-INF directory in the host bundle. If you call the same method after the fragment has been attached you will get a different result with the content of the META-INF directory in the host and fragment! This is pretty powerful to load any kind of resources (for example, a localized properties file, etc.).

Here is another example using the fact that the host has now access to classes it didn’t know about before:

  • I have a bundle which depends on nothing else but the JDK and OSGi.
  • In the activator, I instantiate a LogFactory (internal LinkedIn class) this way:
    String logFactoryClassName = System.getProperty("org.xeril.log.Log.factory.class.name");
    
    LogFactory factory = null;
    
    // a class name was provided
    if(logFactoryClassName != null)
    {
    try
    {
    Class logFactoryClass =
    Thread.currentThread().getContextClassLoader().loadClass(logFactoryClassName);
    
    factory = (LogFactory) logFactoryClass.newInstance();
    }
    catch(Throwable th)
    {
    // we display the stack trace but we don't fail
    th.printStackTrace();
    }
    }
    
    // no class name or error
    if(factory == null)
    {
    factory = new JDKLogFactory();
    }
    
  • Now I have a fragment bundle which depends on Log4j and has a Log4jLogFactory class. The system property gets set on the command line and if the fragment is attached, using reflection, the Log4j factory will be instantiated properly although the host does not depend on Log4j nor knows anything about Log4jLogFactory. If it is not attached I simply use the JDK logger.

Fragment Lifecycle
The lifecycle of fragments is a little bit different from other bundles. For example you cannot start a fragment. If you undeploy a fragment that is attached to a host, the fragment is gone from the list of bundles but it is still attached to the host. Same if you install a new one. You actually need to ‘refresh’ the host to see something happening.

Below is an example of activating a bundle with Equinox:

osgi> ss39	ACTIVE      org.springframework.bundle.osgi.extender_1.1.0.m2	            Fragments=5555	RESOLVED    com.linkedin.kernel-core.lispring-osgi_1.0.1.SNAPSHOT	            Master=39osgi> uninstall 55

osgi> ss39	ACTIVE      org.springframework.bundle.osgi.extender_1.1.0.m2	            Fragments=55

osgi> install file:/.../com.linkedin.kernel-core.lispring-osgi_1.0.1.SNAPSHOT.jar

osgi> ss39	ACTIVE      org.springframework.bundle.osgi.extender_1.1.0.m2	            Fragments=5556	INSTALLED   com.linkedin.kernel-core.lispring-osgi_1.0.1.SNAPSHOT

osgi> refresh 39osgi> ss39	ACTIVE      org.springframework.bundle.osgi.extender_1.1.0.m2	            Fragments=5656	RESOLVED    com.linkedin.kernel-core.lispring-osgi_1.0.1.SNAPSHOT	            Master=39

Spring-DM Extender
Now that you know what a fragment is, it should be easy to understand how to extend Spring-DM: you simply need to attach a fragment to the host bundle called org.springframework.bundle.osgi.extender. In your fragment you need to have a directory called META-INF/spring/extender which contains normal Spring context files. Spring-DM will automatically see those files, create an application context and instantiate the beans. It will then look for beans with some specific names to customize itself: this is described in the reference documentation.

For example, by having a bean called applicationContextCreator, you can extend or override entirely the way Spring-DM detects that a bundle is a Spring Powered Bundle. By default, Spring-DM looks for a header or the presence of a META-INF/spring directory to determine that it is a Spring Powered Bundle. You can redefine this behavior to be your own custom header or your own custom directory (or whatever other mechanism you can think of). You can also provide configuration properties like how long to wait on shutdown.

Note: As mentioned in the fragment lifecycle section above, be careful if you attach/update the fragment. You need to refresh the host which in the case of Spring-DM extender will shutdown all application contexts created previously and recreate them. My recommendation is to install both the fragment and the host, and start the host only once they are both installed so that the fragment attaches right away without having to refresh the host afterwards.

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

Joining LinkedIn: An Intern’s Perspective

Andrew Carman, LinkedIntern

Despite the foreboding, Matrix-esque connotation, I was excited to become truly LinkedIn. My previous internships were interesting and educational, but I was looking forward to working in a younger, faster company. And, wow! LinkedIn delivers on that. By the end of day one I was set up with envy-inspiring equipment (fully-loaded MacBook Pro, giant Cinema display, and super comfy chair!), friendly, helpful colleagues, and all the tools I needed to start working on my first project, OpenSocial widgets.

The goal was to create a lightweight widget that grabs company information from LinkedIn via OpenSocial, and displays buzz about the user’s company on their LinkedIn home page, all as an exercise to help LinkedIn’s OpenSocial team develop and test the platform. Getting up to speed on OpenSocial was very easy. Between the Google tutorials and knowledgeable colleagues, setting up "hello world" was practically done for me. By day four I had a working, albeit ugly, version of the widget.

In short, working at LinkedIn is awesome. From the fast pace and supportive working environment (free food!) to the trust the company places in all its employees, even interns, LinkedIn is a company I am proud to work for. It’s going to be the best summer ever! Or at the very least, better than that one I spent painting houses. ;-)

Andrew Carman
LinkedIntern

[Post to Twitter] Tweet This Post

Share: ShareThis | LinkedIn | Digg | Twitter

Close
E-mail It
Powered by ShareThis