alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Main.java)

This example Java source code file (Main.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

exit_abnormal, exit_cmderr, exit_ok, f_debug_lines, f_debug_source, f_debug_vars, f_opt, file, integer, main, stop, string, text, util, xinterclass

The Main.java Java example source code

/*
 * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.tools.javac;

import sun.tools.java.*;
import sun.tools.util.CommandLine;
// JCOV
import sun.tools.asm.Assembler;
// end JCOV

import java.util.*;
import java.io.*;
import java.text.MessageFormat;

/**
 * Main program of the Java compiler
 *
 * WARNING: The contents of this source file are not part of any
 * supported API.  Code that depends on them does so at its own risk:
 * they are subject to change or removal without notice.
 *
 * @deprecated As of J2SE 1.3, the preferred way to compile Java
 * language sources is by using the new compiler,
 * com.sun.tools.javac.Main.
 */
@Deprecated
public
class Main implements Constants {
    /**
     * Name of the program.
     */
    String program;

    /**
     * The stream where error message are printed.
     */
    OutputStream out;

    /**
     * Constructor.
     */
    public Main(OutputStream out, String program) {
        this.out = out;
        this.program = program;
    }

    /**
     * Exit status.
     * We introduce a separate integer status variable, and do not alter the
     * convention that 'compile' returns a boolean true upon a successful
     * compilation with no errors.  (JavaTest relies on this.)
     */

    public static final int EXIT_OK = 0;        // Compilation completed with no errors.
    public static final int EXIT_ERROR = 1;     // Compilation completed but reported errors.
    public static final int EXIT_CMDERR = 2;    // Bad command-line arguments and/or switches.
    public static final int EXIT_SYSERR = 3;    // System error or resource exhaustion.
    public static final int EXIT_ABNORMAL = 4;  // Compiler terminated abnormally.

    private int exitStatus;

    public int getExitStatus() {
        return exitStatus;
    }

    public boolean compilationPerformedSuccessfully() {
        return exitStatus == EXIT_OK || exitStatus == EXIT_ERROR;
    }

    public boolean compilationReportedErrors () {
        return exitStatus != EXIT_OK;
    }

    /**
     * Output a message.
     */
    private void output(String msg) {
        PrintStream out =
            this.out instanceof PrintStream ? (PrintStream)this.out
                                            : new PrintStream(this.out, true);
        out.println(msg);
    }

    /**
     * Top level error message.  This method is called when the
     * environment could not be set up yet.
     */
    private void error(String msg) {
        exitStatus = EXIT_CMDERR;
        output(getText(msg));
    }

    private void error(String msg, String arg1) {
        exitStatus = EXIT_CMDERR;
        output(getText(msg, arg1));
    }

    private void error(String msg, String arg1, String arg2) {
        exitStatus = EXIT_CMDERR;
        output(getText(msg, arg1, arg2));
    }

    /**
     * Print usage message and make exit status an error.
     * Note: 'javac' invoked without any arguments is considered
     * be an error.
     */
    public void usage_error() {
        error("main.usage", program);
    }

    private static ResourceBundle messageRB;

    /**
     * Initialize ResourceBundle
     */
    static void initResource() {
        try {
            messageRB =
                ResourceBundle.getBundle("sun.tools.javac.resources.javac");
        } catch (MissingResourceException e) {
            throw new Error("Fatal: Resource for javac is missing");
        }
    }

    /**
     * get and format message string from resource
     */
    public static String getText(String key) {
        return getText(key, (String)null);
    }

    public static String getText(String key, int num) {
        return getText(key, Integer.toString(num));
    }

    public static String getText(String key, String fixed) {
        return getText(key, fixed, null);
    }

    public static String getText(String key, String fixed1, String fixed2) {
        return getText(key, fixed1, fixed2, null);
    }

    public static String getText(String key, String fixed1,
                                 String fixed2, String fixed3) {
        if (messageRB == null) {
            initResource();
        }
        try {
            String message = messageRB.getString(key);
            return MessageFormat.format(message, fixed1, fixed2, fixed3);
        } catch (MissingResourceException e) {
            if (fixed1 == null)  fixed1 = "null";
            if (fixed2 == null)  fixed2 = "null";
            if (fixed3 == null)  fixed3 = "null";
            String message = "JAVAC MESSAGE FILE IS BROKEN: key={0}, arguments={1}, {2}, {3}";
            return MessageFormat.format(message, key, fixed1, fixed2, fixed3);
        }
    }

    // What major and minor version numbers to use for the -target flag.
    // This should grow every time the minor version number accepted by
    // the VM is incremented.
    private static final String[] releases =      { "1.1", "1.2", "1.3", "1.4" };
    private static final short[] majorVersions =  {    45,    46,    47,    48 };
    private static final short[] minorVersions =  {     3,     0,     0,     0 };

    /**
     * Run the compiler
     */
    public synchronized boolean compile(String argv[]) {
        String sourcePathArg = null;
        String classPathArg = null;
        String sysClassPathArg = null;
        String extDirsArg = null;
        boolean verbosePath = false;

        String targetArg = null;
        short majorVersion = JAVA_DEFAULT_VERSION;
        short minorVersion = JAVA_DEFAULT_MINOR_VERSION;

        File destDir = null;
//JCOV
        File covFile = null;
        String optJcov = "-Xjcov";
        String optJcovFile = "-Xjcov:file=";
//end JCOV
        int flags = F_WARNINGS | F_DEBUG_LINES | F_DEBUG_SOURCE;
        long tm = System.currentTimeMillis();
        Vector v = new Vector();
        boolean nowrite = false;
        String props = null;
        String encoding = null;

        // These flags are used to make sure conflicting -O and -g
        // options aren't given.
        String prior_g = null;
        String prior_O = null;

        exitStatus = EXIT_OK;

        // Pre-process command line for @file arguments
        try {
            argv = CommandLine.parse(argv);
        } catch (FileNotFoundException e) {
            error("javac.err.cant.read", e.getMessage());
            System.exit(1);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }

        // Parse arguments
        for (int i = 0 ; i < argv.length ; i++) {
            if (argv[i].equals("-g")) {
                if (prior_g!=null && !(prior_g.equals("-g")))
                   error("main.conflicting.options", prior_g, "-g");
                prior_g = "-g";
                flags |= F_DEBUG_LINES;
                flags |= F_DEBUG_VARS;
                flags |= F_DEBUG_SOURCE;
            } else if (argv[i].equals("-g:none")) {
                if (prior_g!=null && !(prior_g.equals("-g:none")))
                   error("main.conflicting.options", prior_g, "-g:none");
                prior_g = "-g:none";
                flags &= ~F_DEBUG_LINES;
                flags &= ~F_DEBUG_VARS;
                flags &= ~F_DEBUG_SOURCE;
            } else if (argv[i].startsWith("-g:")) {
                // We choose to have debugging options conflict even
                // if they amount to the same thing (for example,
                // -g:source,lines and -g:lines,source).  However, multiple
                // debugging options are allowed if they are textually
                // identical.
                if (prior_g!=null && !(prior_g.equals(argv[i])))
                   error("main.conflicting.options", prior_g, argv[i]);
                prior_g = argv[i];
                String args = argv[i].substring("-g:".length());
                flags &= ~F_DEBUG_LINES;
                flags &= ~F_DEBUG_VARS;
                flags &= ~F_DEBUG_SOURCE;
                while (true) {
                    if (args.startsWith("lines")) {
                        flags |= F_DEBUG_LINES;
                        args = args.substring("lines".length());
                    } else if (args.startsWith("vars")) {
                        flags |= F_DEBUG_VARS;
                        args = args.substring("vars".length());
                    } else if (args.startsWith("source")) {
                        flags |= F_DEBUG_SOURCE;
                        args = args.substring("source".length());
                    } else {
                        error("main.bad.debug.option",argv[i]);
                        usage_error();
                        return false;  // Stop processing now
                    }
                    if (args.length() == 0) break;
                    if (args.startsWith(","))
                        args = args.substring(",".length());
                }
            } else if (argv[i].equals("-O")) {
                // -O is accepted for backward compatibility, but
                // is no longer effective.  Use the undocumented
                // -XO option to get the old behavior.
                if (prior_O!=null && !(prior_O.equals("-O")))
                    error("main.conflicting.options", prior_O, "-O");
                prior_O = "-O";
            } else if (argv[i].equals("-nowarn")) {
                flags &= ~F_WARNINGS;
            } else if (argv[i].equals("-deprecation")) {
                flags |= F_DEPRECATION;
            } else if (argv[i].equals("-verbose")) {
                flags |= F_VERBOSE;
            } else if (argv[i].equals("-nowrite")) {
                nowrite = true;
            } else if (argv[i].equals("-classpath")) {
                if ((i + 1) < argv.length) {
                    if (classPathArg!=null) {
                       error("main.option.already.seen","-classpath");
                    }
                    classPathArg = argv[++i];
                } else {
                    error("main.option.requires.argument","-classpath");
                    usage_error();
                    return false;  // Stop processing now
                }
            } else if (argv[i].equals("-sourcepath")) {
                if ((i + 1) < argv.length) {
                    if (sourcePathArg != null) {
                        error("main.option.already.seen","-sourcepath");
                    }
                    sourcePathArg = argv[++i];
                } else {
                    error("main.option.requires.argument","-sourcepath");
                    usage_error();
                    return false;  // Stop processing now
                }
            } else if (argv[i].equals("-sysclasspath")) {
                if ((i + 1) < argv.length) {
                    if (sysClassPathArg != null) {
                        error("main.option.already.seen","-sysclasspath");
                    }
                    sysClassPathArg = argv[++i];
                } else {
                    error("main.option.requires.argument","-sysclasspath");
                    usage_error();
                    return false;  // Stop processing now
                }
            } else if (argv[i].equals("-bootclasspath")) {
                if ((i + 1) < argv.length) {
                    if (sysClassPathArg != null) {
                        error("main.option.already.seen","-bootclasspath");
                    }
                    sysClassPathArg = argv[++i];
                } else {
                    error("main.option.requires.argument","-bootclasspath");
                    usage_error();
                    return false;  // Stop processing now
                }
            } else if (argv[i].equals("-extdirs")) {
                if ((i + 1) < argv.length) {
                    if (extDirsArg != null) {
                        error("main.option.already.seen","-extdirs");
                    }
                    extDirsArg = argv[++i];
                } else {
                    error("main.option.requires.argument","-extdirs");
                    usage_error();
                    return false;  // Stop processing now
                }
            } else if (argv[i].equals("-encoding")) {
                if ((i + 1) < argv.length) {
                    if (encoding!=null)
                       error("main.option.already.seen","-encoding");
                    encoding = argv[++i];
                } else {
                    error("main.option.requires.argument","-encoding");
                    usage_error();
                    return false; // Stop processing now
                }
            } else if (argv[i].equals("-target")) {
                if ((i + 1) < argv.length) {
                    if (targetArg!=null)
                       error("main.option.already.seen","-target");
                    targetArg = argv[++i];
                    int j;
                    for (j=0; j<releases.length; j++) {
                        if (releases[j].equals(targetArg)) {
                            majorVersion = majorVersions[j];
                            minorVersion = minorVersions[j];
                            break;
                        }
                    }
                    if (j==releases.length) {
                        error("main.unknown.release",targetArg);
                        usage_error();
                        return false; // Stop processing now
                    }
                } else {
                    error("main.option.requires.argument","-target");
                    usage_error();
                    return false; // Stop processing now
                }
            } else if (argv[i].equals("-d")) {
                if ((i + 1) < argv.length) {
                    if (destDir!=null)
                       error("main.option.already.seen","-d");
                    destDir = new File(argv[++i]);
                    if (!destDir.exists()) {
                        error("main.no.such.directory",destDir.getPath());
                        usage_error();
                        return false; // Stop processing now
                    }
                } else {
                    error("main.option.requires.argument","-d");
                    usage_error();
                    return false; // Stop processing now
                }
// JCOV
            } else if (argv[i].equals(optJcov)) {
                    flags |= F_COVERAGE;
                    flags &= ~F_OPT;
                    flags &= ~F_OPT_INTERCLASS;
            } else if ((argv[i].startsWith(optJcovFile)) &&
                       (argv[i].length() > optJcovFile.length())) {
                    covFile = new File(argv[i].substring(optJcovFile.length()));
                    flags &= ~F_OPT;
                    flags &= ~F_OPT_INTERCLASS;
                    flags |= F_COVERAGE;
                    flags |= F_COVDATA;
// end JCOV
            } else if (argv[i].equals("-XO")) {
                // This is what -O used to be.  Now undocumented.
                if (prior_O!=null && !(prior_O.equals("-XO")))
                   error("main.conflicting.options", prior_O, "-XO");
                prior_O = "-XO";
                flags |= F_OPT;
            } else if (argv[i].equals("-Xinterclass")) {
                if (prior_O!=null && !(prior_O.equals("-Xinterclass")))
                   error("main.conflicting.options", prior_O, "-Xinterclass");
                prior_O = "-Xinterclass";
                flags |= F_OPT;
                flags |= F_OPT_INTERCLASS;
                flags |= F_DEPENDENCIES;
            } else if (argv[i].equals("-Xdepend")) {
                flags |= F_DEPENDENCIES;
            } else if (argv[i].equals("-Xdebug")) {
                flags |= F_DUMP;
            // Unadvertised option used by JWS.  The non-X version should
            // be removed, but we'll leave it in until we find out for
            // sure that no one still depends on that option syntax.
            } else if (argv[i].equals("-xdepend") || argv[i].equals("-Xjws")) {
                flags |= F_PRINT_DEPENDENCIES;
                // change the default output in this case:
                if (out == System.err) {
                    out = System.out;
                }
            } else if (argv[i].equals("-Xstrictdefault")) {
                // Make strict floating point the default
                flags |= F_STRICTDEFAULT;
            } else if (argv[i].equals("-Xverbosepath")) {
                verbosePath = true;
            } else if (argv[i].equals("-Xstdout")) {
                out = System.out;
            } else if (argv[i].equals("-X")) {
                error("main.unsupported.usage");
                return false; // Stop processing now
            } else if (argv[i].equals("-Xversion1.2")) {
                // Inform the compiler that it need not target VMs
                // earlier than version 1.2.  This option is here
                // for testing purposes only.  It is deliberately
                // kept orthogonal to the -target option in 1.2.0
                // for the sake of stability.  These options will
                // be merged in a future release.
                flags |= F_VERSION12;
            } else if (argv[i].endsWith(".java")) {
                v.addElement(argv[i]);
            } else {
                error("main.no.such.option",argv[i]);
                usage_error();
                return false; // Stop processing now
            }
        }
        if (v.size() == 0 || exitStatus == EXIT_CMDERR) {
            usage_error();
            return false;
        }

        // Create our Environment.
        BatchEnvironment env = BatchEnvironment.create(out,
                                                       sourcePathArg,
                                                       classPathArg,
                                                       sysClassPathArg,
                                                       extDirsArg);
        if (verbosePath) {
            output(getText("main.path.msg",
                           env.sourcePath.toString(),
                           env.binaryPath.toString()));
        }

        env.flags |= flags;
        env.majorVersion = majorVersion;
        env.minorVersion = minorVersion;
// JCOV
        env.covFile = covFile;
// end JCOV
        env.setCharacterEncoding(encoding);

        // Preload the "out of memory" error string just in case we run
        // out of memory during the compile.
        String noMemoryErrorString = getText("main.no.memory");
        String stackOverflowErrorString = getText("main.stack.overflow");

        env.error(0, "warn.class.is.deprecated", "sun.tools.javac.Main");

        try {
            // Parse all input files
            for (Enumeration e = v.elements() ; e.hasMoreElements() ;) {
                File file = new File((String)e.nextElement());
                try {
                    env.parseFile(new ClassFile(file));
                } catch (FileNotFoundException ee) {
                    env.error(0, "cant.read", file.getPath());
                    exitStatus = EXIT_CMDERR;
                }
            }

            // Do a post-read check on all newly-parsed classes,
            // after they have all been read.
            for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) {
                ClassDeclaration c = (ClassDeclaration)e.nextElement();
                if (c.getStatus() == CS_PARSED) {
                    if (c.getClassDefinition().isLocal())
                        continue;
                    try {
                        c.getClassDefinition(env);
                    } catch (ClassNotFound ee) {
                    }
                }
            }

            // compile all classes that need compilation
            ByteArrayOutputStream buf = new ByteArrayOutputStream(4096);
            boolean done;

            do {
                done = true;
                env.flushErrors();
                for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) {
                    ClassDeclaration c = (ClassDeclaration)e.nextElement();
                    SourceClass src;

                    switch (c.getStatus()) {
                      case CS_UNDEFINED:
                        if (!env.dependencies()) {
                            break;
                        }
                        // fall through

                      case CS_SOURCE:
                        if (tracing)
                            env.dtEvent("Main.compile (SOURCE): loading, " + c);
                        done = false;
                        env.loadDefinition(c);
                        if (c.getStatus() != CS_PARSED) {
                            if (tracing)
                                env.dtEvent("Main.compile (SOURCE): not parsed, " + c);
                            break;
                        }
                        // fall through

                      case CS_PARSED:
                        if (c.getClassDefinition().isInsideLocal()) {
                            // the enclosing block will check this one
                            if (tracing)
                                env.dtEvent("Main.compile (PARSED): skipping local class, " + c);
                            continue;
                        }
                        done = false;
                        if (tracing) env.dtEvent("Main.compile (PARSED): checking, " + c);
                        src = (SourceClass)c.getClassDefinition(env);
                        src.check(env);
                        c.setDefinition(src, CS_CHECKED);
                        // fall through

                      case CS_CHECKED:
                        src = (SourceClass)c.getClassDefinition(env);
                        // bail out if there were any errors
                        if (src.getError()) {
                            if (tracing)
                                env.dtEvent("Main.compile (CHECKED): bailing out on error, " + c);
                            c.setDefinition(src, CS_COMPILED);
                            break;
                        }
                        done = false;
                        buf.reset();
                        if (tracing)
                            env.dtEvent("Main.compile (CHECKED): compiling, " + c);
                        src.compile(buf);
                        c.setDefinition(src, CS_COMPILED);
                        src.cleanup(env);

                        if (src.getNestError() || nowrite) {
                            continue;
                        }

                        String pkgName = c.getName().getQualifier().toString().replace('.', File.separatorChar);
                        String className = c.getName().getFlatName().toString().replace('.', SIGC_INNERCLASS) + ".class";

                        File file;
                        if (destDir != null) {
                            if (pkgName.length() > 0) {
                                file = new File(destDir, pkgName);
                                if (!file.exists()) {
                                    file.mkdirs();
                                }
                                file = new File(file, className);
                            } else {
                                file = new File(destDir, className);
                            }
                        } else {
                            ClassFile classfile = (ClassFile)src.getSource();
                            if (classfile.isZipped()) {
                                env.error(0, "cant.write", classfile.getPath());
                                exitStatus = EXIT_CMDERR;
                                continue;
                            }
                            file = new File(classfile.getPath());
                            file = new File(file.getParent(), className);
                        }

                        // Create the file
                        try {
                            FileOutputStream out = new FileOutputStream(file.getPath());
                            buf.writeTo(out);
                            out.close();

                            if (env.verbose()) {
                                output(getText("main.wrote", file.getPath()));
                            }
                        } catch (IOException ee) {
                            env.error(0, "cant.write", file.getPath());
                            exitStatus = EXIT_CMDERR;
                        }

                        // Print class dependencies if requested (-xdepend)
                        if (env.print_dependencies()) {
                            src.printClassDependencies(env);
                        }
                    }
                }
            } while (!done);
        } catch (OutOfMemoryError ee) {
            // The compiler has run out of memory.  Use the error string
            // which we preloaded.
            env.output(noMemoryErrorString);
            exitStatus = EXIT_SYSERR;
            return false;
        } catch (StackOverflowError ee) {
            env.output(stackOverflowErrorString);
            exitStatus = EXIT_SYSERR;
            return false;
        } catch (Error ee) {
            // We allow the compiler to take an exception silently if a program
            // error has previously been detected.  Presumably, this makes the
            // compiler more robust in the face of bad error recovery.
            if (env.nerrors == 0 || env.dump()) {
                ee.printStackTrace();
                env.error(0, "fatal.error");
                exitStatus = EXIT_ABNORMAL;
            }
        } catch (Exception ee) {
            if (env.nerrors == 0 || env.dump()) {
                ee.printStackTrace();
                env.error(0, "fatal.exception");
                exitStatus = EXIT_ABNORMAL;
            }
        }

        int ndepfiles = env.deprecationFiles.size();
        if (ndepfiles > 0 && env.warnings()) {
            int ndeps = env.ndeprecations;
            Object file1 = env.deprecationFiles.elementAt(0);
            if (env.deprecation()) {
                if (ndepfiles > 1) {
                    env.error(0, "warn.note.deprecations",
                              new Integer(ndepfiles), new Integer(ndeps));
                } else {
                    env.error(0, "warn.note.1deprecation",
                              file1, new Integer(ndeps));
                }
            } else {
                if (ndepfiles > 1) {
                    env.error(0, "warn.note.deprecations.silent",
                              new Integer(ndepfiles), new Integer(ndeps));
                } else {
                    env.error(0, "warn.note.1deprecation.silent",
                              file1, new Integer(ndeps));
                }
            }
        }

        env.flushErrors();
        env.shutdown();

        boolean status = true;
        if (env.nerrors > 0) {
            String msg = "";
            if (env.nerrors > 1) {
                msg = getText("main.errors", env.nerrors);
            } else {
                msg = getText("main.1error");
            }
            if (env.nwarnings > 0) {
                if (env.nwarnings > 1) {
                    msg += ", " + getText("main.warnings", env.nwarnings);
                } else {
                    msg += ", " + getText("main.1warning");
                }
            }
            output(msg);
            if (exitStatus == EXIT_OK) {
                // Allow EXIT_CMDERR or EXIT_ABNORMAL to take precedence.
                exitStatus = EXIT_ERROR;
            }
            status = false;
        } else {
            if (env.nwarnings > 0) {
                if (env.nwarnings > 1) {
                    output(getText("main.warnings", env.nwarnings));
                } else {
                    output(getText("main.1warning"));
                }
            }
        }
//JCOV
        if (env.covdata()) {
            Assembler CovAsm = new Assembler();
            CovAsm.GenJCov(env);
        }
// end JCOV

        // We're done
        if (env.verbose()) {
            tm = System.currentTimeMillis() - tm;
            output(getText("main.done_in", Long.toString(tm)));
        }

        return status;
    }

    /**
     * Main program
     */
    public static void main(String argv[]) {
        OutputStream out = System.err;

        // This is superceeded by the -Xstdout option, but we leave
        // in the old property check for compatibility.
        if (Boolean.getBoolean("javac.pipe.output")) {
            out = System.out;
        }

        Main compiler = new Main(out, "javac");
        System.exit(compiler.compile(argv) ? 0 : compiler.exitStatus);
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Main.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.