plasma-umass / doppio

Breaks the browser language barrier (includes a plugin-free JVM).
http://plasma-umass.github.io/doppio-demo
MIT License
2.16k stars 174 forks source link

Can't load custom class #448

Closed ianopolous closed 8 years ago

ianopolous commented 8 years ago

Sorry for the barrage of questions. I really appreciate all your help!

I'm trying now to load one of our classes, but doppio can't find the class. https://github.com/ianopolous/DoppioDemo

I've loaded the class files into the BrowserFS from the /classes directory. Then tried to add /classes to the classpath of the JVM. However it still throws loading peergos.user.UserContext class.

jvilk commented 8 years ago

You should treat DoppioJVM like a regular JVM. Make a class with a public static void main method, and then just call jvm.runClass(/* Class name */ 'foo.bar.Baz', /* Arguments */ [], function(exitCode) { /* Called when execution terminates. */ }).

As a side note, when execution terminates, you need to create a fresh DoppioJVM. You cannot re-use it.

If I was better at API design, I would have just exposed a single static method that just ran a class or a JAR file and left it at that.

ianopolous commented 8 years ago

I'm trying to call a static method that returns something, not a main method. Basically I want to keep the returned object around in javascript and call various methods on it. Is that possible? I'm fine with those methods being wrapped in a promise if need be. I've been following https://github.com/plasma-umass/doppio/wiki/Running-Java-methods-from-JavaScript

jvilk commented 8 years ago

No, that breaks a number of internal assumptions. Like a regular JVM, DoppioJVM expects to run a main method. When that method completes, the JVM shuts down. Doing anything else is weird and unexpected, and may break in unknown ways.

What you should probably do is something like this, where you bootstrap DoppioJVM with a simple main method, and then call into a native method that simply never returns:

class MyClass {
  public static native void doStuff(MyObject obj);

  public static void main(String[] args) {
    MyObject obj = SomeClass.staticMethod(...);
    doStuff(obj);
  }
}

You implement doStuff in JavaScript like the other native methods. You should suspend the "thread" that the JVM is running your program on with thread.setStatus(Doppio.VM.Enums.ThreadStatus.ASYNC_WAITING);, otherwise it will expect a synchronous return value from your method.

I cannot immediately recall, but you may need to re-suspend the thread each time you call a method.

jvilk commented 8 years ago

I documented this particular assumption, which is standard for all JVMs, in the updated Getting Started Guide.