Skip to content

Code Conventions

Levente Santha edited this page May 9, 2026 · 1 revision

Code Conventions

JNode coding standards, patterns, and anti-patterns. Follow these when contributing to maintain consistency across the ~3,300 Java source files.

Basics

Rule Detail
Java target 1.6 (no lambdas, no try-with-resources, no diamond operator, no multi-catch)
File encoding US-ASCII only
Formatter jnode-eclipse-formatter-settings.xml in repo root
License header LGPL 2.1, present in all source files

Java 1.6 Restrictions

Since JNode targets Java 1.6, do not use:

  • Lambda expressions (->)
  • Method references (Class::method)
  • Diamond operator (new ArrayList<>())
  • Try-with-resources (try (...))
  • Multi-catch (catch (A | B e))
  • String.isEmpty() is available (Java 1.6+) — prefer it over .length() == 0
  • @Override on interface methods (allowed only from Java 1.6+, use cautiously)
  • java.util.Objects (Java 1.7+)
  • java.nio.file package (Java 1.7+)

Annotation Patterns

JNode defines custom annotations that control JIT compiler and VM behavior. These are critical to understand:

VM Annotations (org.jnode.annotation)

Annotation Meaning
@Uninterruptible No GC safepoints, no thread switching. Use in kernel/scheduler code.
@KernelSpace Method runs in kernel privilege context
@Internal Not part of public API, may change without notice
@SharedStatics Static fields shared across all isolates (default: per-isolate)
@LoadStatics Re-initialize statics at boot time (vs. using build-time values)
@MagicPermission Class is allowed to use VmMagic / Unsafe operations
@PrivilegedActionPragma Method treated as a privileged action
@Inline Hint to JIT: inline this method
@NoInline Hint to JIT: never inline this method

VMagic Pragmas (org.vmmagic.pragma)

Pragma Meaning
UninterruptiblePragma Older style: throw in method body to mark as uninterruptible
InterruptiblePragma Override inherited uninterruptibility
InlinePragma Older style: throw to hint inlining
NoInlinePragma Older style: throw to prevent inlining
NoOptCompilePragma Skip optimization passes for this method

Prefer the @Annotation style over the pragma/exception style in new code.

VMagic Unboxed Types (org.vmmagic.unboxed)

These represent raw machine values that bypass the Java type system:

Type Represents
Address Raw memory address (pointer)
Offset Signed offset from an address
Word Machine-word-sized unsigned integer
Extent Unsigned size value
ObjectReference Raw object pointer

These are "unboxed" — they don't have object headers and can't be stored in Object variables. The JIT compiler handles them specially.

Naming Conventions

Pattern Usage
Vm prefix VM-internal classes (VmThread, VmSystem, VmProcessor)
Default prefix Standard implementations (DefaultPluginManager)
*Model suffix XML-parsed descriptor models (PluginDescriptorModel)
*Impl suffix Interface implementations (ResourceManagerImpl)
*Plugin suffix Plugin entry point classes (DMAPlugin)

Error Handling Patterns

In kernel / VM code

// Use Unsafe.debug() for output — System.out may not be ready
Unsafe.debug("Error: something went wrong\n");

In normal code

// Use BootLogInstance for early boot, Logger after initialization
BootLogInstance.get().error("Error message", exception);

Anti-patterns to avoid

  • Empty catch blocks — Always at minimum log the exception
  • e.printStackTrace() — Use proper logging instead
  • System.exit() — This halts the entire OS, not just your process

Service Registration

Services are registered via InitialNaming:

// Register
InitialNaming.bind(DeviceManager.NAME, deviceManager);

// Lookup
DeviceManager dm = InitialNaming.lookup(DeviceManager.NAME);

This is JNode's equivalent of a service locator / JNDI.

Resource Management

When working with hardware resources (I/O ports, IRQ, DMA, memory-mapped I/O):

// Always claim resources through ResourceManager
ResourceManager rm = InitialNaming.lookup(ResourceManager.NAME);
IOResource io = rm.claimIOResource(owner, startPort, length);
try {
    // use io
} finally {
    io.release();
}

Common Patterns

Plugin with Extension Point

public class MyPlugin extends Plugin {
    protected void startPlugin() throws PluginException {
        // Get extensions registered at our extension point
        ExtensionPoint ep = getDescriptor().getExtensionPoint("my-point");
        for (Extension ext : ep.getExtensions()) {
            // Process each extension
        }
    }
}

Driver Registration via Descriptor

<extension point="org.jnode.driver.bus.pci.device-factories">
    <device-factory class="com.example.MyDriver"/>
</extension>

Anti-Patterns

Don't Do Instead
new String(str) Just use str directly
str.length() == 0 str.isEmpty()
new Integer(x) Integer.valueOf(x)
catch (Exception e) {} At minimum log.error("...", e)
e.printStackTrace() Proper logging
synchronized in driver hot path Use ProcessorLock or SpinLock
Direct field access to VM internals Use facade interfaces

Related Pages

Clone this wiki locally