The big idea of capabilities is that your access to the object is mediated through a proxy which does some computation on every call out to your object. Scala's support for call-by-name and lazy evaluation makes it straightforward to add object capabilities into the mix, but it's also possible to do this in Java, using only a supplier with a proxy.
Assume you have a
You can create a proxy implementation of Foo that will mediate access to the original:
Now that you have a supplier and a proxy, you can control access and audit calls to the original implementation:
This is the basis of object capabilities – code that uses
timeLimitedFoo has no way to execute methods on
fooImpl after a certain date. The caller's access is revoked.
The really nice thing about this is that it's all straightforward. There's no reflection, there's no code generation, there's no tricks. Setting up a proxy class is something that IntelliJ IDEA will do automatically if you use the "Delegate" action, and you're done in five minutes.
I've written a small project called ocapjsse that provides proxies for
SSLEngine. There are two sub-projects: one that handles logging, and another than handles revocation.
The logging subproject will take an individual key manager or trust manager, and print out method call access through SLF4J. It's a lightweight alternative to using the debugjsse provider because it's only on one instance, and can be tightly scoped.
The revocation sub-project adds a
Caretaker class that returns a proxied capability, and a
Revoker to shut off access through that proxy. You can use this to shut off credentials or a TLS connection whenever security guarantees are violated, or you may want to make double sure that an expired certificate can't be used incorrectly.
This code isn't published on Maven or Bintray yet, but I'm working on it.
Beyond the logging and revocation, you can do more powerful things like responsibility tracking and simulate latency and errors in your low level stack for a chaos monkey type check of your recovery code.
I hope this gives an idea of how simple and powerful object capabilities can be. This only really scratches the surface, but it shows how you can add behavior around an object from the outside without changing the internals.