SlideShare a Scribd company logo
Rewriting a Plugin Architecture 3 Times to Harness the API Economy
Rewriting a Plugin Architecture 3 Times
to Harness the API Economy
A couple of Atlassians who are passionate about plugins
Tim Pettersen
Developer Provocateur
@kannonboy
Ian Buchanan
Developer Partisan
@devpartisan
API
Economy
Economy
$50,000,000
*Paid to ISVs to date.
*2011. http://techcrunch.com/2012/04/24/facebook-revenue-share-apps/
15,000,000 paying
users
$1,000,000,000
*Paid to ISVs in 2013. http://www.partner-path.com/2013/12/salesforce-partner-ecosystem/
Blue logos?
REST? OAuth?
API
Economy
SPI
API Application
Programming
Interface
SPI Service
Provider
Interface
Atlassian
Plugins
(2004)
P2
(2008)
Atlassian
Connect
(2014)
Rewriting a Plugin Architecture 3 Times to Harness the API Economy
Rewriting a Plugin Architecture 3 Times to Harness the API Economy
Atlassian
Plugins
(2004)
Open(-ish)
Source
[2001]
Why it’s awesome!
Customers can “scratch their own itch”
Atlassian devs can focus on the 90%
Customization == stickier product
Devs who customize, evangelize
Why it sucks..
Developer support load
Poor plugin UX == poor product
perception
Pain to build the entire product
Massive barrier to upgrade
Atlassian
Plugins
(2004)
JIRA 3.0
How?
Wherever there is a collection of
type FOO, let the end user inject
their own implementations of FOO.
“Web fragments”
<ul>
</ul>
<li><a href=“/dashboard.jspa”>Home</a></li>
<li><a href=“/project.jspa”>Browse Project</a></li>
<!-- 
 -->
<li><a href=“/admin.jspa”>Administration</a></li>
interface WebItem {
String getHref();
String getText();
}
class FooWebLink implements WebItem {
}
public String getHref() {
return “http://foo.com”;
}
public String getText() {
return “Foo”;
}
List<WebItem> getModules()
PluginAccessor
<li><a href=“/dashboard.jspa”>Home</a></li>
<li><a href=“/project.jspa”>Browse Project</a></li>
<!-- 
 -->
<li><a href=“/admin.jspa”>Administration</a></li>
<ul>
</ul>
<% for (WebItem wi : pluginAccessor.getModules()) { %>
<li>
<a href=“<% wi.getHref() %>”>
<% wi.getText() %>
</a>
</li>
<% } %>
Plugins promote abstraction and enforce
modular architecture!
Two plugins
looks great!
3+ plugins.. not
so hot.
Every (pluggable) collection is now potentially
infinitely large.
List<WebItem> getModules()List<Type> getModules(Type)
PluginAccessor
public void transitionIssue(Issue issue, Transition tn) {
// update issue state
// ..
// send email to watchers
for (User watcher : issue.getWatchers()) {
issue.emailTo(watcher);
}
}
public void transitionIssue(Issue issue, Transition tn) {
// update issue state
// ..
}
public static interface PostFn {
void onTransition(Issue issue);
}
public class EmailFn implements PostFn {
public void onTransition(issue) {
for (User watcher : issue.getWatchers()) {
issue.emailTo(watcher);
}
}
}
public void transitionIssue(Issue issue, Transition tn) {
// update issue state
// ..
// trigger post functions
for (PostFn fn : pluginAccessor.get(PostFn.class)) {
fn.onTransition(issue);
}
}
public class EmailFn implements PostFn {
public void onTransition(issue) {
for (User watcher : issue.getWatchers()) {
issue.emailTo(watcher);
}
}
}
Adding a new “plugin point” is easy if you
already have good abstraction!
You SHOULD make “pluginizing” a feature
as simple & quick as possible. Otherwise if
there’s a crunch for time, it won’t happen.
Spike it
Make it
work
Test it
Add an
API / SPI
Ship it
for (PostFn fn : pluginAccessor.get(PostFn.class)) {
fn.onTransition(issue);
}
ArithmeticException
StackOverflowError
while (true) {}
OutOfMemoryError
ClassNotFoundException
ClassCastException
Murphy’s law:
If a plugin can fail, it will.
Horrifically.
for (PostFn fn : pluginAccessor.get(PostFn.class)) {
fn.onTransition(issue);
}
Code defensively
try {
} catch (Exception e) {
log.error(“Plugin post-function failed”, e);
}
log.debug(“Invoking ” + fn);
Corollary:
If an API is public, it will be used.
Often incorrectly.
public void publicApiMethod(List<?> list)
..
}
Show them the way
if (list == null) throw new NullPointerException(
“list must not be null”
);
if (list.isEmpty()) throw new IllegalArgumentException(
“list must not be empty”
) );
/**
* @param list a non-null, non-empty list
*/
Backend
‱ Custom fields
‱ JQL functions
‱ Workflows (post-functions, conditions)
generic
‱ Servlets
‱ Filters
‱ Event listeners
https://bitbucket.org/atlassian/atlassian-plugins
Source (BSD 3-clause licensed)
Embedding Guide
http://bit.ly/embedding-plugins
Atlassian Plugins
‱ Host application exposes some “plugin point”
interfaces
public static interface PostFn {
void onTransition(Issue issue);
}
‱ Plugin developer provides concrete implementations
public class EmailFn implements PostFn {
// send email to watchers
for (User watcher : issue.getWatchers()) {
issue.emailTo(watcher);
}
}
How it works (1 of 3)
‱ Plugin developer adds an XML descriptor (remember
it’s 2004)
<post-function class=“com.foo.EmailFn” weight=“10” />
‱ Developer packages up the class and XML in a JAR
and puts it on the classpath
atlassian-jira/WEB-INF/lib/my-cool-plugin-1.0.jar/
How it works (2 of 3)
atlassian-plugin.xml
com/foo/EmailFn.class
‱ On startup, plugin system parses the XML and
instantiates classes with Spring DI
‱ The PluginAccessor is injected into other
components and used to look up modules.
‱ Because the class path is static, the PluginAccessor
caches plugins very aggressively.
How it works (3 of 3)
commons-
lang.jar
atlassian-
jira.jar
plugin0.jar plugin1.jar
WEB-INF/lib
interface
com.atlassian.PostFn
class
com.foo.EmailFn
implements
my-cool-
lib.jar
Why it’s awesome!
Easier customization by end-users
Smoother upgrades
Improved customization UX
Architectural benefits
Simple to implement
Why it sucks..
Totally bespoke, non-standard
Need to restart to install plugins
No API delineation
Shared classpath
Re-architecting as plugins
a bunch of
work
Dogfooding APIs?
product
manager
“PM friendly” benefits!
Release plugins out of band
Ship “dark features”
Customers can turn stuff off
Release paid plugins ($$$)
Architecture == velocity
Make sure your plugin
system works.
Nothing turns off a plugin developer like
a broken API or an unstable platform.
P2
(2008)
P2
(2008)
Why plugins suck..
Totally bespoke, non-standard
Need to restart to install plugins
No API delineation
Shared classpath
OSGi
commons-
lang.jar
atlassian-
jira.jar
plugin0.jar plugin1.jar
WEB-INF/lib
my-cool-
lib.jar
commons-
lang-3.1.jar
atlassian-
jira.jar
WEB-INF/lib
Export-Package:
com.atlassian.jira;version=“5.0”,
org.apache;version=“3.1”,


MANIFEST.MF
Import-Package:
com.atlassian.jira;version=“5.0”,
MANIFEST.MF
Export-Package:
org.apache;version=“3.3”
plugin1.jar
Import-Package:
org.apache;version=“3.3”
MANIFEST.MF
my-cool-
lib.jar
plugin0.jar
commons-
lang-3.3.jar
Why it sucks..
Totally bespoke, non-standard
Need to restart to install plugins
No API delineation
Shared classpath
Why it sucks..
OSGi is pretty
complicated
175Kb of text
JIRA Agile’s
MANIFEST.MF
P1 P2
<post-function class=“com.foo.EmailFn”
weight=“10” />
public class EmailFn implements PostFn {..}
+
=
a working plugin
<post-function class=“com.foo.EmailFn”
weight=“10” />
public class EmailFn implements PostFn {..}
Import-Package:
com.atlassian.jira;version=“5.0”,
Export-Package:
org.apache;version=“3.3”
<component>
..
</component>
+
+
+
=
a working plugin

 maybe
Abstracting OSGi and a few
other things..( )
C nsPr s
‱ Less upgrade pain
‱ Easy onboarding for
new users
‱ Startup time
‱ Leaky abstraction
‱ Non-standard use
of standard tech
‱ Proxies all the way
down
‱ Complexities
Was it
worth it?
Probably.
Supporting
your ecosystem
Photo: Nicholas A. Tonelli
Rewriting a Plugin Architecture 3 Times to Harness the API Economy
Good for devs!
Paint-by-numbers marketing
Pricing & licensing APIs
Feedback
Tracking & analytics
Good for customers!
Central authority for add-ons
Less fragmented UX
Ratings & reviews
Unified billing
Focus shifts from user to
vendor customization
Building a marketplace is
non-trivial
Rewriting a Plugin Architecture 3 Times to Harness the API Economy
Tim’s top tip for dev docs
Keep your documentation as close to
the code as possible.
Bind the code..
..to the docs!
master feature
Write the
docs
Code talks!
Make sure you have a simple process
for open sourcing and liberally
licensing example add-ons.
Meta-Developer Tools
Photo: Biser Todorov
SDK
Fully automate plugin ALM
Spin up products in “developer mode”
Tight development loop
Provide realistic test data
Dogfood it!
FREE
/stash/projects
/stash/rest/api/1.0/projects
/stash/rest/api/1.0/projects
/stash/projects
?web.panels&web.items/stash/projects
?web.panels&web.items/stash/projects
Developer Mode
Trim out dev speed killers (websudo, etc)
Expose logs & debug info
Release your own internal
productivity tools
Add in custom “dev mode” plugins
(2014)
What is Atlassian Connect?
Remote Plugins
REST API
‱ Drive the product via its REST API
WebHooks
‱ Receive notiïŹcations from the product via WebHooks
‱ Inject content into the product UI via iframes
UI
Atlassian ‹
Product
Plugin
Service
Add-ons
Why?
Atlassian Cloud (SaaS)
Run 3rd party code out-of-process
Improved customization UX (yet again)
Architectural benefits
Rewriting a Plugin Architecture 3 Times to Harness the API Economy
‱ Connect is a new layer on
top of the older plugin
model.
‱ Same Marketplace serves
up Connect plugins.
‱ Same plugins still available
in the Marketplace.
‱ Same REST APIs still
available for both Server
and Cloud.
‱ Connect adds a new mode
of integration.
Building up
http://housebeauty.net/dressy-modern-townhouse-design-with-rooftop-garden-and-glass-walls/eye-catching-green-
roofed-penthouse-apartment-rooftop-garden-with-deck-surrounded-by-glass-balustrades/#image-1
How?
Wherever a module is called, ‹
let a third-party inject a new feature.
remember web fragments
AC WebPanel
AC IssueTab
‱ Declare plugin with a descriptor.
‱ Extend the Atlassian application UI with modules.
‱ Request appropriate scopes.
‱ Recognize the user.
‱ Call the Atlassian application's REST API.
‱ Respond to the Atlassian application's webhooks.
‱ Register on the Atlassian Marketplace.
‱ Respect plugin licensing.
How to author a Connect Plugin
"name": "Hello World", "description": "
",
"key": "com.example.myaddon", "apiVersion": 1,
"baseUrl": "http://example.com/myaddon",
"modules": {
"generalPages": [{
"name": { "value": "Greeting" }, "key": "hello-world",
"location": "system.top.navigation.bar",
"url": "/helloworld.html"
}]
},
"scopes": [ "read", "write" ],
"authentication": { "type": "jwt" },
"lifecycle": { "installed": "/add-on-installed-callback" }
where it is hosted
which modules it uses
which scopes it needs
recognize the user
Example Scopes for JIRA
PROJECT_ADMIN
DELETEWRITE
ADMIN
READ
GET /myaddon?jwt=<jwt-token> http/1.1
POST /jira/rest/api/2/issue/AC-1/attachments http/1.1
Authorization: JWT <jwt-token>
Recognizing the user with JWT
Example REST API for Confluence
‱ URLs for resources
‱ HTTP verbs
‱ Parmeters ïŹlter collections
‱ JSON data
‱ HAL(ish) links (newer APIs)
Example JIRA WebHooks
‱ HTTP callback to a URL
‱ Filtered by JQL
‱ When speciïŹc event occurs
"modules": {
"webhooks": [{
"event": "jira:issue_created",
"url": "/issue-created"
}]
}
Register on the Atlassian Marketplace
‱ Find: in context
catalog of add-ons
‱ Try: manage leads
‱ Buy: manage sales
and licensing
‱ Vagrant Box for local development

‱ JSON descriptor validator

‱ JWT decoder

‱ Marketplace wizard to create a
Connect listing

‱ Access Token model for private plugins

‱ Webhook Inspector
Developer Tools for Atlassian Connect
C nsPr s
‱ Code in any language
‱ Use any build & dev
tools
‱ Use anything:
databases, search
indexes, caching
services, etc
‱ Host and scale a
service
‱ No automated
devloop (P2 SDK)
‱ Provide everything:
databases, search
indexes, caching
services, etc
Why it’s awesome!
BYOS (Bring your own stack)
More services, than products
Sandboxing
UI Design
Aligned with microservice thinking
Why it sucks..
Complex to troubleshoot
Harder to create concrete examples
More developer tools, not just docs
More interfaces must be stable
Remember
SPIs?
P1
open(ish) source
P2
What’s Next?
Consolidate and expand
Vendor
add-on
‱ Extend Bitbucket and HipChat
‱ Build complex vertical apps: powered by Atlassian
‱ Build integrations between Atlassian applications
Atlassian
add-on
Questions?
A couple of Atlassians who are passionate about plugins
Tim Pettersen
Developer Provocateur
@kannonboy
Ian Buchanan
Developer Partisan
@devpartisan

More Related Content

PPTX
Plugin architecture (Extensible Application Architecture)
KEY
L0016 - The Structure of an Eclipse Plug-in
PPTX
Building Eclipse Plugins
ODP
Simplifying RCP Update and Install
PPT
Introduction To Eclipse RCP
 
PPT
Eclipse Plug-in Develompent Tips And Tricks
PPTX
Eclipse RCP Demo
PPTX
Test automation with php codeception
Plugin architecture (Extensible Application Architecture)
L0016 - The Structure of an Eclipse Plug-in
Building Eclipse Plugins
Simplifying RCP Update and Install
Introduction To Eclipse RCP
 
Eclipse Plug-in Develompent Tips And Tricks
Eclipse RCP Demo
Test automation with php codeception

What's hot (20)

PDF
SpringBoot
PDF
Codeception
PDF
Acceptance testing in php with Codeception - Techmeetup Edinburgh
PPT
Eclipse IDE
PDF
What's new in Eclipse Mars
PDF
Testing with Codeception
PDF
Spring Boot
PDF
White paper mbre_en
PDF
Eclipse plug in development
PDF
Testing PHP with Codeception
PPTX
Eclipse Overview
PDF
Codeception introduction and use in Yii
PDF
Eclipse RCP outside of Eclipse IDE - Gradle to the rescue!
PDF
Connecting Connect with Spring Boot
PPT
Eclipse RCP
PPTX
Eclipse RCP Overview @ Rheinjug
PDF
Codeception: introduction to php testing
ODP
Integration Testing in Python
DOCX
Selenium interview questions
PDF
Rediscovering Spring with Spring Boot(1)
SpringBoot
Codeception
Acceptance testing in php with Codeception - Techmeetup Edinburgh
Eclipse IDE
What's new in Eclipse Mars
Testing with Codeception
Spring Boot
White paper mbre_en
Eclipse plug in development
Testing PHP with Codeception
Eclipse Overview
Codeception introduction and use in Yii
Eclipse RCP outside of Eclipse IDE - Gradle to the rescue!
Connecting Connect with Spring Boot
Eclipse RCP
Eclipse RCP Overview @ Rheinjug
Codeception: introduction to php testing
Integration Testing in Python
Selenium interview questions
Rediscovering Spring with Spring Boot(1)
Ad

Similar to Rewriting a Plugin Architecture 3 Times to Harness the API Economy (20)

PPT
Plugins 2.0: The Overview
 
ODP
Plug yourself in and your app will never be the same (1 hr edition)
PPT
The Web on OSGi: Here's How
 
PPTX
Flask
PDF
Declaring Server App Components in Pure Java
PDF
IBM ConnectED 2015 - BP106 From XPages Hero To OSGi Guru: Taking The Scary Ou...
PPTX
Power Apps Component Framework - Dynamics Power! 365 Paris 2019
PPTX
SoapUI Pro Plugin Workshop #SoapUIPlugins
ODP
Plug yourself in and your app will never be the same (2 hour edition)
ODP
Plug yourself in and your app will never be the same (2 hr editon)
PDF
Google App Engine for Java
PDF
Jenkins - Automating Yourself Out Of A Job (One That You Don't Want)
ODP
Lotusphere 2011 Jmp103 - Jumpstart Your "Jedi Plug-in Development Skills" wi...
PDF
Serverless in production (O'Reilly Software Architecture)
ODP
eXo Platform SEA - Play Framework Introduction
PPTX
Developing for the Atlassian Ecosystem
PPTX
Introduction to Google App Engine with Python
PPT
Understanding and extending p2 for fun and profit
PPT
Maven Introduction
PPT
ASP.NET AJAX with Visual Studio 2008
Plugins 2.0: The Overview
 
Plug yourself in and your app will never be the same (1 hr edition)
The Web on OSGi: Here's How
 
Flask
Declaring Server App Components in Pure Java
IBM ConnectED 2015 - BP106 From XPages Hero To OSGi Guru: Taking The Scary Ou...
Power Apps Component Framework - Dynamics Power! 365 Paris 2019
SoapUI Pro Plugin Workshop #SoapUIPlugins
Plug yourself in and your app will never be the same (2 hour edition)
Plug yourself in and your app will never be the same (2 hr editon)
Google App Engine for Java
Jenkins - Automating Yourself Out Of A Job (One That You Don't Want)
Lotusphere 2011 Jmp103 - Jumpstart Your "Jedi Plug-in Development Skills" wi...
Serverless in production (O'Reilly Software Architecture)
eXo Platform SEA - Play Framework Introduction
Developing for the Atlassian Ecosystem
Introduction to Google App Engine with Python
Understanding and extending p2 for fun and profit
Maven Introduction
ASP.NET AJAX with Visual Studio 2008
Ad

More from Tim Pettersen (6)

PDF
Git and Unity
PDF
Tracking large game assets with Git LFS
PDF
Code reviews vs Pull requests
PDF
Tracking huge files with Git LFS - LinuxCon 2016
PDF
Tracking huge files with Git LFS (GlueCon 2016)
PDF
Master your metadata
Git and Unity
Tracking large game assets with Git LFS
Code reviews vs Pull requests
Tracking huge files with Git LFS - LinuxCon 2016
Tracking huge files with Git LFS (GlueCon 2016)
Master your metadata

Recently uploaded (20)

PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
 
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Nekopoi APK 2025 free lastest update
PDF
System and Network Administration Chapter 2
PPTX
history of c programming in notes for students .pptx
PDF
top salesforce developer skills in 2025.pdf
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PPTX
Introduction to Artificial Intelligence
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Odoo POS Development Services by CandidRoot Solutions
Operating system designcfffgfgggggggvggggggggg
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
 
PTS Company Brochure 2025 (1).pdf.......
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Odoo Companies in India – Driving Business Transformation.pdf
How Creative Agencies Leverage Project Management Software.pdf
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Nekopoi APK 2025 free lastest update
System and Network Administration Chapter 2
history of c programming in notes for students .pptx
top salesforce developer skills in 2025.pdf
2025 Textile ERP Trends: SAP, Odoo & Oracle
Introduction to Artificial Intelligence
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
CHAPTER 2 - PM Management and IT Context
How to Migrate SBCGlobal Email to Yahoo Easily
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf

Rewriting a Plugin Architecture 3 Times to Harness the API Economy