konsoletyper / teavm

Compiles Java bytecode to JavaScript, WebAssembly and C
https://teavm.org
Apache License 2.0
2.62k stars 262 forks source link

loadClass signatures missing from ClassLoader #774 #775

Closed ldubost closed 11 months ago

ldubost commented 1 year ago

Placeholder implementation which would allow programs which use this functions to still compile. The proposed placeholder implementation returns null.

konsoletyper commented 1 year ago

TeaVM is an ahead-of-time compiler that's incapable of dynamic capabilities of JVM like class loading, so it's unlikely that TeaVM ever obtains support of class loading. If you have a project that uses some missing methods like this, you can write a TeaVM plugin that patches your classes.

ldubost commented 1 year ago

You are mentioning a TeaVM plugin to patch classes ? I tried to find documentation about this, but could not find it on the TeaVM documentation. Would there be a link to a documentation or an example ?

konsoletyper commented 1 year ago

There's no documentation. There's an interface TeaVMPlugin. You just implement it and use ServiceLoader convention to register it. What you need it to implement and register ClassHolderTransformer. Use emit API (see ProgramEmitter) to generate bodies of new methods or take bodies from other methods and copy them into new bodies. For example, in you case it can look like this:

public class ClassLoaderTransformer implements ClassHolderTransformer {
    @Override
    public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) {
        if (cls.getName().equals(ClassLoader.class.getName())) {
            var method = new MethodHolder(new MethodDescriptor("loadClass", String.class, boolean.class, Class.class));
            var pe = ProgramEmitter.create(method, context.getHierarchy());
            pe.constantNull(Class.class).returnValue();
        }
    }
}

another example is:

public class ClassLoaderTransformer implements ClassHolderTransformer {
    @Override
    public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) {
        if (cls.getName().equals(ClassLoader.class.getName())) {
            var method = new MethodHolder(new MethodDescriptor("loadClass", String.class, boolean.class, Class.class));
            var templateMethod = context.getHierarchy().getClassSource().get(ClassLoaderTransformer.class.getName())
                    .getMethod(new MethodDescriptor("loadClassTemplate", String.class, boolean.class, Class.class));
            var programTemplate = templateMethod.getProgram();
            var program = ProgramUtils.copy(programTemplate);
            method.setProgram(program);
        }
    }

    @SuppressWarnings("unused")
    private Class<?> loadClassTemplate(String name, boolean initialize) {
        return null;
    }
}

There are plenty examples of plugins in TeaVM source code, actually, runtime is implemented as a set of plugins.