CommonLib abstraction layer, and two consumer modules (the Swing desktop viewer and the HTTP web server) discover available parsers at runtime through Java’s ServiceLoader mechanism. The result is a codebase with zero third-party runtime dependencies — only the JDK is required to run any part of the project.
Maven Module Structure
The rootpom.xml declares all sub-modules. Each module compiles to a single JAR and carries its own module-info.java descriptor.
CommonLib
CommonLib is the foundation that every other module builds on. It exports the org.binaryinternals.commonlib package and transitively re-exports java.desktop and java.logging so that format modules do not need to repeat those dependencies. Key types it provides:
FileFormat— abstract base class for all format parsers; holds the rawfileByteArrayand defines thegenerateTreeNodecontract.PluginDescriptor— service provider interface that theServiceLoaderdiscovers; maps file extensions to aFileFormatsubclass.PosDataInputStream— position-tracking byte reader built on top ofDataInputStream; exposesgetPos()for offset queries and little-endian read helpers.JTreeNodeFileComponent— value object attached to eachDefaultMutableTreeNode; carriesstartPos,length,text, optionalicon, and optional HTMLdescription.FileComponent— lightweightstartPos/lengthpair used by individual parsed fields inside a format module.GenerateTreeNode— interface for parsed sub-components that know how to add themselves to the tree.Icons— enum of all built-in node icons available to format parsers.
BinaryInternalsViewer
The desktop module (org.binaryinternals.app) declares uses org.binaryinternals.commonlib.PluginDescriptor in its module-info.java. At startup it calls ServiceLoader.load(PluginDescriptor.class) to obtain every format plugin on the module path, builds a file-extension filter from the results, and renders the parsed tree in a Swing JTree.
BinaryInternalsWeb
The web module (org.binaryinternals.web) follows exactly the same uses / ServiceLoader pattern. It embeds the JDK’s built-in com.sun.net.httpserver (via requires jdk.httpserver) to expose a REST API without pulling in any external web framework. ParseService wraps the ServiceLoader call and also converts the DefaultMutableTreeNode tree to JSON.
Dependency Flow
CommonLib. Neither the Viewer nor the Web module is listed as a dependency of any format module — the relationship is inverted through ServiceLoader.
Plugin Discovery via ServiceLoader
Each format module registers itself as aPluginDescriptor provider using the Java Platform Module System provides directive in module-info.java:
ServiceLoader.load(PluginDescriptor.class) returns one instance per provides directive found across all modules on the module path. Adding a new format to the application is therefore a matter of dropping the format JAR onto the module path — no code change is needed in the viewer or web server.
Data Flow
The path from raw bytes to a visible tree follows four steps:- Read — the file’s bytes are loaded into
FileFormat.fileByteArraythrough thePath-accepting constructor. - Parse — the
FileFormatsubclass reads fields from aPosDataInputStreamwrappingfileByteArray, populating typed Java fields. - Tree build —
generateTreeNode(DefaultMutableTreeNode parentNode)is called; the parser createsJTreeNodeFileComponentvalue objects and attaches them as child nodes. - Render or serialize — the Swing viewer displays the
DefaultMutableTreeNodetree directly, whileBinaryInternalsWeb’sParseService.toJson()walks the same tree and emits JSON.
icon and description fields are omitted when absent; children is omitted for leaf nodes.
Key Interfaces
Binary Internals carries zero third-party runtime dependencies beyond the JDK. The only compile-time-only dependency declared in the root POM is
spotbugs-annotations, which is scoped provided and declared requires static in module-info.java so it is never packaged into the distributed JARs.