Compiling Java programs

This chapter contains the following sections:


Overview of compiling

The JBuilder compiler has full support for the Java language, including inner classes and JAR files. You can compile from within the IDE, or from the command line using bmj (Borland Maker for Java) or bcj (Borland Compiler for Java).

A Java compiler reads Java source files, determines which additional files need to be compiled, and produces the Java program in the form of .class files containing bytecodes that are the machine code for the Java Virtual Machine (VM).

Compiling produces a separate .class file for each class declaration and interface declaration in a source file. When you run the resulting Java program on a particular platform, such as Windows NT, the Java interpreter for that platform runs the bytecodes contained in the .class files.

The just-in-time compiler is a different type of compiler. The just-in-time compiler for a given platform rapidly converts the bytecodes from the Java VM format to the platform's machine code, as the Java program runs.

For additional general information about compiling in Java, see the overview of the compiler that comes with the Java Development Kit (JDK), javac - The Java Compiler.

The following parts of a program can be compiled:

Smart Dependencies Checking

JBuilder provides fast yet complete compiling by using Smart Dependencies Checking, which results in fewer unnecessary compiles of interdependent source files, and thus accelerates the edit/recompile cycle. When compiling, instead of deciding whether to recompile a source file based only on the time stamp of the file, JBuilder analyzes the nature of the changes you make to source files.

When you compile source files for the first time, a dependency file is automatically created for each package, and is placed in the output directory along with the class files. The dependency file contains detailed information about which class uses which, for all the classses in that package. This file has an extension of .dependency.

Pre-generated dependency files are provided for the JDK and JBCL libraries. They are found in the same directory as the class files for those libraries.

Dependency files must be located in the Class Path so the compiler can find them. When you compile from within the IDE, the Cass Path is correctly set, by default. For information on how the Class Path is constructed, see the Class Path section in the "Creating and managing projects" chapter of Getting Started with JBuilder.

If you compile from the command line, you might need to run setvars.bat. For more information, see the section called Setting environment variables for command-line tools in "Using the command line tools."

Smart Dependencies Checking is used by the compiler in the IDE and by the bmj command-line compiler, but not by the bcj command-line compiler.


Types of compiling

The commands for compiling are on the Build menu:

The node can be a project, a package, or a .java file. Packages lower in the project tree hierarchy are built before packages higher in the hierarchy.

The Make and Build commands are described in greater detail below.

The Make command

Build|Make compiles any .java files within the selected node that have outdated or nonexistent .class files. The Make command also compiles any files imported by the node that have outdated or nonexistent .class files.

The selected node can be a project, package, or .java file. Making a package or project includes all the .java files within the package or project, including those within nested packages.

An "outdated" .class file is one that was not generated by compiling the current version of its .java source file.

The imported files that are checked and compiled include all recursively imported files (that is, imported files of imported files) except for files that are not in packages in the current project, such as files in packages that are marked "stable."

Make is faster than Rebuild, once you have done the initial compiling. The Make command is generally preferred over Rebuild.

To Make a node, select the node in the Navigation pane, and choose Build|Make <node name>.

Issuing File|Save and then Make on a file won't necessarily cause the file to be recompiled, because the date-time stamp reflects the last edit action, not the last save. To force a recompile, either use Build|Rebuild, or make a change to the file in the editor before saving it. For example, type a space and then a backspace.

The Rebuild command

Build|Rebuild compiles all .java files within the selected node, regardless of whether their .class files are outdated. The Rebuild command also compiles the imported files, regardless of whether their .class files are outdated. Compiler options, such as Obfuscate, are applied to all files as they are compiled.

The selected node can be a project, package, or .java file. Rebuilding a package or project includes all the .java files within the package or project, including those within nested packages.

The imported files that are compiled include all recursively imported files (that is, imported files of imported files) except for files in the stable packages that are not part of the project.

To Rebuild a node, select the node in the Navigation pane, and choose Build|Rebuild <node name>.


Compiling a program

To compile the source files for an application or applet:
  1. Open the project containing the program, or open a single Java file.

  2. In the Navigation pane, do one of the following:

  3. Then, do one of the following:

Any error messages are displayed in the Error pane that is inserted in the AppBrowser below the Content pane. Select an error message to display the associated source code. To get help on the error message, go to the Error Messages topic. Error messages are listed by number.

To select another error message, use View|Next Error Message or View|Previous Error Message.

Problems compiling imported projects

If you import a project and it won't compile, check the path settings on the Paths page of the Project Properties dialog box to make sure they are set correctly. JBuilder uses the path settings to construct the Class Path and Source Path, which is where the compiler looks for files.

Additionally, check the Libraries list on the Paths page. If one or more of the libraries is highlighted in red, it is not defined for your installation of JBuilder. Double-click the library name to define it. Then, try to recompile the project.

To set default paths for new projects (to avoid future potential problems), use the Default Project Properties dialog box (Tools|Default Project Properties). See the Setting project properties and How JBuilder constructs paths topics in the "Creating and managing projects" chapter of Getting Started with JBuilder for more information.

Checking for package/directory correspondence

JBuilder provides protective checking for duplicate class definitions in a project and for package/directory correspondence. The IDE and bmj compilers verify that the package statement in a source file corresponds to the package directory, and verify that two source files do not define the same class.

The first time you build a project, all the available .java files in a package directory will be verified and compiled. If you have temporary sources that you do not want to compile, you should use another extension besides .java. For example, if the project contains an old version of a file you are working on, that contains another definition of the same class, you'll get a "duplicate class definition" error. This checking prevents subtle problems that would be difficult to locate.

If you are using a class library that is partly inconsistent and you don't have the sources to rebuild the library, you can avoid verifying all classes of the package, and check only the classes that are actually used, by specifying the -nomakestable compiler option on the command line. In the IDE, check the Make Packages Stable option on the Compiler page of the Project Properties dialog to accomplish the same result. See the Setting compiler options section for more information.

Selectively compiling stable packages

Packages of common libraries, such as java.lang, sun.io, or borland.jbcl.control, are rarely modified, so it is usually unnecessary to take the time to recheck them for consistency every time you compile. To prevent these libraries from being checked every time you compile, these packages are marked "stable." When all classes of a package have been successfully compiled, the package is considered "stable" and a flag is set in the dependency file. When only some classes of a package have been compiled, or if an error occurred, then the package remains marked "unstable."

Stable packages won't be checked for consistency if you are compiling within the IDE and the Check Stable Packages option is off on the Compiler page of the Project Properties dialg box (File|Project Properties), or if you specify the -nocheckstable option for the bmj command-line compiler. As a result, stable packages are not checked for being up-to-date. However, if a package is included in your project, or if at least one source file in the package is included in your project, that package will be marked "unstable" and will thus be checked at every recompilation (that is, every time you do Build|Make).

In the IDE, if a package is marked "stable" but you are editing a file of that package outside of the IDE (using a different editor), it's best to include that package in the project so it is checked for recompiling. In the IDE, the compiler does not check packages marked "stable" to see if they are up to date, unless they are part of the project.

Making stable packages

Within the IDE, check the Make Packages Stable option on the Compiler page of the Project Properties dialog box to make all the classes of a package the first time it is built and to mark the package as "stable."

If this option is off or if the -nomakestable option is specified for the bmj compiler, only the referenced classes of the package are made, and the package remains "unstable." This is handy when you are working with a library of classes for which you have no source code and some of the unused class files are not consistent.


Setting compiler options

You can specify compiler options for the current project. The options are applied to all files in the project tree. The options are also applied to files referenced by these files, stopping at packages which are marked "stable" and have no classes in the project tree.

To set compiler options,

  1. Select the project node in the Navigation pane.

  2. Right-click and choose Properties.
    The Project Properties dialog box is displayed.

  3. Click the Compiler tab to display the Compiler page.

  4. Choose the following options:

    Option Description

    Include Debug Information Includes symbolic debug information in the .class file when you compile, make, or rebuild a node.
    Show Warnings Displays compiler warning messages.
    Show Deprecations Displays all deprecated classes, methods, properties, events, and variables used in the API. If a warning is displayed when compiling, indicating that some deprecated APIs were used, you can turn this option on to see all deprecated APIs.
    Check Stable Packages Checks files in the packages that are marked "stable" to see whether they and their imported classes need to be recompiled. This option shortens the edit/recompile cycle by not re-checking stable packages.

    If this option is off, a given branch of the checking process halts when it reaches a package marked "stable;" it does not look for unstable packages imported by the stable packages. Therefore, with this option, you might need to specify a greater number of modules to compile.

    By default, the compiler checks packages marked "stable" as well as packages marked "unstable," to determine whether they and their imported classes need to be recompiled.

    Make Packages Stable If this option is on, the compiler will compile or check all the classes of a package on the first build and mark the package "stable." If this option is off, only the referenced classes of this package will be made, and the package will not be marked "stable."

    This option should be off when working with partial projects.

    This option is especially useful for working with a library of classes with no source available, when some of the class files are not consistent, but not used.

    Obfuscate Obfuscates your code.

    Obfuscation makes your programs less vulnerable to reverse engineering. After decompiling your obfuscated code, the generated source code contains altered symbol names for private symbols.

    Exclude Class Excludes the selected .class file from a compile.
    Encoding Specifies the encoding that controls how the compiler interprets characters beyond the ASCII character set. If no setting is specified, the default native-encoding converter for the platform is used.
    Autosave All Files Automatically saves all files in the project.

  5. Click OK to close the Project Properties dialog box and save your settings.
Note:
The options set on the Compiler page of the Default Project Properties dialog (Tools|Default Project Properties) are used for new projects.

The scope of project-wide settings

If you change compiler options, you should fully Rebuild your packages or your entire project, and not just Make them. The project options are applied to any class being rebuilt, outside the project tree as well as inside the project tree. For example, if you set obfuscation on some classes and compile them in one project, then in another project reference those same files without obfuscation, but do a Rebuild All, you will un-obfuscate them.

You cannot set compile options per file; however, a file can be used by two projects, both of which have different settings for compiling. Applying options on classes or packages individually is not supported, because there is no separate compilation of headers and modules in Java. If some import information is missing (such as a class file), the imported class is compiled at the same time as the importing class, using the same project-wide options.

Adding symbolic debug information

To add symbolic debug information at compile time, choose File|Project Properties. On the Compiler page, check the Include Debug Information option.

When you compile, make, or rebuild a node, symbolic debug information will be included in the .class file.


Compiling from the command line

You can compile from the command line using the bmj or bcj commands. To see the syntax and list of options, type bmj or bcj at the command line.

You might need to run setvars.bat to set the environment variables for the command line, so that the required classes are found.

bmj

bmj is the Borland Maker for Java. bmj compiles any .java files within the selected node that have outdated or nonexistent .class files. bmj also compiles any imported classes that have outdated or nonexistent .class files.

bmj looks for dependency files on the classpath, and does dependencies checking. If you specify a set of sources, some or all of those sources might not be recompiled. For example, the class files might be determined to be up to date, if they have been saved but not edited since the last compile. You can force recompilation using the -rebuild option.

To check a set (or "graph") of interdependent modules, it is sufficient to call bmj on the root source (or multiple root sources, if one is not under the other). You can specify this argument using source names, package names, class names, or a combination.

bcj

bcj is the Borland Compiler for Java. bcj compiles the specified sources, whether or not their .class files are outdated. It also compiles any directly imported .java files that do not have .class files. Imported .java files that already have .class files will not be recompiled, even if their .class files are outdated; after using bcj, some imported classes might still have outdated .class files.

bcj does not do dependencies checking, and does not use or generate a dependency file. bcj only compiles the items you specify, and only compiles the imported classes which have no .class file yet.

See also:
The bmj command-line compiler
The bcj command-line compiler
Setting environment variables for command-line tools

Switching between the command line and IDE

If you edit a file outside the IDE, be sure to include its package or at least one of that package's sources in your project, so that the package is considered "unstable" and is checked when you compile. Otherwise, the change will not be detected, and the source won't be recompiled.

The default setting at the command line is to check consistency for referenced classes, regardless of whether their packages are marked "stable" or "unstable." That is, the option -nocheckstable is not specified by default on the command line.


Running applets

When you run an applet from within the IDE, the applet is displayed in the Applet Viewer, a Java-enabled browser. The HTML file that calls the applet is always able to find the class file, even if the class file is in a different directory. The HTML file usually resides in the myprojects tree, while the corresponding class file resides in the myclasses tree. The CODEBASE parameter in the <APPLET> tag usually does not need to be defined.

To run an applet from within the IDE:

  1. Select the HTML file that contains the APPLET tag.
  2. Choose Run|Run.
    The applet is displayed in the Applet Viewer.
The HTML file might need to specify a package name prefix in addition to a class name:
CODE="somePackage.SomeClass.class"

Running applets from the command line

To run an applet from the command line, you need to set the CODEBASE parameter and the environment variables, so that the HTML file can find the class files.

To run an applet from the command line:

  1. In the APPLET tag in the HTML file, specify:
    CODEBASE="\jbuilder\myclasses"
  2. If necessary, run setvars.bat to set your paths (see above).