-
Notifications
You must be signed in to change notification settings - Fork 0
InitialNaming Service Registry
InitialNamingis JNode's central service registry: a simple, type-keyed map used to bind and look up singleton OS services at runtime.
JNode has a lightweight service registry built on org.jnode.naming.InitialNaming. Rather than using JNDI strings as names, JNode uses Class objects as keys — this provides type-safe, refactor-friendly service lookups. Services are singleton objects (one per key) registered by plugins during boot and service startup.
The registry is initialized once during VmSystem.initialize() before any plugin code runs.
| File | Purpose |
|---|---|
org/jnode/naming/InitialNaming.java |
Static facade — the entry point for bind, lookup, unbind
|
org/jnode/naming/NameSpace.java |
Interface defining the contract: bind, unbind, lookup, nameSet
|
org/jnode/naming/AbstractNameSpace.java |
Base class handling listener dispatch; concrete subclasses implement the map |
org/jnode/naming/NameSpaceListener.java |
Observer interface: serviceBound(T), serviceUnbound(T)
|
org/jnode/vm/VmSystem.java:122 |
Initializes the namespace: InitialNaming.setNameSpace(new DefaultNameSpace())
|
At VmSystem.initialize() (line 122):
InitialNaming.setNameSpace(new DefaultNameSpace());setNameSpace can only be called once. A SecurityException is thrown on any subsequent call.
Plugins bind services by passing the service's interface Class and a singleton instance:
// From WorkPlugin.java:100
InitialNaming.bind(NAME, this); // NAME is WorkManager.class
// From DefaultPluginManager.java:77
InitialNaming.bind(NAME, this); // NAME is PluginManager.class
// From BootLogInstance.java:60
InitialNaming.bind(BootLog.class, bootLog);Only one service can be bound under a given Class key. Attempting to rebind throws NameAlreadyBoundException.
Any code can look up a registered service by its Class key:
// From WorkUtils.java:44
wm = InitialNaming.lookup(WorkManager.NAME);
// From VmIsolate.java:695
piManager = InitialNaming.lookup(PluginManager.NAME);
// Convenience in BootLogInstance.java
BootLog log = BootLogInstance.get(); // calls InitialNaming.lookup(BootLog.class) internallylookup throws NameNotFoundException if no service is bound under that Class.
NameSpaceListener<T> allows code to be notified when a service becomes available (or is removed). On registration, if the service is already bound, the listener is called immediately:
// From InitialNaming.java:57
public static <T> void addNameSpaceListener(Class<T> name, NameSpaceListener<T> l) {
NAME_SPACE.addNameSpaceListener(name, l);
}The AbstractNameSpace implementation handles the listener registry and fires callbacks when bind/unbind occurs. This is particularly useful for subsystems that depend on services that are initialized later.
InitialNaming.nameSet() returns all currently registered service keys (as a Set<Class<?>>). This can be used for introspection or debugging.
VmSystem.initialize()
→ InitialNaming.setNameSpace() // create the registry
→ BootLogImpl.initialize()
→ InitialNaming.bind(BootLog.class, bootLog)
→ DefaultPluginManager creation
→ InitialNaming.bind(PluginManager.class, pm)
→ [Plugins start, each bind their own services]
→ Other subsystems look up services as needed
Using Class objects as keys instead of strings:
- Type safety: The compiler verifies the return type at the call site
- No typos: Refactoring a class name automatically updates all lookups
- Single instance: Each service class has at most one singleton in the registry
- Impossible to guess: No string name collision issues
-
Once-only initialization:
setNameSpacecan only be called once. The namespace is effectively immutable after first boot. -
NameNotFoundException on missing service:
lookupfails if the service hasn't been bound yet. Services must be started in the correct dependency order. - No lazy instantiation: The registry holds direct object references. Lazy service creation must be implemented by the service itself.
-
No namespace hierarchy: Unlike JNDI, there is only a flat map of
Class→Object. No sub-contexts. -
Observer fires on add: When you call
addNameSpaceListener, if the service is already bound, your listener is called synchronously from withinaddNameSpaceListener.
- Architecture — System layers, package structure, subsystem interactions
- Plugin-System — How plugins and extensions work
- Boot-Sequence — GRUB → assembly → VM init → plugin startup
- Isolate-Implementation — Per-isolate static fields, dual-statics architecture