Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to write Bad Eclipse Plug-ins

alblue
September 16, 2015

How to write Bad Eclipse Plug-ins

Anyone can write an Eclipse Plug-in, but can they write a Bad Eclipse Plug-in? This talk, originally presented at Eclipse Night London in September 2015, takes a tongue-in-cheek view on how to write bad Eclipse plug-is by presenting a number of anti-patterns that can be used to degrade the Eclipse experience. See http://alblue.bandlem.com/2015/09/eclipse-night-london.html for more information.

alblue

September 16, 2015
Tweet

More Decks by alblue

Other Decks in Programming

Transcript

  1. How to Write Bad Eclipse Plug-ins Alex Blewitt @alblue Originally

    presented at Eclipse Night London 16 September 2015
  2. Bad Eclipse Plug-ins • This talk will present anti-patterns for


    Eclipse plug-in development • Use these techniques in order to degrade a user's experience of Eclipse • Bad plug-ins don't just happen by accident!
  3. Bad Eclipse Plug-ins • This talk will present anti-patterns for


    Eclipse plug-in development • Use these techniques in order to degrade a user's experience of Eclipse • Bad plug-ins don't just happen by accident!
  4. First impressions • First impressions last - make them count

    • Display a splash screen specifically for your plug-in • Otherwise how will they know what plug-in they have installed? • Use new Shell() and resize to size of window for maximum effect • Preferably whilst they're in the middle of something
  5. First impressions • First impressions last - make them count

    • Display a splash screen specifically for your plug-in • Otherwise how will they know what plug-in they have installed? • Use new Shell() and resize to size of window for maximum effect • Preferably whilst they're in the middle of something
  6. Have a Dialog with user • If a splash screen

    won't fit then consider a Dialog instead • For maximum benefit, show whilst typing – easier to accidentally press one of the buttons • Register a KeyListener on the SWT container to receive notifications of when they are typing
  7. Rentware • Dialogs are great for rentware • Remind the

    user to pay up or the software will stop working • Allow the dialog to be dismissed, but come back • Bonus points for having it in a different place • Punch the Money!
  8. Rentware • Dialogs are great for rentware • Remind the

    user to pay up or the software will stop working • Allow the dialog to be dismissed, but come back • Bonus points for having it in a different place • Punch the Money!
  9. Rentware • Dialogs are great for rentware • Remind the

    user to pay up or the software will stop working • Allow the dialog to be dismissed, but come back • Bonus points for having it in a different place • Punch the Money!
  10. Rentware • Dialogs are great for rentware • Remind the

    user to pay up or the software will stop working • Allow the dialog to be dismissed, but come back • Bonus points for having it in a different place • Punch the Money!
  11. Interactive dialog • Dialogs can be interactive too • Why

    not add a payment field into the dialog? • Take a credit card number • Add a field listener to validate number; use the LUHN check to determine if card is valid • Enable payment button when valid
  12. Interactive dialog • Dialogs can be interactive too • Why

    not add a payment field into the dialog? • Take a credit card number • Add a field listener to validate number; use the LUHN check to determine if card is valid • Enable payment button when valid
  13. Interactive dialog • Dialogs can be interactive too • Why

    not add a payment field into the dialog? • Take a credit card number • Add a field listener to validate number; use the LUHN check to determine if card is valid • Enable payment button when valid
  14. Notifications • Another option is to use Mylyn Notifications •

    Pop-up dialogs in bottom right of screen • Problems with this approach • Notification goes away after inactivity • User doesn't get distracted • Limited click-through conversion rate!
  15. Combine them! • Splash screen AND field input • What's

    not to like? • Use them to unlock functionality • Good way of populating marketing lists
  16. Combine them! • Splash screen AND field input • What's

    not to like? • Use them to unlock functionality • Good way of populating marketing lists
  17. Assume the Networks • Only successful people use Eclipse •

    Clearly they can afford in-flight WiFi ✈ • If their computer isn't connected, it's their fault • Make sure to log lots of errors (or just fail) • Automated Error Reporter is lonely • Who uses firewalls anyway? ⛔
  18. On the Job – the UIJob • Your plug-in is

    the most important plug-in the user has installed • Instead of running a Job in the background, use UIJob instead • Especially if using the filesystem or network • Everyone loves the beachball!
  19. Reporting Progress • IProgressMonitor allows progress to be reported •

    Can avoid giving any hints by avoiding setting amount of work - use UNKNOWN (-1) • Ignore cancellations • Pretty animations!
  20. Bundle Activator • Bundle-Activator is an opportunity for delays •

    Eclipse start-up is serial activation of activators • Single bundle can take down Eclipse! • Thread.sleep(1000000…) • Even if bundle does nothing useful, leave the Activator in there – shows you used a template
  21. Bundle Activator • Bundle-Activator is an opportunity for delays •

    Eclipse start-up is serial activation of activators • Single bundle can take down Eclipse! • Thread.sleep(1000000…) • Even if bundle does nothing useful, leave the Activator in there – shows you used a template 258 classes out of 762 bundles can't be wrong!
  22. Activators are the • When you reference a class from

    a bundle it triggers activation automatically if the following: • Bundle-ActivationPolicy: lazy • Referring to a class is enough to cause delays! • Useful in combination with static blocks
  23. Activators are the • When you reference a class from

    a bundle it triggers activation automatically if the following: • Bundle-ActivationPolicy: lazy • Referring to a class is enough to cause delays! • Useful in combination with static blocks static { ImageDescriptor img = … JFaceResources. getImageRegistry(). put(…,img) } Added 100k+ to application load by triggering ImageRegistry creation
  24. Laziness is overrated • Why be lazy when you can

    be active? • Better to be fit • IStartup provides ultimate active extension • earlyStartup() – use resources actively at start • Use UIJob().schedule(0) for immediate effect • Don't use declarative services – multi threaded
  25. IInterface and IImplementation • Eclipse ❤ Iinterfaces • Put IInterface

    and IImplementation in same bundle so they won't get lost • Bonus: refer to the interface, activate the bundle! • Ensure you always cast the interface to hidden internal implementation class to prevent reuse!
  26. IInterface2 • Even better, interfaces can be versioned! • IInterface2

    • IInterface3 • IInterface4 • IInterface∞ ! ! Never delete code! Never revoke an API! If it was good enough for Eclipse 2.1 then it is good enough for you!
  27. Avoid new-fangled code • Most Eclipse APIs don't use generics

    – 
 why should you? • Avoid new annotations like @Inject and @EventTopic – these aren't yet decades old • Why use command and handler when Action is still used by the platform?
  28. Graphics Leaks • SWT is a great library for being

    able to leak resources • ERROR_NO_HANDLES • Just forget to call dispose() on your Resource • Don't use: • ImageRegistry, ColorRegistry, FontRegistry • Sleak, SWTBot
  29. Summary • Use splash screens, dialogs and interruptions • Rentware

    is highly popular • Assume the network is always available • Use UIJob instead of Job to block the interface • Don't estimate progress; or check for cancel
  30. Summary • Put all your complex logic in Bundle Activators

    • Run tasks in IStartup with zero delay for priority • Use static blocks of code to avoid lazy code • Mix interface & implementation in same bundle • Avoid declarative services, @Inject, commands