Skip to content

Thread Introspection, Reflection Proxy, Retry, Data and Classpath URLs

Compare
Choose a tag to compare
@ddimtirov ddimtirov released this 26 May 14:58
· 20 commits to master since this release
v0.4.0

This release delivers 4 small features - while not related, they are especially useful if you are hacking legacy code or doing whitebox testing.

The Threads class is a wraps a Java ThreadGroup and provides convenient access its contained Threads or the actual Runnable instances that do the work. This, combined with reflection allows to get access to the internals of servers and messaging frameworks, or could be just useful to monitor for leaked threads. The API also allows conveniently to navigate to parent and child thread-groups starting from main or the thread group of the current thread.

ReflectionProxy complements the Threads class, by providing convenient way to apply a series of reflective operations on an object graph. Here is a combined example, changing timeout field of a hypothetical server.

Runnable acceptor = Threads.getAllThreads().getWithUniqueName("Acceptor-Thread");
ReflectionProxy.wrap(acceptor).get("reactor").get("config").set("timeout", 100_000);

Another useful feature for concurrent testing is being able to retry until success. This is achieved by Functions.retry(). While concept is similar to Spock's PollingConditions, the main difference is that Functions.retry() is reentrant.

By reentrant, we mean that you may write a method foo using retry() and later call foo from the retry() body in method bar. A naive implementation would spin in foo until it times out, effectively causing priority inversion. This is exacerbated when used in architectures such as agent-based systems. Functions.retry() only spins at the top-level, of the stack with any reentrant calls being treated as pass-through.

In addition, Functions.retry() can come handy outside of testing too - i.e. for handling unavoidable races. It is robust, allows for busy-waiting before sleeping, and handles interruption well.

Finally, the UrlStreamHandlers provides base classes that can be used to add support for Data URLs, Classpath URLs, or custom schemas translating to supported URL types (i.e. one may implement a handler translating config:connection/http/port to file:config/connection.xml and delegating the resolution to it).

See also bintray version, javadocs at Sonatype or on javadocs.io (in case OSSRH is unavailable)