Project Jigsaw: API draft


// Jigsaw API draft
// 28 January 2009


package java.lang;

public class Class<T> {

    /** @new */
    public Module getModule();

}


package java.lang.reflect;

/** @new */
public class Module
    implements AnnotatedElement
{

    public ClassLoader loader();

    // Derived from internal fields filled in by the VM
    public ModuleInfo info();

    // Convenience methods; logically, just delegate to info()
    public String name();
    public String version();

    // + AnnotatedElement methods + serial form

}


/** @new */
package java.lang.module;

public interface VersionQuery
    implements Comparator<String>
{
    public boolean matches(String version);
    public int compare(String v1, String v2);
}

public class ModuleId {
    public ModuleId(String name, String version);
    public String name();
    public String version();
}

public class ModuleIdQuery {
    public ModuleIdQuery(String name, VersionQuery vq);
    public String name();
    public VersionQuery versionQuery();
}

public class Dependence {
    public static enum Modifier { PRIVATE, OPTIONAL, LOCAL; }
    public Set<Modifier> modifiers();
    public ModuleIdQuery query();
}

public abstract class ModuleInfo
    implements java.lang.reflect.AnnotatedElement
{
    public abstract ModuleId id();
    public abstract Set<Dependence> requires();
    public abstract Set<ModuleId> provides();
    public abstract Set<String> permits();
    public abstract String mainClass();
    // + AnnotatedElement methods + serial form

    public static native ModuleInfo parse(byte[]);
}

public class ModuleClassLoader
    extends ClassLoader
{

    protected ModuleClassLoader();

    /** Primary entry point from the VM */
    public abstract Class<?> loadClass(String name, Module requestor)
        throws ClassNotFoundException;

    // Invokes a corresponding native method implemented in the VM
    protected Class<?> defineClass(Module m, String name,
                                   byte[] b, int off, int len)
        throws ClassFormatError;

    // Invokes a corresponding native method implemented in the VM
    protected Module defineModule(ModuleId id, byte[] b, int off, int len)
        throws ClassFormatError;

    @Override
    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        // ## Handle compatibility cases here
        throw new ClassNotFoundException(name)
    }

}


/** @new */
package org.openjdk.jigsaw;

public class JigsawModuleSystem
    // aka ModuleClassLoaderPool, ModuleClassManager, ModuleClassLoaderFactory
{

    public JigsawModuleSystem(ModuleLibrary lib);

    public ModuleClassLoader findLoader(ModuleId mid);

    // Invoked by JRE launcher to find the main class
    public Class<?> findClass(ModuleIdQuery query, String name)
        throws ClassNotFoundException;

}

public final class JigsawModuleClassLoader
    extends ModuleClassLoader
{

    public ModuleClassLoader(JigsawModuleSystem ms);

    /** Primary entry point from the VM */
    public Class<?> loadClass(String name, ModuleInfo requestor)
        throws ClassNotFoundException;

    protected Class<?> defineClass(Module m, String name,
                                   byte[] b, int off, int len)
        throws ClassFormatError;

    protected Module defineModule(ModuleId id, byte[] b, int off, int len)
        throws ClassFormatError;

}

public class ModuleLibrary {

    public static ModuleLibrary create(java.io.File path)
        throws IOException;

    // For Jigsaw{ModuleSystem,ClassLoader}
    public ModuleId findModuleForClass(String className, ModuleInfo requestor);
    public ModuleId findModule(ModuleIdQuery query);

    // For javac
    public static enum AgePolicy { NEWEST, OLDEST; }
    public static enum FormPolicy { SOURCE, BINARY; }
    public ModuleId findModule(ModuleQuery mq, AgePolicy ap, FormPolicy fp,
                               ModuleIdFilter midf);

    // Extracting module data
    public byte[] readClass(ModuleId mid, String className);
    public byte[] readModuleInfo(ModuleId mid);
    public char[] readSource(ModuleId mid, String className);
    public long readTimestamp(ModuleId mid, String className);

    // ## Needed?  (Leftovers from earlier notes, might not be relevant now)
    boolean checkAccess(ModuleInfo requestor, ModuleInfo supplier);
    Set<ModuleInfo> findObservedModules(ModuleInfo observer);

}

public interface ModuleIdFilter {
    boolean accept(ModuleId mi);
}