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- rethrow checked exception as unchecked
- convert throwing functional interfaces into non-throwing counterparts
- enable the usage of throwing methods in not-throwing lambdas
- enrich exception message without wrapping it
- cleanup exception stacktrace, causes and suppressed exceptions
- preset stack transformer that works for many situations
- preset stack transformers for Groovy MOP, Java Reflection, etc.
- stack transformer to get rid of some parasitic stackframes in Groovy
- dump an exception stacktrace to multi-line string and parse it back
-
Extractors- reflection utilspeekandpoketo a private or final fieldinvokeMethodto invoke any method with minimum ceremony- convert between wrapper and primitive classes
- create a default value for type (no-args constructor, zero,
false, ornull) - safely load potentially missing classes (useful for plugins and optional functionality)
- dependency injection primitives (roll your custom DI injector in few lines)
- type linearization - walk the class inheritance tree in concrete first, then breadth
first,
Objectlast order - iterator through all constructors, fields or methods (including private inherited)
-
TextTable- formats complex data in logs, stdout and file reports- rendering to any
Appendableobject (StringBuilder,Writer, etc.) - alignment, padding, right-hand border and custom formatting per cell or column
- default values for optional column
- extensible visual styles for frames, borders, separators, headers
- row-group separators
- each cell can contain multi-line strings
- virtual calculated columns, based on row and column siblings
- hiden columns, holding data used by calcolations, but not rendered
- rendering to any
-
Functions- utilities for lambdas andjava.util.functionobjects- decorate lambdas and functional objects with human-readable
toString() - flexible
fallback()combinator, trying multiple functions until the result matches a predicate and/or no exception is thrown. Nice error reporting. - composable reentrant
retry()decorator - factory for utility function objects allowing to intercept function objects before/after call
- adaptors allowing to use
voidfunctions in non-void context
- decorate lambdas and functional objects with human-readable
-
Portsimplement a block-based port allocation pattern, useful for integration tests- clean, simple and extensible API
- hook to customize the actual allocation algorithm.
- hooks to validate and export the allocated ports to custom config mechanism
(i.e. generate config files, or update
System.getProperties())
-
UrlStreamHandlersprovides base classes and utilities to easily incorporate data URLs and custom resource-based URL handlers into any application. -
Threadsallows to introspect running threads, thread-groups and runnables. -
ReflectionProxyis 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 withThreadsto get access to the runnable of another thread). -
Special Groovy API
- Use
Extractorsas Groovy category to decorate any object withpeekField()/pokeField(), which can be used access private or final fields as in this example:foobar.peekField('finalField', Integer) - Any
java.lang.Classwill gainpeekField()/pokeField()as extension methods that can be used to access static private or final fields - i.e.SomeClass.pokeField('someFinalField', newValue) - Use
closure.named('name')to decorate Closures with human-readabletoString() - Use
DelegatedClosurewhen you want to write a decorator intercepting a method or two of a wrapped closure. Portssupports array-like indexing to get ports by ID (i.e. one can writeports['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" }Threadsallows access to the runnable of threads with unique name within the scope by using square-brackets notation - i.e.threadPool['worker-thread-1']ReflectionProxyallows the usage of square brackets to access fields, as well as specify resolution type for shadowed fields. For example, if a private fieldfoois declared in bothParentandChildyou can access te parent'sfoofrom a child instance by doingchildProxy[Parent]['foo'].- Each object gets an extra
reflectionDsl()method which allows to use theReflectionProxyin 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 tochieldProxyDsl[Parent].foo
- Use
-
Special Kotlin API
- Transform Exceptions in more natural way, by adding
throwable.transform {...}extension method. Added few extension methods to the transform builder. - Access encapsulated fields by using
clazz.peek/pokeStaticField(...)andinstance.peek/pokeField(...) - Added
col(name) { ... }extension method for more natural config of a table column. Portssupports array-like indexing to get ports by ID (i.e. one can writeports['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" }
- Transform Exceptions in more natural way, by adding
- Fat-jar friendly (don't add yet another jar to your distribution)
- no 3rd party dependencies at runtime
- some optional features take advantage of
@Inject,GroovyandKotlinif they happen to be on the class path - all components are designed with dependencies in mind, making it trivial
to strip the parts you don't use with something like
ProGuard.
- high quality testing and javadoc
- tested on OS X, Windows and Linux
- code quality checked by Findbugs, Checkstyle and Coverity
- test coverage tracked by Codecov
- Codacy dashboard tracks multiple metrics over time
- annotated with the JetBrains annotations (helps if you use IntelliJ IDEA)
- the naming of static methods is chosen to be easily recognizable, yet reduce the chance of clashing when imported statically.
- The performance should be reasonable, though that is not a requirement for now.
- Most of the classes are thread-safe, and thread safety and threading policies are documented in the class and method Javadoc.
- Many of the classes are abusing reflection to flip the
accessiblebit on fields and methods. As usual, if you are using security manager you need to do your testing.