42575

How to create a wrapper for a large interface

Question:

I want to create a wrapper that traps a particular exception and retries for all methods in a large (100+ methods) interface. I have the retry code working no worries, but I can't figure out how to hook up an implementation of the interface without cut'n'paste into all the methods.

I tried to use a missing method handler but that meant that I couldn't have it implement the interface. Abstract is obviously out as I won't be able to instantiate it.

I'm hoping for a better solution than creating the class as a template on the fly but I'm willing to do that.

Answer1:

Have you tried overriding invokeMethod for the interface?

YourInterface.metaClass.invokeMethod = {String name, args -> def result println "Calling method $name" try{ result = metaClass.getMetaMethod(name, args).invoke(delegate, args) }catch(YourException | AnyOtherException | Exception e){ println "Handling exception for method $name" result = //Call retry code here } println "Called method $name" result }

Overriding invokeMethod works as as interceptor for all the method calls in the interface. Handle the exception for each method and return the success result.

Answer2:

I tried to use @dmahapatro's example but I kept getting IllegalArgumentException. I eventually realised that it only happened for mixin methods (the method shows the signature of the mixin). Instead of invoke() I needed to use doMethodInvoke() to get the appropriate type coersion.

errorProneInstance.metaClass.invokeMethod = { String name, args -> def result def method = delegate.metaClass.getMetaMethod(name, args) while(true) { try { result = method.doMethodInvoke(delegate, args) break } catch (AnnoyingIntermittentButRetryableException e) { print "ignoring exception" } } result }

Recommend

  • JPS useBean with HashMap
  • Cannot instantiate the type Image java?
  • SQL Server Integrated Security from an Azure Web Site
  • Furthest-point Voronoi diagram in Java
  • How to initialize context? [closed]
  • How to override __call__ in celery on main?
  • What is the reason that Policy.getPolicy() is considered as it will retain a static reference to the
  • Merge Module leaving files during uninstall
  • Android onKey w/ virtual keyboard
  • Adding a model to a Marionette CollectionView's collection doesn't trigger onItemAdd callb
  • NSIS decompiler
  • Magento site down due to mysql error General error: 1030 Got error -1 from storage engine
  • How to 'create temp table as select' in Slick?
  • How load cv2.KeyPoint and Descriptors correctly on OpenCV 3 with Python 3?
  • Redirect STDERR in OPEN pipe comand. Perl Linux
  • calculate gradient output for Theta update rule
  • Django simple Captcha “No module named fields” error
  • Detect when Facebook like button is clicked
  • AJAX Html Editor Extender upload image appearing blank
  • Paperclip, set path outside of rails root folder
  • Initializer list vs. initialization method
  • Control modification in presentation layer
  • Projection media query: browser support and workarounds?
  • Sails.js/waterline: Executing waterline queries in toJSON function of a model?
  • Getting last autonumber in access
  • Fetching methods from BroadcastReceiver to update UI
  • C# - Serializing and deserializing static member
  • Is there a amazon webstore API for customers?
  • Bug in WPF DataGrid
  • Excel - Autoshape get it's name from cell (value)
  • Incrementing object id automatically JS constructor (static method and variable)
  • Check if a string to interpolate provides expected placeholders
  • Do create extension work in single-user mode in postgres?
  • RestKit - RKRequestDelegate does not exist
  • Traverse Array and Display in markup
  • Java static initializers and reflection
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • unknown Exception android
  • Observable and ngFor in Angular 2
  • Unable to use reactive element in my shiny app