SlideShare a Scribd company logo
Expose yourself!
How to Leverage Plugin Extensibility to
         Delight Your Users
Obligatory
Vanity Slide

• GreenHopper
  developer

• Atlassian for 3.5
  years
Why are we here?

• Because we all develop Atlassian
  plugins:

 • Commercial
 • In-house
 • Contracted customizations
Why are we here?
         ...in this session
• Because I want you all to
  start exposing yourself

  • Build, document and
    support APIs for your
    plugins

  • Encourage one another
    to build integrations
    based on these APIs
Your response?


    GTFO!
Your response?

• “How hard is it?”
• “Sounds like a support and
  maintenance nightmare”

• “What’s in it for me?”
We’re doing it
We’re doing it
We’re doing it
We’re doing it
What’s in this talk?

• What we’ve been doing
• Why you should follow our lead
• How you can do it.
GreenHopper
integrations
Pretty URLs
Pivotal importer
GreenFire (or
BonHopper)
Sample data
HipChat for
        GreenHopper


• ???
Why did we build
these integrations?
• Cheap
• Users get something extra for free
• Makes JIRA feel more like a more
  seamless experience
Why should you
   develop such

• Depends on who you are:
 • Commercial developers
 • In-house developers
 • Contract developers
How do we get
       there
• Find opportunities for integrations
• Follow best practices
• Use techniques best-suited to each
  integration
Finding integration
   opportunities
• Existing pain points
• Redundancy between plugins
• Feature overlap
• Contextual interaction
Best Practices
• Don’t build API in a vacuum
• Dogfood your own API
• Build reference implementations
• Clearly separate API from internal
• Decouple through events, where
  possible

• Document
Available
       techniques
• Leverage the plugin system, as
  much as possible

 • Contexts/locations on existing
   module types

 • Custom module types
• Event-driven JS APIs
 • Lightweight
http://wiki.eclipse.org/
Evolving_Java-based_APIs
Available
        techniques
• Demarcate what is API through use
  of a separate API artifact

• Be vigilant to ensure backwards
  compatibility of API - additive
  changes

• Have integration tests and alerts to
  avoid regressions
Exposing Java API
(and playing nicely with the plugin
             system)

• Mark API plugin components as
  public=true

• Export-Package statements
• Limit external class references in
  API artifact to JIRA + platform

• Ensure all maven dependencies are
  marked <scope>provided</scope>
Available
       techniques
• Decide: Hard or soft dependency
 • Hard - your plugin will not
   function in absence of depended-
   upon plugin

 • Soft - graceful degradation, only
   integration features fail
Available
            techniques
• Hard dependency
 • <pluginDependency> in your pom
 • Release your plugin as an OBR
• Soft dependency
 •    DynamicImport-Package, optional service pattern, OptionalFeatureService and
    PluginDependencies, conditional UI elements



 • ...it’s a little harder. Join me over
    in IDEA

More Related Content

KEY
AtlasCamp US 2012 Keynote, Jean-Michel Lemieux
KEY
Developing for Remote Bamboo Agents, AtlasCamp US 2012
PDF
Developers Use Bitbucket and So Can You
PDF
Building GPE: What We Learned
PDF
Jira Daten über Unternehmensgrenzen teilen – K15t Solution Forum 2018
PDF
How HipChat Ships and Recovers Fast with DevOps Practices
PDF
Building an Eclipse plugin to recommend changes to developers
PDF
Cpl12 continuous integration
AtlasCamp US 2012 Keynote, Jean-Michel Lemieux
Developing for Remote Bamboo Agents, AtlasCamp US 2012
Developers Use Bitbucket and So Can You
Building GPE: What We Learned
Jira Daten über Unternehmensgrenzen teilen – K15t Solution Forum 2018
How HipChat Ships and Recovers Fast with DevOps Practices
Building an Eclipse plugin to recommend changes to developers
Cpl12 continuous integration

What's hot (20)

PDF
Reark : a Reference Architecture for Android using RxJava
KEY
The Developer Experience
PDF
London Atlassian User Group - February 2014
PDF
Unpacking Developer Experience
PDF
An Exploration of Cross-product App Experiences
PPTX
Do's and Don'ts of APIs
PDF
Tear Up Your Roadmap and Get Out of the Building
PDF
A Day in the Life of a HipChat Developer
PDF
NodeJS Interactive 2019: FaaS meets Frameworks
PPTX
Rest in practice
PPTX
Api Design
PDF
Building Salesforce1 Communities Apps with React Native and Flux
PDF
Test Driven Development - Workshop
PPTX
PhoneGap - Now and the Future
PDF
Getting Predictable - Pragmatic Approach for Mobile Development - Devday.lk ...
PDF
Designing for User Experience (UX) with Atlassian Tools
PDF
Building a full-stack app with Golang and Google Cloud Platform in one week
PDF
Why your APIs should fly first class
PDF
Beyond Agile and DevOps: From Concepts to Products in Weeks, Not Months
PPTX
SONY BBS - React Native
Reark : a Reference Architecture for Android using RxJava
The Developer Experience
London Atlassian User Group - February 2014
Unpacking Developer Experience
An Exploration of Cross-product App Experiences
Do's and Don'ts of APIs
Tear Up Your Roadmap and Get Out of the Building
A Day in the Life of a HipChat Developer
NodeJS Interactive 2019: FaaS meets Frameworks
Rest in practice
Api Design
Building Salesforce1 Communities Apps with React Native and Flux
Test Driven Development - Workshop
PhoneGap - Now and the Future
Getting Predictable - Pragmatic Approach for Mobile Development - Devday.lk ...
Designing for User Experience (UX) with Atlassian Tools
Building a full-stack app with Golang and Google Cloud Platform in one week
Why your APIs should fly first class
Beyond Agile and DevOps: From Concepts to Products in Weeks, Not Months
SONY BBS - React Native
Ad

Similar to Expose Yourself! How to Leverage Plugin Extensibility to Delight your Users, AtlasCamp US 2012 (20)

PPTX
Openfest15 MySQL Plugin Development
PDF
DevSecCon Asia 2017 - Abhay Bhargav: Building an Application Vulnerability To...
PDF
JUC Europe 2015: Continuous Integration and Distribution in the Cloud with DE...
PDF
Building the Eventbrite API Ecosystem
PPTX
Testing API's: Tools & Tips & Tricks (Oh My!)
KEY
Continuous Integration In A PHP World
PPT
Useful automation
PPTX
Oscon2014 Netflix API - Top 10 Lessons Learned
PDF
KrishnaToolComparisionPPT.pdf
PDF
AD1545 - Extending the XPages Extension Library
PDF
Laravel CI / CD in Azure Web Apps - Global Azure Bootcamp Jakarta
PPTX
Developing for the Atlassian Ecosystem
PPTX
Top 10 Lessons Learned from the Netflix API - OSCON 2014
PPTX
IBM Connect 2016: Speaker Session with Teresa Deane, Senior Developer, BCC
PDF
The Ultimate API Publisher's Guide
PPT
Bridging the Gap - Laracon 2013
PDF
Using BladeRunnerJS to Build Front-End Apps that Scale - Fluent 2014
PPTX
Global Azure 2022 - Architecting Modern Serverless APIs with Azure Functions ...
PPTX
Lessons learned on the Azure API Stewardship Journey.pptx
PPT
How to design effective APIs
Openfest15 MySQL Plugin Development
DevSecCon Asia 2017 - Abhay Bhargav: Building an Application Vulnerability To...
JUC Europe 2015: Continuous Integration and Distribution in the Cloud with DE...
Building the Eventbrite API Ecosystem
Testing API's: Tools & Tips & Tricks (Oh My!)
Continuous Integration In A PHP World
Useful automation
Oscon2014 Netflix API - Top 10 Lessons Learned
KrishnaToolComparisionPPT.pdf
AD1545 - Extending the XPages Extension Library
Laravel CI / CD in Azure Web Apps - Global Azure Bootcamp Jakarta
Developing for the Atlassian Ecosystem
Top 10 Lessons Learned from the Netflix API - OSCON 2014
IBM Connect 2016: Speaker Session with Teresa Deane, Senior Developer, BCC
The Ultimate API Publisher's Guide
Bridging the Gap - Laracon 2013
Using BladeRunnerJS to Build Front-End Apps that Scale - Fluent 2014
Global Azure 2022 - Architecting Modern Serverless APIs with Azure Functions ...
Lessons learned on the Azure API Stewardship Journey.pptx
How to design effective APIs
Ad

More from Atlassian (20)

PPTX
International Women's Day 2020
PDF
10 emerging trends that will unbreak your workplace in 2020
PDF
Forge App Showcase
PDF
Let's Build an Editor Macro with Forge UI
PDF
Meet the Forge Runtime
PDF
Forge UI: A New Way to Customize the Atlassian User Experience
PDF
Take Action with Forge Triggers
PDF
Observability and Troubleshooting in Forge
PDF
Trusted by Default: The Forge Security & Privacy Model
PDF
Designing Forge UI: A Story of Designing an App UI System
PDF
Forge: Under the Hood
PDF
Access to User Activities - Activity Platform APIs
PDF
Design Your Next App with the Atlassian Vendor Sketch Plugin
PDF
Nailing Measurement: a Framework for Measuring Metrics that Matter
PDF
Building Apps With Color Blind Users in Mind
PDF
Creating Inclusive Experiences: Balancing Personality and Accessibility in UX...
PDF
Beyond Diversity: A Guide to Building Balanced Teams
PDF
The Road(map) to Las Vegas - The Story of an Emerging Self-Managed Team
PDF
Building Apps With Enterprise in Mind
PDF
Shipping With Velocity and Confidence Using Feature Flags
International Women's Day 2020
10 emerging trends that will unbreak your workplace in 2020
Forge App Showcase
Let's Build an Editor Macro with Forge UI
Meet the Forge Runtime
Forge UI: A New Way to Customize the Atlassian User Experience
Take Action with Forge Triggers
Observability and Troubleshooting in Forge
Trusted by Default: The Forge Security & Privacy Model
Designing Forge UI: A Story of Designing an App UI System
Forge: Under the Hood
Access to User Activities - Activity Platform APIs
Design Your Next App with the Atlassian Vendor Sketch Plugin
Nailing Measurement: a Framework for Measuring Metrics that Matter
Building Apps With Color Blind Users in Mind
Creating Inclusive Experiences: Balancing Personality and Accessibility in UX...
Beyond Diversity: A Guide to Building Balanced Teams
The Road(map) to Las Vegas - The Story of an Emerging Self-Managed Team
Building Apps With Enterprise in Mind
Shipping With Velocity and Confidence Using Feature Flags

Recently uploaded (20)

DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
Cloud computing and distributed systems.
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
KodekX | Application Modernization Development
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Empathic Computing: Creating Shared Understanding
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Modernizing your data center with Dell and AMD
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
cuic standard and advanced reporting.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
The AUB Centre for AI in Media Proposal.docx
Cloud computing and distributed systems.
Reach Out and Touch Someone: Haptics and Empathic Computing
NewMind AI Weekly Chronicles - August'25 Week I
KodekX | Application Modernization Development
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
NewMind AI Monthly Chronicles - July 2025
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Encapsulation_ Review paper, used for researhc scholars
Unlocking AI with Model Context Protocol (MCP)
Empathic Computing: Creating Shared Understanding
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Modernizing your data center with Dell and AMD
MYSQL Presentation for SQL database connectivity
Per capita expenditure prediction using model stacking based on satellite ima...
cuic standard and advanced reporting.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
Chapter 3 Spatial Domain Image Processing.pdf
Spectral efficient network and resource selection model in 5G networks
“AI and Expert System Decision Support & Business Intelligence Systems”

Expose Yourself! How to Leverage Plugin Extensibility to Delight your Users, AtlasCamp US 2012

  • 1. Expose yourself! How to Leverage Plugin Extensibility to Delight Your Users
  • 2. Obligatory Vanity Slide • GreenHopper developer • Atlassian for 3.5 years
  • 3. Why are we here? • Because we all develop Atlassian plugins: • Commercial • In-house • Contracted customizations
  • 4. Why are we here? ...in this session • Because I want you all to start exposing yourself • Build, document and support APIs for your plugins • Encourage one another to build integrations based on these APIs
  • 6. Your response? • “How hard is it?” • “Sounds like a support and maintenance nightmare” • “What’s in it for me?”
  • 11. What’s in this talk? • What we’ve been doing • Why you should follow our lead • How you can do it.
  • 17. HipChat for GreenHopper • ???
  • 18. Why did we build these integrations? • Cheap • Users get something extra for free • Makes JIRA feel more like a more seamless experience
  • 19. Why should you develop such • Depends on who you are: • Commercial developers • In-house developers • Contract developers
  • 20. How do we get there • Find opportunities for integrations • Follow best practices • Use techniques best-suited to each integration
  • 21. Finding integration opportunities • Existing pain points • Redundancy between plugins • Feature overlap • Contextual interaction
  • 22. Best Practices • Don’t build API in a vacuum • Dogfood your own API • Build reference implementations • Clearly separate API from internal • Decouple through events, where possible • Document
  • 23. Available techniques • Leverage the plugin system, as much as possible • Contexts/locations on existing module types • Custom module types • Event-driven JS APIs • Lightweight
  • 25. Available techniques • Demarcate what is API through use of a separate API artifact • Be vigilant to ensure backwards compatibility of API - additive changes • Have integration tests and alerts to avoid regressions
  • 26. Exposing Java API (and playing nicely with the plugin system) • Mark API plugin components as public=true • Export-Package statements • Limit external class references in API artifact to JIRA + platform • Ensure all maven dependencies are marked <scope>provided</scope>
  • 27. Available techniques • Decide: Hard or soft dependency • Hard - your plugin will not function in absence of depended- upon plugin • Soft - graceful degradation, only integration features fail
  • 28. Available techniques • Hard dependency • <pluginDependency> in your pom • Release your plugin as an OBR • Soft dependency • DynamicImport-Package, optional service pattern, OptionalFeatureService and PluginDependencies, conditional UI elements • ...it’s a little harder. Join me over in IDEA

Editor's Notes

  • #2: \n
  • #3: Hey everyone, My name is James, I&apos;m a dev on the GreenHopper team and in the three and a half years I&apos;ve been at Atlassian, I&apos;ve worked almost exclusively on JIRA plugins - plugins are my bread and butter. \n
  • #4: So, we&amp;#x2019;re all developers of Alassian plugins, some of you write commercial plugins, like we on the GreenHopper team do. Some of you write plugins which just run on your company&amp;#x2019;s internal Atlassian product instances. And some of you do contracted customizations for all manner of other companies. But, we all write plugins and the plugins which we write will invariably run alongside other plugins - quite likely some written by other people in this room. This is the nature of developing for an ecosystem like that of Atlassian plugins.\n
  • #5: Where am I going with this? Well, I want us to all start exposing ourselves, in a rather public manner.\nBy which I mean: I want to see more of us plugin developers writing, exposing, documenting and supporting APIs which other plugin developers can then use to build integrations between their plugins and your own. I also want to encourage you to start building such integrations as well.\n
  • #6: Whatcha thinking? Sounds fine, right?\n
  • #7: You&amp;#x2019;re thinking: \n* APIs are hard, designing them is hard, implementing them in the OSGi-land which is Atlassian plugins sounds even harder.\n* Supporting and maintaining that? You&amp;#x2019;re kidding me.\n* And for all that effort, what do I get? If someone else uses my API that&apos;s their feature, not mine!\n\nAnswering each of these in order: \n* Certain knowledge is required to do this well, but that&amp;#x2019;s why we&amp;#x2019;re here - the GH team made mistakes, so that you don&amp;#x2019;t have to.\n* If you decouple your APIs well enough, write the right sort of tests and continue your regular CI practices, then there&amp;#x2019;s no extra ongoing costs.\n* Trust me: a well designed API that gets integrated with by many consumers is a feature in its own right.\n
  • #8: This isn&amp;#x2019;t all talk: we&amp;#x2019;ve really committed to this principle on the GH team - some of our real killer features have been a result of us exposing APIs, or have been achieved through us integrating with APIs exposed by other plugins. \n
  • #9: This isn&amp;#x2019;t all talk: we&amp;#x2019;ve really committed to this principle on the GH team - some of our real killer features have been a result of us exposing APIs, or have been achieved through us integrating with APIs exposed by other plugins. \n
  • #10: This isn&amp;#x2019;t all talk: we&amp;#x2019;ve really committed to this principle on the GH team - some of our real killer features have been a result of us exposing APIs, or have been achieved through us integrating with APIs exposed by other plugins. \n
  • #11: I&amp;#x2019;ll show you how GreenHopper users have benefited from us exposing APIs and integrating with other plugins.\nI&amp;#x2019;ll convince you, as plugin developers, to expose yourself through APIs and to integrate with other plugins which have exposed APIs.\nTowards the end, we&amp;#x2019;ll get into the nitty gritty technical details of how to build APIs in your Atlassian plugins, both at a design level and at an implementation level.\n
  • #12: So what have we been doing?\n
  • #13: We&amp;#x2019;ve written a new plugin - called pretty urls - which exposes a &lt;routing&gt; plugin module type to allow for much nicer urls for your plugin, as shown in this screenshot. GreenHopper now ships as an OSGi bundle repository (or OBR) which includes our minimum required version of pretty urls. This ensures that the other plugin is available, and that the API that it exposes is available for GreenHopper to consume. We wrote this as an API-exposing plugin (rather than as a feature in GreenHopper) so that other plugins can take advantage of it. Ideally, we will eventually get it added as a bundled plugin in JIRA.\n
  • #14: When GreenHopper first started working on the New GreenHopper (or Rapid Boards, as we were then calling them), we collaborated with the JIRA importers team in Poland to produce the Pivotal Tracker importer. This involved us building a number of Java API services:LabsConfiguration (so that the importer can ensure that the new GH labs feature was available), a RapidViewCreationService (for creating a new board for the newly imported issues) and later - a RankService to ensure that issues are imported in the same rank order as in Pivotal. \nThis last service was actually not developed specifically for this purpose - we developed it at the request of the Structure plugin developers, but after getting it in place, it became available for the importers plugin to use as well. When we develop an API for creating sprints in GreenHopper, then we fully expect the importers plugin to make use of it in their pivotal importer too.\n
  • #15: This has been my favourite integration to work on so far, and turned out to be the easiest to develop. In this case, we exposed an API for adding tabs to the issue detail view in the new GreenHopper. We&amp;#x2019;re all familiar with the atlassian-plugin &lt;web-panel&gt; tag? So this tag has a location attribute, we declared a new web-panel location &amp;#x201C;atl.gh.issue.details.tab&amp;#x201D;. Any plugin can now add an extra tab to the GreenHopper detail view, simply by adding a new web-panel, and adding any required JavaScript to the &amp;#x201C;gh-rapid&amp;#x201D; web-resource context. We currently have a small Javascript API for enabling these panels to integrate with the broader GH board.\n
  • #16: GreenHopper has a relatively new feature called sample data: on project and board creation, we offer to populate the new board with some sample issues, which are structured to provide an in-product tutorial. This feature relies on the JIRA importers plugin to actually create the issue. Again, we worked with the importers team in Poland to develop an API for creating issues (with history!) from a stream of JSON data. So none of this issue creation logic actually happens in GH - we just call out to an API service published by the importers plugin, (meaning we don&apos;t have to maintain or support that code).\nA nice side effect of this is that the team in Poland can now use this new service to improve their product based importers, none of which currently import history. Building a good API helped them to build a better product.\n
  • #17: This last example was one that I&amp;#x2019;ve been working on in my 20% time. Shortly after Atlassian acquired HipChat, one of my colleagues built this really nice JIRA plugin called HipChat for JIRA, which enabled users to set JIRA up to push notifications to HipChat rooms as a post function on workflow steps. Now this is great functionality, but it&amp;#x2019;s only really available to users who grok workflows and post functions AND have admin rights on their JIRA instance. I looked at this problem, and thought &amp;#x201C;Hey, GreenHopper&amp;#x2019;s column configuration is really just an abstraction layer over workflow - so if I could integrate with H4J, then users could just say &amp;#x201C;I want notifications when issues are moved into these columns on my board&amp;#x201D; - which enables this neat feature to a much wider range of users.\n
  • #18: Why did we build these? To answer that, we have to consider what the common aspects of these features are? \n* Well, in each case the API consumer got a feature for cheaper than they would have if they built it entirely by themselves.\n* The users get extra features simply because they have plugins X and Y installed. In the case where both plugins cost money, this is awesome - They&apos;ve spent money on one plugin to solve a specific problem, they decide to spend money on some other plugin to solve a seemingly unrelated problem and BAM! by the simple fact that they&apos;re using both plugins - they get something extra &apos;for free&apos;. \n* By having all these plugins which sit on top of JIRA integrate with one another, we make using JIRA feel much more cohesive - rather than having a number of siloed experiences which each integrate with JIRA, we have a fully integrated network of applications which are better together.\n
  • #19: Commercial devs - same as for the GH team, you lot are the easiest to convince - cheap features, better user experience.\nIn-house developers - 1 big monolithic plugin for your org means that if something goes wrong, your whole big-bank-jira-plugin comes down. If you can partition it into separate plugins which interact through well defined interfaces, then you can graceful degradation of just the integration features when things go wrong. Also, by making smaller code bases for more plugins, you can lower the barrier of entry to contribution.\nContract developers - As above, but also: reuse! You could build a customizations API plugin which contains the application logic - but not the business logic - for the kind of customizations that you often are asked to build. \n
  • #20: Convinced? Cool, well - in the remaining time, I&amp;#x2019;m going to show you how we get there.\n
  • #21: * Look for painpoints - I saw the JIRA hipchat plugin and thought: &quot;Such a cool feature, but as I described earlier - the barrier to entry is a little high.&amp;#x201D;\n* Look for redundancy between another plugin and yours. Remove it through integrating with the other plugin.\nWhen you see a problem for your users which needs solving, consider if some other plugin already solves a similar problem.\n* Similarly, if you want to build some feature which overlaps with something another plugin already does, then try to leverage the other plugin. This is what happened with GH sample data, we thought &amp;#x201C;Hmm... creating issues, that sounds like something the JIRA importers plugin already does&amp;#x201D;.\n* Look for a story where a user would be doing something through plugin X and logically wants to take their current context with them when they enter plugin Y - think of the Bonfire-GH integration story: A user has just completed development on a story, they transition it into awaiting QA in greenhopper and they want to start a test session. The bonfire tab in GH allows them to do exactly this - allowing them to interact with Bonfire, from their current context inside GreenHopper.\n
  • #22: * Don&amp;#x2019;t build in a vacuum, have at least one planned use case for every bit of API you build, to help focus what you&amp;#x2019;re building\n* Where it&amp;#x2019;s possible, consume your own API, rather than having duplicate internal and external API. Note: build the API first, then look to remove redundancy - to avoid tailoring your API to your internal usecase. Also, be aware of performance costs.\n* In addition to having third party consumers AND internal consumers, build a reference implementation for each part of your API. We do this by having a second plugin in our source tree - the greenhopper-client-plugin. This never gets released, and serves no purpose, but as a developer you notice very quickly that it goes missing.\n* Your API should be clearly separate from internal services - both for consumers and for internal developers. Make it hard to &amp;#x2018;accidentally&amp;#x2019; break API.\n* Where it makes sense, use atlassian-events for backend API, and JS events for front end.\n* Document your API, so people know to use it. Open source your reference client, so that people can easily see how to make it work.\nNote: some of you who consume GreenHopper API may be finding some of this advice a little amusing - yes, I said at the top that we have made mistakes so that you don&amp;#x2019;t have to. Some of this is a case of do as we say, not as we do.\n
  • #23: The plugin system already solves many problems for us, so leverage it wherever possible. \n\nImplicit in this slide: favour non-java API - \n
  • #24: Some of the eclipse folks have developed this fantastic guide to Java APIs. If you&amp;#x2019;re embarking on this path, read this, then reread it, then keep it open in a pinned browser tab and refer back to it in perpetuity.\n
  • #25: \n
  • #26: \n
  • #27: \n
  • #28: \n