The Excelsior JET command-line compiler comes integrated with the project system as a single utility called jc. This Chapter demonstrates practical use of the command-line compiler from a simple “Hello, world” program to a multicomponent (executable plus shared library) application.
It is assumed that JET has been properly installed and its default configuration has not been changed.
If your Java application consists of a single class file, like the "Hello world!" sample in the samples/Hello subdirectory of your JET installation, simply specify the name of that class file as a parameter to jc:
jc hello.class
jc shall compile hello.class to native code and automatically invoke the linker that shall create the hello executable.
Similarly, if your application consists of several class files residing in the same directory, pass to jc the name of the class which you specify on your Java launcher command line:
jc MainClass.class
This would produce an executable file MainClass.
Finally, if all your application’s classes are in a single .jar file, which you run on the JVM as
java -jar MyApp.jar
you may compile it to MyApp executable as follows:
jc MyApp.jar
If not already present, subdirectories bod, obj, and sym are created during compilation. They are intended for storage of intermediate files.
The above samples illustrate jc operation in the default mode, called the MAKE mode. In that mode, the compiler recursively processes all classes used by the class specified on the command line. If intermediate files for a particular class do not exist or are out of date, that class is compiled.
If the class specified on the jc command line is a main class (i.e. it has a static void main (String args[]) public method), the linker is invoked automatically after compilation to produce an executable file. Otherwise, the compiler issues an error message.
Along with the name of the .class or .jar file, you may specify various options on the command line. The relative order of command-line parameters is irrelevant.
For instance, if you want to bind resource files (images, audio clips, etc.) from the source jar to the resulting executable, switch the BINDRESOURCES option on:
jc MyApp.jar +bindresources
In more compicated cases, e.g. if your application classes are distributed among several directories and/or .jar files, are organized into packages, etc., we recommend you to write a project file.
In the simplest case, a project file consists of a single line specifying the name of the main class:
!module hello.class
but it may also contain various option settings, file lookups, import libraries, etc.
Note: !module and !batch directives (see Project files) have to be specified at the very end of a project file.
Below is a project file containing some option settings. Notice the percent sign indicating comment lines.
% disable stack allocation -genstackalloc % bind resource files to the executable +bindresources % reduce stack size -stacklimit=100000 % main application class !module MainClass.class % jar file with resources !module Resources.jar
To compile a project, specify its name on the command line and use the =p parameter to force the compiler into the PROJECT mode:
jc =p hello.prj
The JET compiler gives you complete control over location of your bytecode files, intermediate files, and resulting executables. Using LOOKUP equations, you specify directories and jars from which jc shall read your class files, as well as directories into which it shall place intermediate files and executables:
-lookup=*.class=./class;./jars/MyLib.jar
-lookup=*.obj=./tmp
!module MainClass.class
In the above sample, the compiler is told to look for *.class files first in the class subdirectory of the current directory, and then in the archive ./jars/MyLib.jar. Object files are to be placed in ./tmp (overriding the default ./obj).
A few hints:
-lookup=*.jar=$(MYJARS);
Now, if you move your jar files to another directory, you just have to change the environment variable MYJARS accordingly.
-lookup=*.class=$!/class
By doing so you ensure that regardless of what the current directory is during compilation, the class files are read from the class subdirectory of the directory containing the project file.
Any file may be specified as an input file to jc, though files of unrecognized types are ignored. The JET project system distinguishes files by their extensions. It passes bytecode (.class) files to the compiler. Files of other types, such as libraries (.lib) or icons (.ico), are passed to the linker.
There are two project file directives that allow you to enumerate the set of jc input files. The !module directive is followed by a file name:
!module Foo.class
!module Bar.class
!module /usr/local/java/lib/Comm.jar
!module icons/MyApp.ico
whereas the batch directive facilitates processing of a group of files of the same type residing in a particular subdirectory of a lookup directory for that file type:
-lookup = *.class=/usr/local/java/lib
. . .
!batch *.class com/MyCorp/MyPackage
See The !batch directive for more information.
Your application may include classes that are organized into packages. For packages located in .jar or .zip archives, you just have to specify those archive files in LOOKUP statements in your project file:
-lookup=*.class=/usr/local/MyLib/MyPackage.jar
If you have the package as a set of separate .class files, do the following:
-lookup=*.class=/usr/local/MyLib
Now the compiler is able to find the classes from your package referenced by other classes. If you want your executable (usually a shared library) to include the entire package, use the !batch project file statement in addition to the actions described above:
+gendll
-lookup=*.class=/usr/local/MyLib
!batch *.class com/MyCorp/MyPkg
The compiler is unable to automatically recognize classes that are not imported, but loaded at run-time using Java dynamic loading facilities (Class.forName() and the JNI function FindClass()). Such classes will not be compiled and linked, and ClassNotFoundException will be thrown at run-time on an attempt to load one of them, unless you are taking advantage of the mixed compilation model. If you are not, you have to explicitly specify names of dynamically loaded classes in your project file:
. . . !module MainClass.class !module DynamicallyLoadedClass1.class !module DynamicallyLoadedClass2.class . . .
Of course, adding classes one by one may be very annoying. Fortunately, JET project system provides mechanisms to specify multiple classes at once:
!batch *.class com/MyCorp/DynaLoadPackage
-lookup = *.jar = ./MyJars . . . !module Dynamic.jar
See also Using multiple components.
With JET, you may create both executables and shared libraries. This allows you to share common classes and class libraries among multiple applications and employ the Java dynamic loading facility (see Multi-component applications).
The following instructions have to be carefully followed when building shared libraries:
Therefore, to build a shared library, you have to do the following:
Sample project:
+gendll -outputname=MyLib -lookup=*.class=./MyLib -lookup=*.jar=./MyLib -lookup=*.sym=./MyLibsym -lookup=*.bod=./MyLibbod !module MyLib.jar !module Lib1.class !module Lib2.class
The result of compilation of the above project shall be the file MyLib.so.
Then, in a project file for an executable that will be using classes from MyLib.so, do the following:
-lookup=*.class=./MyApp -lookup=*.sym=./MyAppsym;./MyLibsym -lookup=*.bod=./MyAppbod;./MyLibbod !module MainClass.class
!module MyLib.so
For more information about dynamic linking, please consult Chapter Dynamic linking. See also the programs in samples/DLL.
When the compiler detects an error during compilation, it displays an error message. The compiler may also issue warnings and notices. The default message format includes file name, position inside the original source file /Only for class files that contain line number information./ , message type indicator ([N]otice, [W]arning, [E]rror, or [F]ault), message number, and message text itself.
Assuming that the input class files are correct, jc shall normally report notices and warnings only. An error or fault reported during class file compilation indicates a misconfiguration, such as inability to locate or create a file, or a compiler bug.
For a full description of compiler messages, see Chapter Compiler messages.
* [ Dhrystone.java 278.01 W900 ] * redundant code eliminated # charLoc1 = charPar1Val;