Noeud:Java, Noeud « Next »:, Noeud « Previous »:C++, Noeud « Up »:Integrated Languages



Java

The front-end for Java is the GNU Java Compiler, gcj. Not all of the classes for Java have been implemented, which isn't surprising due to the impressive amount of classes that Java contains. In particular, support for the Abstract Windowing Toolkit and Swing components have not yet been implemented1, and there is no support for Remote Method Invocation either. The Java FAQ <http://gcc.gnu.org/java/faq.html> details the reasons for current extent of support. It is worth visiting this site because new developments are made all the time as new classes and features are added. Also, the current status of the gcj compiler can be viewed at <http://gcc.gnu.org/java>.

The gcj compiler can take input files in the form of .java or .class files. If a .java source file is passed in, then it can either be passed to gcj and compiled into a .class file or compiled into native machine code. If gcj is passed a .class file, then it can only produce native machine code.

To view the machine-dependant classes in object-file format, supported by gcj, locate the libgcj.a archive library (mine is located in /usr/lib/) and perform an ar t libgcj.a on it2. The results should be something like this: ...

EnumerationChain.o BufferedInputStream.o
BufferedOutputStream.o BufferedReader.o
BufferedWriter.o ByteArrayInputStream.o
ByteArrayOutputStream.o CharArrayReader.o
CharArrayWriter.o CharConversionException.o
DataInput.o DataInputStream.o
DataOutput.o DataOutputStream.o
EOFException.o File.o
FileDescriptor.o FileInputStream.o
FileNotFoundException.o FileOutputStream.o
FileReader.o FileWriter.o
FilenameFilter.o FilterInputStream.o
FilterOutputStream.o FilterReader.o
FilterWriter.o IOException.o
InputStream.o InputStreamReader.o
InterruptedIOException.o LineNumberInputStream.o
LineNumberReader.o OutputStream.o
OutputStreamWriter.o PipedInputStream.o
PipedOutputStream.o PipedReader.o
...

which shows the output of a small section of the archive library. The Java-equivalent files are in object file format, obviously, since gcj takes java source code (or class files) and can convert the information into machine-dependent binary files.

GCJ Options

Let's look at some of the commands first, and then focus on a few relatively simple examples.

gcj is invoked as follows:

gcj [options] file1 [[file2] ... [filen]]

There are a number of different options available.

-C takes the .java file and produce a corresponding .class file. The .class file is in (machine independent) byte code, so it can be run with the JVM as normal. This option cannot be used with --main=File (see below), because no machine-dependent code is being produced. Thus, the command gcj -C SomeClass.java will produce a file named SomeClass.class which can be run with the java command as normal.
--main=File specifies the file to be used when searching for the file that would normally be invoked with java [filename].java for the file named [filename].class where the main method is specified. Cannot be used with -C. You must specify this when creating a binary produced in native format, because the usual main stub cannot be found unless we tell it where to look; remember that Java can specify a public static void main(...) method in any of its classes, so we need some way of telling the compiler where main will be located.
-o file creates the executable named file instead of the default a.out. This flag cannot be used in conjuction with -C, because you cannot rename the class file (Java .class files are named according to their corresponding .java source files).
-d dir places class files in directory dir. Only used when compiling byte-code using -C.
-v As with gcc, print verbose output to stdout.
-g Produce debugging information, when creating machine dependent code; this is useful since it enables you to use (for example) gdb or ddd to debug java source files that have been made into machine-dependent binaries - see Debugging with gdb and DDD.

Compiling a simple Java source file

The following example utilises two Java source files.

     $ cat Main.java
     /* Main.java */
     import helloworld.HelloWorld;
     
     public class Main
     {
         public static void main(String args[])
         {
           HelloWorld helloWorld = new HelloWorld();
           System.out.println(helloWorld.toString());
         }
     }
     $
     

and our HelloWorld package file located in the directory helloworld in the same directory that Main.java is in:

     $ cat helloworld/HelloWorld.java
     /* HelloWorld.java */
     package helloworld;
     
     public class HelloWorld
     {
       String helloWorld;
       public HelloWorld()
       {
         helloWorld = "Hello, world!";
       }
       public String toString()
       {
         return helloWorld;
       }
     }
     $
     

Compiling this program with the command

$ gcj --main=Main Main.java helloworld/HelloWorld.java -o HelloWorld

yields the following output (if any problems occur, it may be because your classpath may not be set. If you can't fix it by using any of the options already given, try looking at the FAQ at the gcj homepage at <http://gcc.gnu.org/java/faq.html> for answers to many common problems when trying to compile java programs):

     $ ./HellowWorld
     Hello, world!
     $
     

Helloworld is our machine-dependent binary. If we wanted, we could have simply produced a .class file

$ gcj -C Main.java helloworld/HelloWorld.java

Which produces Main.class and HelloWorld/HelloWorld.class, which can be ran using the command java Main:

     $ java Main
     Hello, world!
     $
     

Notes de bas de page

  1. That is up to the point when this book went to press.

  2. ar is an archiving tool for archives.