javac
javac invokes the Java compiler. When specifying the file(s) to compile, be sure to include the .java suffix on the end!

Syntax:

	javac [options] [source files]
One or more source files can be specified at the end. If you have two or more source files, they should be separated by spaces. This implies if you want to compile a java filename that contains spaces, there should be quotes around the name.
javac options
-classpath or -cp The classpath is an argument set on the command-line, or through an environment variable, that tells the JVM where to look for user-defined classes and packages in Java programs. Classpaths consist of a varying number of directory locations or jar files, separated by delimiters. In Unix, the pathname separator is / and the delimiter is ':'. On Windows, the pathname separator is \ and the delimiter is ';'.

When specifying classpaths, the current directory is not searched by default. To look for files in the current directory, add a '.' to the classpath. (This is different than searching for the source file to compile, where javac DOES look in the current directory, by default.)

When specifying pathnames, if the pathname starts with a /, it implies 'the root directory.' If it doesn't start with /, it implies 'relative to the current directory.' Therefore, '/users/kamilche' will go to the root directory, look for the folder 'users', then look for the folder 'kamilche', and 'kamilche' will look for a folder 'kamilche' in the current directory only.

'.' and '..' can be used when specifying pathnames, as well. '.' means 'the current directory', and '..' means 'the directory above the current directory.'

-helpDump some help info
-dDestination - what directory to put the .class files in.
source filesList of source files to compile, or *.java. By default, javac will search the current directory ('.') for these source files. This is the only place it will lookin the current directory! The classpath NEVER looks in the current directory, unless you add '.' to it.
javac examples
javac myclass.javaCompiles a single source file 'myclass.java'
javac *.javaCompiles all source files in current folder.
javac myclass1.java myclass2.javaCompiles two source files.
javac "My source file.java"Compiles a source file whose filename contains spaces.
javac -d bin myclass.javaCompiles the source file 'myclass.java', and place the resulting .class file in the 'bin' directory.
javac large example
Given the following source folder structure:
ECS
  src
    gov
      wa
        lni
          utilities
            customsort
              DynamicComparer.java  - package gov.wa.lni.utilities.customsort
              MultiComparable.java  - package gov.wa.lni.utilities.customsort
              MultiComparer.java    - package gov.wa.lni.utilities.customsort
              SortProperty.java     - package gov.wa.lni.utilities.customsort
  projects
    utilities
      DynamicComparer
        Multi_Test.java             - default package
        TestClass.java              - default package
        TestClass2.java             - default package
		 
and the desired output folder structure of
ECS
  bin
    gov
      wa
        lni
          utilities
            customsort
              DynamicComparer.class  
              MultiComparable.class  
              MultiComparer.class    
              SortProperty.class    
    projects
      utilities
        DynamicComparer
          Multi_Test.class
          TestClass.class
          TestClass2.class
The folder 'ECS\bin' must already exist - the compile process can't create that folder. However, the compile process WILL create the folder structure implied in the package name - ie, com.wa.lni.utilities.customsort.

To compile the program into the directory structures specified above:

  • Create the ECS/bin folder
  • Create the ECS/bin/projects/utilities/DynamicComparer folder structure
  • Set your working directory to ECS
  • Issue the following commands to compile the specified source files to the desired destination folders:

    • javac -d bin src/gov/wa/lni/utilities/customsort/*.java

      Compiles the actual utility files 'DynamicComparer.java', 'MultiComparable.java', 'MultiComparer.java', 'SortProperty.java' to the desired directory. You only had to specify 'bin' folder because those utility files were in package 'gov.wa.lni.utilities.customsort' - this caused them to automatically distribute to that folder structure within the 'bin' directory.

    • javac -d bin/projects/utilities/DynamicComparer
      -classpath bin;bin/projects/utilities/DynamicComparer;C:\junit4.8.1\junit-4.8.1.jar
      projects/utilities/DynamicComparer/TestClass.java
      projects/utilities/DynamicComparer/TestClass2.java
      projects/utilities/DynamicComparer/Multi_Test.java

      This line had to be so big, for several reasons:

      1. The -d option points to output directory for the resulting compiled class files, ie 'bin/projects/utilities/DynamicComparer'. The code for the test routines were in the 'default' package - this meant they will get put in the exact folder you specify, and not be distributed to 'gov/wa/lni/utilities' etc. That's why we had to specify the full foldername for the resulting class files, ie 'bin/projects/utilities/DynamicComparer'.
      2. The -classpath option points to all the supporting classes the source to be compiled requires. These test routines require the sort classes compiled above, its own supporting classes, and JUnit. Therefore, we need to all those locations on the classpath, separated by semicolons.
        • The location of the sort classes is 'ECS/bin/gov/wa/lni/utilities/customsort'. HOWEVER, they are in package gov.wa.lni.utilities.customsort, so you don't need to specify that part of the folder structure. You only need to include the pathname to the folder level ABOVE this hierarchy - the compiler will automatically search the folder structure specified by the package of class. In addition, remember the current working directory is ECS. Given the above, only 'bin' was necessary.
        • The location of the test classes is 'ECS/bin/projects/utilities/DynamicComparer', which is the same as the folder we're compiling to. This folder contains the test class, plus supporting test classes, all in the default package. javac will NOT automatically look in the destination directory for supporting class files! If we want to include that location in the search, we need to specify it manually. Therefore, we included 'bin/projects/utilities/DynamicComparer'.
        • The JUnit classes are bundled in a jar file, they're not .class files loose in a folder. When including a jar file, you can't include just the foldername! You need to specify the full pathname to the jar file, ending in the suffix ".jar". Compare this to searching for classes folders, where you only have to specify the folder name, not the full pathname. Because of the above, we included JUnit by adding C:\junit4.8.1\junit-4.8.1.jar to the classpath.
      3. At the end of the command, you specify which files to compile, separated by spaces. If you were to specify *.java at this point, you would probably encounter errors, because the order of compilation matters. We can't compile the main file first - we need to compile the supporting files first, because compilation of the main file requires them; and THEN the main file.

Phew, we're done! This is just a simple utility with test classes. Imagine how complex the build would become, to compile a large application! That's the beauty of using Eclipse and automatically-generated Ant build files - it gets you out of a whole lot of headache.

java
The java command is used to invoke the Java Virtual Machine. Syntax:
    java [options] class [command-line args sent to program]
where 'class' is the name of the class WITHOUT THE .CLASS SUFFIX! If you specify the .class suffix, you'll get the following error:

java options
-classpath (or -cp) Just like javac - if your program uses classes that aren't in the same directory as the program, you need to specify the folder of the .class files, plus the full pathname of any .jar files necessary, here. See the 'javac' command above for more information, and a detailed example.
-DSet a system property. Note that the D is capitalized, and there is NO SPACE between it and the property name! If the property contains spaces, you must put quotes around it. If you need to set multiple system properties, enter several -D options.

Example - The following system properties set while issuing the java command:

    // sets 1 property
    -Darg1=foo1  
	
    // sets multiple properties	
    -Darg1=foo1 -Darg2="some text with spaces" 
can be retrieved from within the Java program in the following manner:
    arg1 = System.getProperty("arg1");   
    //arg1 = "foo1"
    arg2 = System.getProperty("arg2")          
    //arg2 = "some text with spaces"	
System properties are accessible from within Java - import java.util.Properties, and issue the appropriate command System.getProperties(), System.setProperty(), or System.getProperty().

JAR Files
Jar stands for 'Java Archive.' It's basically the folder structure for an entire program, zipped into a single file with a manifest. Jar files can be automatically run like an executable, if they're set up to do so. javac and java will use the jar like a normal directory tree.
To create a jar file, go to the directory one above the directory you wish to zip up, and issue the following command:
    jar -cf MyJar.jar myAppFolder
where 'MyJar.jar' is the name of the jar file you wish to create, and 'myAppFolder' should be replaced with the name of the folder containing your app.
To view a jar file, issue the following command:
    jar -tf MyJar.jar
where 'MyJar.jar' is the name of the jar file you wish to view.
Any jar files put into the jre/lib/ext folder in the Java runtime directory, will be automatically found without having to specify them on the classpath.

Static Imports
A normal Java import statement, imports one or more classes from a package into the current namespace, so you can refer to them without specifying the full package name + class name, just the class name only.

A static Java import statement, imports one or more members from a class into the current namespace, so you can refer to them without specifying the full package + class name + member name, just the member name only.

You can't import classes with a static import statement, you must use the normal import statement instead.

You can't import static members of a class with a normal import statement, you must use the static import statement instead.

Importing static members of a class, does NOT import the class itself! You must import the class as well, if you wish to refer to it without the full package name.

Here's an example with comments to assist you in understanding this:

// The following 4 lines won't work, because you can't import packages!
import java.util;
import my.remote.stuff;
import static java.util;
import static my.remote.stuff;

//This won't work, because classes are not static!
//import static my.remote.stuff.FancyClass;

// The following 2 lines won't work, because the 'static' tries 
// to bring in members of a class, not classes in a package,
// and those lines are pointing at packages.
// Remove the word 'static', and they would work - they would 
// import all classes from the package, then.
import static my.remote.stuff.*;
import static java.util.*;

// The following 2 lines won't work, because the 'static' 
// tries to bring in members of a class, and it's pointing
// to classes in a package instead.
// Add a '.*' at the end, and they would work - they would
// import all static members from the classes, instead.
import static my.remote.stuff.FancyClass;
import static java.util.Collections;

// The following 2 lines will work, because the 'static'
// is bringing in all static members of those classes.
import static my.remote.stuff.FancyClass.*;
import static java.util.Collections.*;

// The following will import class my.remote.stuff.FancyClass,
// and let you use it. Lines 1 and 2 compile, but 3 and 4 don't.
import my.remote.stuff.FancyClass;

// This will let lines 3 and 4 compile, but not lines 1 and 2.
import static my.remote.stuff.FancyClass.*;

// In short - you need to have BOTH of the following import statements
// to make lines 1 through 4 work.
// The first one lets line 1 and 2 work,
// the second one lets lines 3 and 4 work.
import my.remote.stuff.FancyClass;
import static my.remote.stuff.FancyClass.*;

import static java.util.Collections.sort;

public class TestFancyClass {
  public static void main(String[] args) {
    System.out.println(FancyClass.publicStaticList); // 1
    System.out.println(FancyClass.myFancyConstant);  // 2
    System.out.println(publicStaticList);            // 3
    System.out.println(myFancyConstant);             // 4
    
    sort(publicStaticList);
    System.out.println(publicStaticList);  
  }
}
Source file 'FancyClass.java'
package my.remote.stuff;
import java.util.*;
public class FancyClass {
  public static Integer myFancyConstant = 10;
  public static List<Integer> publicStaticList = 
    new ArrayList<Integer>();
  protected static String protectedStaticString = 
    new String("protected static");
  static Integer defaultStaticInt = Integer.MAX_VALUE;
  private static Double privateStaticDouble = 20d;
  static {
    publicStaticList.add(5);
    publicStaticList.add(3);
    publicStaticList.add(1);
  }
}