nuggets is (yet another) utility library for Java. nuggets is a sharp tool - it is you who uses it for good or for evil. nuggets is rubber gloves for those of us who need to dig deep in shitty codebases. nuggets is an experiment in transgressing the one-size-fits-all rules of thumb of "Effective Java". nuggets strives to maximize the functionality-to-code ratio, by providing a composable basis set of well chosen primitives, rather than catering explicitly for every usage scenario. nuggets is an aesthetic exercise - from the Javadoc stylesheet, to the choice of infrastructure, I tinker and experiment until the result pleases me.
Below is a list of features, see the javadocs for detailed documentation, browse the sources at sourcegraph.
Exceptions
- utils for dealing with checked exceptions
and huge stacktraces
Extractors
- reflection utils
peek
and poke
to a private or final fieldinvokeMethod
to invoke any method with minimum ceremony false
, or null
)Object
last orderTextTable
- formats complex data in logs, stdout and file reports
Appendable
object (StringBuilder
, Writer
, etc.)Functions
- utilities for lambdas and java.util.function
objects
toString()
fallback()
combinator, trying multiple functions until the
result matches a predicate and/or no exception is thrown. Nice error
reporting.retry()
decorator void
functions in non-void contextPorts
implement a block-based port allocation pattern, useful for integration tests
System.getProperties()
)UrlStreamHandlers
provides base classes and utilities to easily incorporate
data URLs and custom resource-based URL handlers into any application.
Threads
allows to introspect running threads, thread-groups and runnables.
ReflectionProxy
is a convenient way to perform a series of reflective
accesses, starting from an object. Invaluable for all these cases where you
need to monkey-patch a vendor class (especially powerful when combined with
Threads
to get access to the runnable of another thread).
Special Groovy API
Extractors
as Groovy category
to decorate any object with peekField()/pokeField()
, which can be used access private or
final fields as in this example: foobar.peekField('finalField', Integer)
java.lang.Class
will gain peekField()/pokeField()
as
extension methods
that can be used to access static private or final fields - i.e.
SomeClass.pokeField('someFinalField', newValue)
closure.named('name')
to decorate Closures with human-readable toString()
DelegatedClosure
when you want to write a decorator intercepting a
method or two of a wrapped closure.Ports
supports array-like indexing to get ports by ID (i.e. one can write
ports['http']
), as well as DSL configuration such as:
def ports = Ports.continuousBlock(10) // easy config for default setup
ports.withPortSpec(5000) { // easy registration
id "foo"
id "bar" offset 1
id "baz"
}
Threads
allows access to the runnable of threads with unique name within the scope by using
square-brackets notation - i.e. threadPool['worker-thread-1']
ReflectionProxy
allows the usage of square brackets to
access fields, as well as specify resolution type for shadowed fields.
For example, if a private field foo
is declared in both Parent
and Child
you can access te parent's foo
from a child instance by doing
childProxy[Parent]['foo']
.reflectionDsl()
method which allows to use the ReflectionProxy
in more idiomatic way. Just call the methods and access the fields as properties.
Use square brackets to specify a resolution type. I.e. the above example would translate to
chieldProxyDsl[Parent].foo
Special Kotlin API
throwable.transform {...}
extension method. Added few extension methods to the transform builder.clazz.peek/pokeStaticField(...)
and instance.peek/pokeField(...)
col(name) { ... }
extension method for more natural config
of a table column. Ports
supports array-like indexing to get ports by ID (i.e. one can write
ports['http']
), as well as DSL configuration such as:
def ports = portsBlock(10) // easy config for default setup
ports.withPorts(5000) { reserve -> // easy registration
reserve port "foo"
reserve port "bar" at 5
reserve port "baz"
}
@Inject
, Groovy
and Kotlin
if they happen to be on the class pathProGuard
. accessible
bit on fields
and methods. As usual, if you are using security manager you need to do your testing.