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

batchenvironment, bytearrayoutputstream, classdeclaration, classnotfound, f_dependencies, f_warnings, file, generator, ioexception, javac, main, missingresourceexception, printstream, reflection, string, util, vector

The Main.java Java example source code

/*
 * Copyright (c) 1996, 2013, 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.
 */

/*
 * Licensed Materials - Property of IBM
 * RMI-IIOP v1.0
 * Copyright IBM Corp. 1998 1999  All Rights Reserved
 *
 */

package sun.rmi.rmic;

import java.util.Vector;
import java.util.Enumeration;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.MissingResourceException;

import java.io.OutputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ByteArrayOutputStream;

import sun.tools.java.ClassFile;
import sun.tools.java.ClassDefinition;
import sun.tools.java.ClassDeclaration;
import sun.tools.java.ClassNotFound;
import sun.tools.java.Identifier;
import sun.tools.java.ClassPath;

import sun.tools.javac.SourceClass;
import sun.tools.util.CommandLine;
import java.lang.reflect.Constructor;
import java.util.Properties;

/**
 * Main "rmic" program.
 *
 * 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.
 */
public class Main implements sun.rmi.rmic.Constants {
    String sourcePathArg;
    String sysClassPathArg;
    String extDirsArg;
    String classPathString;
    File destDir;
    int flags;
    long tm;
    Vector<String> classes;
    boolean nowrite;
    boolean nocompile;
    boolean keepGenerated;
    boolean status;
    String[] generatorArgs;
    Vector<Generator> generators;
    Class<? extends BatchEnvironment> environmentClass =
        BatchEnvironment.class;
    boolean iiopGeneration = false;

    /**
     * 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;
    }

    /**
     * Output a message.
     */
    public 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.
     */
    public void error(String msg) {
        output(getText(msg));
    }

    public void error(String msg, String arg1) {
        output(getText(msg, arg1));
    }

    public void error(String msg, String arg1, String arg2) {
        output(getText(msg, arg1, arg2));
    }

    /**
     * Usage
     */
    public void usage() {
        error("rmic.usage", program);
    }

    /**
     * Run the compiler
     */
    public synchronized boolean compile(String argv[]) {

        /*
         * Handle internal option to use the new (and incomplete) rmic
         * implementation.  This option is handled here, rather than
         * in parseArgs, so that none of the arguments will be nulled
         * before delegating to the new implementation.
         */
        for (int i = 0; i < argv.length; i++) {
            if (argv[i].equals("-Xnew")) {
                return (new sun.rmi.rmic.newrmic.Main(out,
                                                      program)).compile(argv);
            }
        }

        if (!parseArgs(argv)) {
            return false;
        }

        if (classes.size() == 0) {
            usage();
            return false;
        }

        if ((flags & F_WARNINGS) != 0) {
            for (Generator g : generators) {
                if (g instanceof RMIGenerator) {
                    output(getText("rmic.jrmp.stubs.deprecated", program));
                    break;
                }
            }
        }

        return doCompile();
    }

    /**
     * Get the destination directory.
     */
    public File getDestinationDir() {
        return destDir;
    }

    /**
     * Parse the arguments for compile.
     */
    public boolean parseArgs(String argv[]) {
        sourcePathArg = null;
        sysClassPathArg = null;
        extDirsArg = null;

        classPathString = null;
        destDir = null;
        flags = F_WARNINGS;
        tm = System.currentTimeMillis();
        classes = new Vector<>();
        nowrite = false;
        nocompile = false;
        keepGenerated = false;
        generatorArgs = getArray("generator.args",true);
        if (generatorArgs == null) {
            return false;
        }
        generators = new Vector<>();

        // Pre-process command line for @file arguments
        try {
            argv = CommandLine.parse(argv);
        } catch (FileNotFoundException e) {
            error("rmic.cant.read", e.getMessage());
            return false;
        } catch (IOException e) {
            e.printStackTrace(out instanceof PrintStream ?
                              (PrintStream) out :
                              new PrintStream(out, true));
            return false;
        }

        // Parse arguments
        for (int i = 0 ; i < argv.length ; i++) {
            if (argv[i] != null) {
                if (argv[i].equals("-g")) {
                    flags &= ~F_OPT;
                    flags |= F_DEBUG_LINES | F_DEBUG_VARS;
                    argv[i] = null;
                } else if (argv[i].equals("-O")) {
                    flags &= ~F_DEBUG_LINES;
                    flags &= ~F_DEBUG_VARS;
                    flags |= F_OPT | F_DEPENDENCIES;
                    argv[i] = null;
                } else if (argv[i].equals("-nowarn")) {
                    flags &= ~F_WARNINGS;
                    argv[i] = null;
                } else if (argv[i].equals("-debug")) {
                    flags |= F_DUMP;
                    argv[i] = null;
                } else if (argv[i].equals("-depend")) {
                    flags |= F_DEPENDENCIES;
                    argv[i] = null;
                } else if (argv[i].equals("-verbose")) {
                    flags |= F_VERBOSE;
                    argv[i] = null;
                } else if (argv[i].equals("-nowrite")) {
                    nowrite = true;
                    argv[i] = null;
                } else if (argv[i].equals("-Xnocompile")) {
                    nocompile = true;
                    keepGenerated = true;
                    argv[i] = null;
                } else if (argv[i].equals("-keep") ||
                           argv[i].equals("-keepgenerated")) {
                    keepGenerated = true;
                    argv[i] = null;
                } else if (argv[i].equals("-show")) {
                    error("rmic.option.unsupported", "-show");
                    usage();
                    return false;
                } else if (argv[i].equals("-classpath")) {
                    if ((i + 1) < argv.length) {
                        if (classPathString != null) {
                            error("rmic.option.already.seen", "-classpath");
                            usage();
                            return false;
                        }
                        argv[i] = null;
                        classPathString = argv[++i];
                        argv[i] = null;
                    } else {
                        error("rmic.option.requires.argument", "-classpath");
                        usage();
                        return false;
                    }
                } else if (argv[i].equals("-sourcepath")) {
                    if ((i + 1) < argv.length) {
                        if (sourcePathArg != null) {
                            error("rmic.option.already.seen", "-sourcepath");
                            usage();
                            return false;
                        }
                        argv[i] = null;
                        sourcePathArg = argv[++i];
                        argv[i] = null;
                    } else {
                        error("rmic.option.requires.argument", "-sourcepath");
                        usage();
                        return false;
                    }
                } else if (argv[i].equals("-bootclasspath")) {
                    if ((i + 1) < argv.length) {
                        if (sysClassPathArg != null) {
                            error("rmic.option.already.seen", "-bootclasspath");
                            usage();
                            return false;
                        }
                        argv[i] = null;
                        sysClassPathArg = argv[++i];
                        argv[i] = null;
                    } else {
                        error("rmic.option.requires.argument", "-bootclasspath");
                        usage();
                        return false;
                    }
                } else if (argv[i].equals("-extdirs")) {
                    if ((i + 1) < argv.length) {
                        if (extDirsArg != null) {
                            error("rmic.option.already.seen", "-extdirs");
                            usage();
                            return false;
                        }
                        argv[i] = null;
                        extDirsArg = argv[++i];
                        argv[i] = null;
                    } else {
                        error("rmic.option.requires.argument", "-extdirs");
                        usage();
                        return false;
                    }
                } else if (argv[i].equals("-d")) {
                    if ((i + 1) < argv.length) {
                        if (destDir != null) {
                            error("rmic.option.already.seen", "-d");
                            usage();
                            return false;
                        }
                        argv[i] = null;
                        destDir = new File(argv[++i]);
                        argv[i] = null;
                        if (!destDir.exists()) {
                            error("rmic.no.such.directory", destDir.getPath());
                            usage();
                            return false;
                        }
                    } else {
                        error("rmic.option.requires.argument", "-d");
                        usage();
                        return false;
                    }
                } else {
                    if (!checkGeneratorArg(argv,i)) {
                        usage();
                        return false;
                    }
                }
            }
        }


        // Now that all generators have had a chance at the args,
        // scan what's left for classes and illegal args...

        for (int i = 0; i < argv.length; i++) {
            if (argv[i] != null) {
                if (argv[i].startsWith("-")) {
                    error("rmic.no.such.option", argv[i]);
                    usage();
                    return false;
                } else {
                    classes.addElement(argv[i]);
                }
            }
        }


        // If the generators vector is empty, add the default generator...

        if (generators.size() == 0) {
            addGenerator("default");
        }

        return true;
    }

    /**
     * If this argument is for a generator, instantiate it, call
     * parseArgs(...) and add generator to generators vector.
     * Returns false on error.
     */
    protected boolean checkGeneratorArg(String[] argv, int currentIndex) {
        boolean result = true;
        if (argv[currentIndex].startsWith("-")) {
            String arg = argv[currentIndex].substring(1).toLowerCase(); // Remove '-'
            for (int i = 0; i < generatorArgs.length; i++) {
                if (arg.equalsIgnoreCase(generatorArgs[i])) {
                    // Got a match, add Generator and call parseArgs...
                    Generator gen = addGenerator(arg);
                    if (gen == null) {
                        return false;
                    }
                    result = gen.parseArgs(argv,this);
                    break;
                }
            }
        }
        return result;
    }

    /**
     * Instantiate and add a generator to the generators array.
     */
    protected Generator addGenerator(String arg) {

        Generator gen;

        // Create an instance of the generator and add it to
        // the array...

        String className = getString("generator.class." + arg);
        if (className == null) {
            error("rmic.missing.property",arg);
            return null;
        }

        try {
            gen = (Generator) Class.forName(className).newInstance();
        } catch (Exception e) {
            error("rmic.cannot.instantiate",className);
            return null;
        }

        generators.addElement(gen);

        // Get the environment required by this generator...

        Class<?> envClass = BatchEnvironment.class;
        String env = getString("generator.env." + arg);
        if (env != null) {
            try {
                envClass = Class.forName(env);

                // Is the new class a subclass of the current one?

                if (environmentClass.isAssignableFrom(envClass)) {

                    // Yes, so switch to the new one...

                    environmentClass = envClass.asSubclass(BatchEnvironment.class);

                } else {

                    // No. Is the current class a subclass of the
                    // new one?

                    if (!envClass.isAssignableFrom(environmentClass)) {

                        // No, so it's a conflict...

                        error("rmic.cannot.use.both",environmentClass.getName(),envClass.getName());
                        return null;
                    }
                }
            } catch (ClassNotFoundException e) {
                error("rmic.class.not.found",env);
                return null;
            }
        }

        // If this is the iiop stub generator, cache
        // that fact for the jrmp generator...

        if (arg.equals("iiop")) {
            iiopGeneration = true;
        }
        return gen;
    }

    /**
     * Grab a resource string and parse it into an array of strings. Assumes
     * comma separated list.
     * @param name The resource name.
     * @param mustExist If true, throws error if resource does not exist. If
     * false and resource does not exist, returns zero element array.
     */
    protected String[] getArray(String name, boolean mustExist) {
        String[] result = null;
        String value = getString(name);
        if (value == null) {
            if (mustExist) {
                error("rmic.resource.not.found",name);
                return null;
            } else {
                return new String[0];
            }
        }

        StringTokenizer parser = new StringTokenizer(value,", \t\n\r", false);
        int count = parser.countTokens();
        result = new String[count];
        for (int i = 0; i < count; i++) {
            result[i] = parser.nextToken();
        }

        return result;
    }

    /**
     * Get the correct type of BatchEnvironment
     */
    public BatchEnvironment getEnv() {

        ClassPath classPath =
            BatchEnvironment.createClassPath(classPathString,
                                             sysClassPathArg,
                                             extDirsArg);
        BatchEnvironment result = null;
        try {
            Class<?>[] ctorArgTypes = {OutputStream.class,ClassPath.class,Main.class};
            Object[] ctorArgs = {out,classPath,this};
            Constructor<? extends BatchEnvironment> constructor =
                environmentClass.getConstructor(ctorArgTypes);
            result =  constructor.newInstance(ctorArgs);
            result.reset();
        }
        catch (Exception e) {
            error("rmic.cannot.instantiate",environmentClass.getName());
        }
        return result;
    }


    /**
     * Do the compile with the switches and files already supplied
     */
    public boolean doCompile() {
        // Create batch environment
        BatchEnvironment env = getEnv();
        env.flags |= flags;

        // Set the classfile version numbers
        // Compat and 1.1 stubs must retain the old version number.
        env.majorVersion = 45;
        env.minorVersion = 3;

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

        try {
            /** Load the classes on the command line
             * Replace the entries in classes with the ClassDefinition for the class
             */
            for (int i = classes.size()-1; i >= 0; i-- ) {
                Identifier implClassName =
                    Identifier.lookup(classes.elementAt(i));

                /*
                 * Fix bugid 4049354: support using '.' as an inner class
                 * qualifier on the command line (previously, only mangled
                 * inner class names were understood, like "pkg.Outer$Inner").
                 *
                 * The following method, also used by "javap", resolves the
                 * given unmangled inner class name to the appropriate
                 * internal identifier.  For example, it translates
                 * "pkg.Outer.Inner" to "pkg.Outer. Inner".
                 */
                implClassName = env.resolvePackageQualifiedName(implClassName);
                /*
                 * But if we use such an internal inner class name identifier
                 * to load the class definition, the Java compiler will notice
                 * if the impl class is a "private" inner class and then deny
                 * skeletons (needed unless "-v1.2" is used) the ability to
                 * cast to it.  To work around this problem, we mangle inner
                 * class name identifiers to their binary "outer" class name:
                 * "pkg.Outer. Inner" becomes "pkg.Outer$Inner".
                 */
                implClassName = Names.mangleClass(implClassName);

                ClassDeclaration decl = env.getClassDeclaration(implClassName);
                try {
                    ClassDefinition def = decl.getClassDefinition(env);
                    for (int j = 0; j < generators.size(); j++) {
                        Generator gen = generators.elementAt(j);
                        gen.generate(env, def, destDir);
                    }
                } catch (ClassNotFound ex) {
                    env.error(0, "rmic.class.not.found", implClassName);
                }

            }

            // compile all classes that need compilation
            if (!nocompile) {
                compileAllClasses(env);
            }
        } catch (OutOfMemoryError ee) {
            // The compiler has run out of memory.  Use the error string
            // which we preloaded.
            env.output(noMemoryErrorString);
            return false;
        } catch (StackOverflowError ee) {
            env.output(stackOverflowErrorString);
            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()) {
                env.error(0, "fatal.error");
                ee.printStackTrace(out instanceof PrintStream ?
                                   (PrintStream) out :
                                   new PrintStream(out, true));
            }
        } catch (Exception ee) {
            if (env.nerrors == 0 || env.dump()) {
                env.error(0, "fatal.exception");
                ee.printStackTrace(out instanceof PrintStream ?
                                   (PrintStream) out :
                                   new PrintStream(out, true));
            }
        }

        env.flushErrors();

        boolean status = true;
        if (env.nerrors > 0) {
            String msg = "";
            if (env.nerrors > 1) {
                msg = getText("rmic.errors", env.nerrors);
            } else {
                msg = getText("rmic.1error");
            }
            if (env.nwarnings > 0) {
                if (env.nwarnings > 1) {
                    msg += ", " + getText("rmic.warnings", env.nwarnings);
                } else {
                    msg += ", " + getText("rmic.1warning");
                }
            }
            output(msg);
            status = false;
        } else {
            if (env.nwarnings > 0) {
                if (env.nwarnings > 1) {
                    output(getText("rmic.warnings", env.nwarnings));
                } else {
                    output(getText("rmic.1warning"));
                }
            }
        }

        // last step is to delete generated source files
        if (!keepGenerated) {
            env.deleteGeneratedFiles();
        }

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

        // Shutdown the environment object and release our resources.
        // Note that while this is unneccessary when rmic is invoked
        // the command line, there are environments in which rmic
        // from is invoked within a server process, so resource
        // reclamation is important...

        env.shutdown();

        sourcePathArg = null;
        sysClassPathArg = null;
        extDirsArg = null;
        classPathString = null;
        destDir = null;
        classes = null;
        generatorArgs = null;
        generators = null;
        environmentClass = null;
        program = null;
        out = null;

        return status;
    }

    /*
     * Compile all classes that need to be compiled.
     */
    public void compileAllClasses (BatchEnvironment env)
        throws ClassNotFound,
               IOException,
               InterruptedException {
        ByteArrayOutputStream buf = new ByteArrayOutputStream(4096);
        boolean done;

        do {
            done = true;
            for (Enumeration<?> e = env.getClasses() ; e.hasMoreElements() ; ) {
                ClassDeclaration c = (ClassDeclaration)e.nextElement();
                done = compileClass(c,buf,env);
            }
        } while (!done);
    }

    /*
     * Compile a single class.
     * Fallthrough is intentional
     */
    @SuppressWarnings("fallthrough")
    public boolean compileClass (ClassDeclaration c,
                                 ByteArrayOutputStream buf,
                                 BatchEnvironment env)
        throws ClassNotFound,
               IOException,
               InterruptedException {
        boolean done = true;
        env.flushErrors();
        SourceClass src;

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

        case CS_SOURCE:
            {
                done = false;
                env.loadDefinition(c);
                if (c.getStatus() != CS_PARSED) {
                    break;
                }
                // fall through
            }

        case CS_PARSED:
            {
                if (c.getClassDefinition().isInsideLocal()) {
                    break;
                }
                // If we get to here, then compilation is going
                // to occur. If the -Xnocompile switch is set
                // then fail. Note that this check is required
                // here because this method is called from
                // generators, not just from within this class...

                if (nocompile) {
                    throw new IOException("Compilation required, but -Xnocompile option in effect");
                }

                done = false;

                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()) {
                    c.setDefinition(src, CS_COMPILED);
                    break;
                }
                done = false;
                buf.reset();
                src.compile(buf);
                c.setDefinition(src, CS_COMPILED);
                src.cleanup(env);

                if (src.getError() || nowrite) {
                    break;
                }

                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());
                        break;
                    }
                    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("rmic.wrote", file.getPath()));
                    }
                } catch (IOException ee) {
                    env.error(0, "cant.write", file.getPath());
                }
            }
        }
        return done;
    }

    /**
     * Main program
     */
    public static void main(String argv[]) {
        Main compiler = new Main(System.out, "rmic");
        System.exit(compiler.compile(argv) ? 0 : 1);
    }

    /**
     * Return the string value of a named resource in the rmic.properties
     * resource bundle.  If the resource is not found, null is returned.
     */
    public static String getString(String key) {
        if (!resourcesInitialized) {
            initResources();
        }

        // To enable extensions, search the 'resourcesExt'
        // bundle first, followed by the 'resources' bundle...

        if (resourcesExt != null) {
            try {
                return resourcesExt.getString(key);
            } catch (MissingResourceException e) {}
        }

        try {
            return resources.getString(key);
        } catch (MissingResourceException ignore) {
        }
        return null;
    }

    private static boolean resourcesInitialized = false;
    private static ResourceBundle resources;
    private static ResourceBundle resourcesExt = null;

    private static void initResources() {
        try {
            resources =
                ResourceBundle.getBundle("sun.rmi.rmic.resources.rmic");
            resourcesInitialized = true;
            try {
                resourcesExt =
                    ResourceBundle.getBundle("sun.rmi.rmic.resources.rmicext");
            } catch (MissingResourceException e) {}
        } catch (MissingResourceException e) {
            throw new Error("fatal: missing resource bundle: " +
                            e.getClassName());
        }
    }

    public static String getText(String key) {
        String message = getString(key);
        if (message == null) {
            message = "no text found: \"" + key + "\"";
        }
        return message;
    }

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

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

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

    public static String getText(String key,
                                 String arg0, String arg1, String arg2)
    {
        String format = getString(key);
        if (format == null) {
            format = "no text found: key = \"" + key + "\", " +
                "arguments = \"{0}\", \"{1}\", \"{2}\"";
        }

        String[] args = new String[3];
        args[0] = (arg0 != null ? arg0 : "null");
        args[1] = (arg1 != null ? arg1 : "null");
        args[2] = (arg2 != null ? arg2 : "null");

        return java.text.MessageFormat.format(format, (Object[]) args);
    }
}

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-2021 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.