Source files & packages
This chapter explains the structure of the JNode source tree and the JNode package structure.
Directory structure
The JNode sources are divided into the following groups:
- all
Contains the global libraries, the (Ant) build files and some configuration files. This group does not contain java sources.
- builder
Contains the java source code used to build JNode. This includes several Ant tasks, but also code used to link Elf files and to write the JNode bootimage.
- core
Contains the JNode virtual machine code (both java and assembler), the classpath java library sources and the core of the JNode operating system, including the plugin manager, the driver framework, the resource manager and the security manager. This is by far the largest and most complex group.
- distr
Contains the first parts of the JNode distribution. This includes an installation program and various applications.
- fs
Contains the file system framework, the various file system implementation and the block drivers such as the IDE driver, harddisk driver, CD-ROM etc.
- gui
Contains the JNode gui implementation. This includes the graphics drivers, the AWT peer implementation, font renderers and the JNode desktop.
- net
Contains the JNode network layer. This includes the network drivers, the network framework, the TCP/IP stack and the connection between the network layer and the java.net package.
- shell
Contains the JNode command shell and several system shell commands.
- textui
Contains a copy of the charva text based AWT implementation.
- cli
Contains the bulk of JNode's commands.
Every group is a directory below the root of the JNode CVS archive. Every group contains one or more standard directories.
- build
This directory is created during the build and contains the intermediate build results.
- descriptors
This directory contains the plugin descriptors of the plugins defined in this group.
- lib
This directory contains libraries (jar files) required only by this group. An exception is the All group, for which the lib directory contains libraries used by all groups.
- src
This directory contains the source files. Below this directory there are one or more source directories (source folders in Eclipse) containing the actual source trees.
JNode coding DOs and DONTs
This page lists some tips on how to write good JNode code.
Please add other tips as required.
- Avoid using System.in, System.out, System.err
- Where possible, avoid using these three variables. The problem is that they are global to the current isolate, and are not necessarily connected to the place that you expect them to be.
In a user-level command should use streams provided by the Command API; e.g. by calling the 'getInput()' method from within the command's 'execute' method. Device drivers, services and so on that do not have access to these streams should use log4j logging.
- Avoid cluttering up the console with obscure or unnecessary logging
- If a message is important enough to be written to the console, it should be self explanatory. If it is unimportant, it should be logged using log4j at an appropriate level. We really do not need to see console messages left over from someone's attempts to debug something 12 months ago ...
- Avoid using Unsafe.debug(...) methods
- The org.jnode.vm.Unsafe.debug(...) methods write to the VGA screen and (when kernel debug is enabled) to the serial port. This is ugly, and should be reserved for important early boot sequence logging, VM and GC debugging, and other situations where log4j logging cannot be used.
- Don't call 'Throwable.printStackTrace' and friends
- Commands should allow unexpected exceptions to propagate to the shell level where they are handled according to the user's setting of the 'jnode.debug' property. (The alternative of adding a "--debug" flag to each command, is a bad idea. It is a lot of work and will tend to lead to inconsistencies of implementation; e.g. commands that don't implement "--debug", send "--debug" output to unexpected places, overload other functionality on the flag, etcetera.)
Services, etc should make appropriate log4j calls, passing the offending Throwable as an argument.
- Do use JNode's Command and syntax.* APIs for commands
- Commands that are implemented using the Command and syntax.* APIs support completion and help, and are more likely to behave "normally"; e.g. with respect to stream redirection. There are lots of examples in the codebase.
If the APIs don't do what you want, raise an issue. Bear in mind that some requests may be deemed to be "to hard", or to application specific.
- Do include a 'main' entry point.
- It is a good idea to include a legacy "public static void main(String[])" entry point in each JNode command. This is currently only used by the old "default" command invoker, but in the future it may be used to run the command in a classic JVM.
- Don't use '\n\r' or '\r\n" in output.
- The line separator on JNode is '\n', like on UNIX / Linux. If you expect your command to only run on JNode, it is not unreasonable to hardwire '\n' in output messages, etc. But if you want your command to be portable, it should use 'System.getProperty("line.separator")', or one of the PrintWriter / PrintStream's 'println' methods.
JNode Java style rules
All code that is developed as part of the JNode project must conform to the style set out in Sun's "Java Style Guidelines" (JSG) with variations and exceptions listed below. Javadocs are also important, so please try to make an effort to make them accurate and comprehensive.
Note that we use CheckStyle 4.4 as our arbiter for Java style correctness. Run "./build.sh checkstyle" to check your code style before checking it in or submitting it as a patch. UPDATE: And also, please run "./build.sh javadoc" to make sure that you haven't introduced any new javadoc warnings.
- No TAB characters.
- No TAB characters (HT or VT) are allowed in JNode Java source code.
Whitespace TABs should be replaced with the requisite number of spaces or newlines. Non-whitespace TABs (i.e. in Java strings) should be replaced with "\t" or "\f" escape sequences.
- Use 4 space indentation.
- Two or three characters is too little, eight is too much.
- Maximum line width 120.
- The JSG recommends 80 characters, but most people use tools that can cope with much wider.
- Put following keywords on same line as }
-
For example:
try {
if (condition) {
something();
} else {
somethingElse();
}
} catch (Exception ex) {
return 42;
}
Note that the else is on the same line as the preceding }, as is the catch.
- Indent labels by -4.
- For example:
public void loopy() {
int i;
LOOP:
for (i = 100; i < 1000000; i++) {
if (isPrime(i) && isPrime(i + 3) && isPrime(i + 5) {
break LOOP;
}
}
}
- No empty { } blocks
- A { } block with no code should contain a comment to say why the block is empty. For example,
try {
myStream.close();
} catch (IOException ex) {
// we can safely ignore this
}
- No marker comments
- It is generally accepted that marker comments (like the following) add little to the readability of a program. In fact, most programmers think they are an eyesore and a waste of space.
//*******************************************************
//
// Start of private methods
//
//*******************************************************
- Avoid copying javadoc
- Instead of copying the javadoc from the parent class or method, use the {@inheritDoc} tag and if needed add some specific javadoc.
/**
* {@inheritDoc}
*/
public void myMethod(String param1, int param2) {
}
- Give your references in the javadoc
- When you are implementing a class from a reference document, add a link in the javadoc.
Packages
The java classes of JNode are organized using the following package structure.
Note that not all packages are listed, but only the most important. For a full list, refer to the javadoc documentation.
All packages start with org.jnode.
Common packages
- org.jnode.boot
Contains the first classes that run once JNode is booted. These classes initialize the virtual machine and start the operating system.
- org.jnode.plugin
Contains the interfaces of the plugin manager.
- org.jnode.util
Contains frequently used utility classes.
- org.jnode.protocol
Contains the protocol handlers for the various (URL) protocols implemented by JNode. Every protocol maps onto a package below this package, e.g. the plugin protocol handler is implemented in org.jnode.protocol.plugin.
JNode virtual machine
- org.jnode.vm
Contains the core classes of the JNode virtual machine.
- org.jnode.vm.classmgr
Contains the internal classes that represent java classes, methods & field. It also contains the classfile decoder.
- org.jnode.vm.compiler
Contains the base classes for the native code compilers that convert java bytecodes into native code for a specific platform.
- org.jnode.vm.memmgr
Contains the java heap manager, including the object allocator and the garbage collector.
- org.jnode.vm.<arch>
For every architecture that is supported by JNode a seperate package exists, that contains the architecture dependent classes, including classes for threads and processors and classes for the native code compilation.
JNode operating system
- org.jnode.driver
Contains the driver framework.
All drivers and driver API's have a seperate package below this package. Drivers of a similar type are grouped, e.g. all video drivers have a package below org.jnode.driver.video.
- org.jnode.system
Contains the interfaces for the various low level resources in the system, such as memory regions, I/O port regions, DMA access.
- org.jnode.fs
Contains the filesystem framework.
All file systems have a seperate package below this package, e.g. the EXT2 filesystem implementation is contained in the org.jnode.fs.ext2 package and its sub-packages.
- org.jnode.net
Contains the network layer.
All network protocols have a seperate package below this package, e.g. the IPv4 protocol and its sub-protocols is contained in the org.jnode.net.ipv4 package and its sub-packages.
- org.jnode.shell
Contains the command shell.
All system commands are grouped in packages below this package.
Special packages
There are some packages that do not comply to the rule that all packages start with org.jnode. These are:
- java.*, javax.*
Contains the classpath implementation of the standard java libraries.
- gnu.*
Contains implementation classes of the the classpath library.
- org.vmmagic.pragma
Contains exception classes and interfaces that have special meaning to the virtual machine and especially the native code compilers. These classes are mostly shared with the Jikes RVM
- org.vmmagic.unboxed
Contains non-normal classes that are used as pointers to raw memory, object references and architecture dependent integers (words). These classes have a special meaning to the virtual machine and especially the native code compilers and should never be instantiated or used without a good knowledge of their meaning. These classes are mostly shared with the Jikes RVM
Source file requirements
Header
All java source files must contain the standard JNode header found in <jnode>/all/template/header.txt.
Do not add extra information to the header, since this header is updated automatically, at which time these extra pieces of information are lots.
Add any extra information about the class to the classes javadoc comment. If you make significant contribution to a class, feel free to add yourself as an @author. However, adding a personal copyright notice is "bad form", and unnecessary from the standpoint of copyright law. (If you are not comfortable with this, please don't contribute code to the project.)
Encoding
All Java source files and other text-based files in the JNode project must be US-ASCII encoded. This means that extended characters in Java code must be encoded in the '\uxxxx' form. Lines should end with an ASCII linefeed (LF) character, not CR LF or LF CR, and hard tab (HT) characters should not be used.
If there is a pressing need to break these rules in some configuration or regression data file, we can make an exception. However, it is advisable to highlight the use of "nasty" characters (e.g. as comments in the file) so that someone doesn't accidentally "fix" them.