Newsgroups: comp.lang.java.machine
Subject: NoClassDefFoundError in own ClassLoader with generated vm code

I'm writing an environment for a new programming language which compiles to
JavaVM code on the fly as a means to run code. To this end I pass my generated
bytecodes to my own ClassLoader to hopefully turn into a valid class (see code
below).

The generated code constitutes the class "CompiledAardappel" and is passed to
the ClassLoader as "data". This class references the class "AardappelRuntime"
as its superclass (which is programmed in Java). defineClass calls loadClass
asking for this superclass, and loadClass succeeds, but after that defineClass
throws a the following exception:

java.lang.NoClassDefFoundError: AardappelRuntime

which I can see no logical explanation for, as loadClass already had a reference
to this class. I've been stumped with this problem for ages, and the only thing I
can imagine is that there is something else wrong with my generated code, which
causes a problem in defineClass which somewhere along they way gets turned into
above exception. But since defineClass is native code, I have no way of telling
what actually goes wrong. Another possibility is that it won't accept the class
because it originates from a different ClassLoader (and therefore strictly it is
a different class), but I don't have a clue how to change that.

If anyone is able to shed more light on this problem I would be very grateful. I
can supply the full code if that makes testing easier. Responses please cc to
wvo96r@ecs.soton.ac.uk to avoid me missing one.

Thanks,

Wouter van Oortmerssen.


class RuntimeLoader extends ClassLoader {
  Hashtable cache;
  Class ex;
  RuntimeLoader(byte[] data, String cn) throws ClassFormatError {
    cache = new Hashtable();
    ex = defineClass(cn,data,0,data.length);
    System.out.println("never arrives here: "+cn);
    cache.put(cn,ex);
    resolveClass(ex);
  }
  Class exec() { return ex; }
  public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
    System.out.println("looking for: "+name);
    Class c = (Class)cache.get(name);
    if (c==null) {
      //c = findSystemClass(name);
      c = Class.forName(name);
      cache.put(name,c);
    }
    if(resolve) resolveClass(c);
    System.out.println("found: "+name+" "+c+" "+resolve);
    return c;
  }
}


p.s. the generated code is produced with the jas package, and looks fairly sensible when viewed
with javap, but is likely to be faulty in some way still.
