< Zurück | Inhalt | Weiter >

Chapter 7

The GNU Compiler for Java (gcj)


The GNU Compiler for Java provides a native binary compiler for Java code. In this chapter we’ll show you how to compile a simple binary application from Java sources.



You will learn how to compile a binary executable from Java source code using the gcj compiler.


Quite some time ago Richard Stallman started an effort to create a free version of UNIX called GNU1 (which stands for GNU’s Not UNIX—a recursive


1. http://www.gnu.org/


acronym). More than that, he tried to convince the world that code should be Free with a capital “F”. By this, he meant that it was unreasonable to provide software without both providing the source code and the right to use and modify that code as desired. To ensure this, he and his team created the GPL2 (the GNU Public License) and founded the Free Software Foundation3 to foster development and promote the idea.

The story of the founding of GNU/FSF and the motivations behind it4 makes for a fascinating reading. Even if you are not interested in Free Software, the story prompts you to think in new ways about software, property, and freedom. As interesting as this story is, it is not our topic. The important thing is how the quest to create a Free operating system lead to a native Java compiler and the twists and turns on this way.


If you are going to write a UNIX-like operating system, and one that is “Free” (certainly free of anyone else’s intellectual property which might be restricted from the Free Software point of view), the first thing you need is a C compiler. Thus, a great deal of early effort by the FSF went into developing what was originally called the GNU C Compiler, or gcc.

Once they had a C compiler, some people began to write hundreds of utilities from ls to grep, while others began work on HURD, a microkernel for GNU. That work continues to this day. The bulk of the system commands you use on Linux were in fact developed by the FSF as part of the GNU project. This is why Stallman et al. want us all to refer to “GNU/Linux” rather than “Linux”.5 An understandable, if unenforceable, position.

It wasn’t long before an effort began to integrate C++ into gcc. As time progressed, support for more and more languages and for more and more


2. http://www.gnu.org/licenses/gpl.php

3. http://www.fsf.org/

4. http://www.gnu.org/gnu/thegnuproject.php

5. A viewpoint we understand and appreciate, but we do not bow to is that we must always say “GNU/Linux.” We say it sometimes, but it gets tedious and annoying if used all the time. So we compromise. We tell you about GNU, but we’ll usually say just “Linux” in the text.

architectures6 was being added. At some point, it was decided to rename (reacronym?) gcc to mean “GNU Compiler Collection.”

Not too surprisingly, as Java emerged and gained popularity, it became one of the languages supported by the GCC using a front end called gcj.7 That is what we’ll be talking about here.


The basic form of gcj is

gcj [options...] [codefile...] [@listfile...] [libraryfile...]

We’ll go over the options in a moment. For now, let’s talk about the various kinds of input files the compiler can process.

In the above command-line synopsis, codefile refers to a Java source file, a compiled .class file (yes, gcj can convert already compiled Java byte- codes into native binaries), or even a ZIP or JAR file. A filename prefixed with the at-sign, @, indicates that the file contains a list of filenames to be compiled. That’s the @listfile entry in the command synopsis. Finally, zero or more library files to link with may be specified on the command line. When you specify them directly (as opposed to using the -l command-line option) you must provide the full name of the library.

Like all the other Java compilers we have talked about so far, gcj supports the notion of a classpath. It will look in the classpath for unknown classes refer- enced by the classes you name to the compiler. Since gcj can read and compile from .class and .jar files, you might think you could just make sure that the JAR files from Sun or IBM Java SDK are on the gcj classpath and you would be able to compile any Java program using any Java APIs. Alas, you would be wrong. Why? Because the Java APIs are full of native methods, and which methods are implemented in Java and which are native is not documented anywhere.


6. A lot of people do not realize this, but gcc is a cross-compiler. Precompiled binaries do not always support this, but if you build your compiler from source, you can use gcc to compile code for any supported platform. For example, you can compile a program for a PowerPC-based Macintosh on your Intel-based PC.

7. http://gcc.gnu.org/java/index.php

Even if this were not so, it is not permissible under the GPL to distribute binaries without also offering to distribute source code. So, to distribute the Sun or IBM API JAR files would be incompatible with the GPL, and to not distribute them but to depend on them would mean shipping a product that doesn’t work out of the box and requires users to obtain some non-Free soft- ware in order to work. That is just not acceptable. So the developers of gcj have opted to reimplement as much of the Java APIs as possible.

As you can probably guess if you have browsed the Java API Javadoc files, this is a monumental undertaking. The Java APIs are a moving target, and they started huge and grow larger with every new release. There is a parallel project to gcj called GNU Classpath8 which is attempting to implement the entire Java API. Its target for the 1.0 release is to be fully compatible with Java 1.1 and “largely compatible” with Java 1.2. You might want to look at that project for better API support than that provided by gcj’s libgcj.9 If you are curious about the present status of libgcj’s implementation of the Java APIs, there is a Web page (frequently updated) that compares the status of it against the Java 1.4 packages.10


7.4.1 Compiling FetchURL with gcj

7.4.2 Compiling a Multiclass Program