In the not-too-distant past, engineers who wrote device drivers, operating systems, and other systemlevel software did most of their work in assembly. Today, those same engineers use C&#151even though hand-tuned assembly can still run faster and smaller than the code generated by many C compilers. So why the change? Because experience has shown that the portability, speed of development, and builtin runtime support (the C Standard Library) of C far outweigh the relatively small cost of using it. As it turns out, much the same can be said for Java. In fact, system-level software written in Java can offer an even better cost-benefit ratio, making Java a viable language for both current and future embedded designs. In this paper, we walk through the steps of writing a device driver in Java, from hardware initialization to client interfacing. We also address key issues, such as realtime performance and portability, and identify which types of applications benefit the most from Java device drivers.