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 175 forks source link

Add proper JAR file support #71

Closed jvilk closed 10 years ago

jvilk commented 11 years ago

Here's my proposal for JAR file support:

  1. Extract JAR file to /tmp/doppio/[random string] using some JavaScript library.
  2. Modify classpath as needed.
  3. ...
  4. Profit!

If you use the Node API, it'll 'just work' in the browser since we now have a virtual file system. I can even add a modification that prevents /tmp files from being stored in local storage.

jvilk commented 11 years ago

As a subnote, this will make running JUnit with Doppio much easier... which could lead to us using JUnit for testing!

perimosocordiae commented 11 years ago

We now use Javascript to do our jar-file running:

./console/runner.coffee package.Main --jar=path/to/file.jar

If it has a manifest with a proper Main-Class attribute, then you can leave out the main class:

./console/runner.coffee --jar=path/to/file.jar

This change added a new npm dependency (adm-zip), so I'm not sure if it'll "just work" in the browser, but it's progress!

perimosocordiae commented 11 years ago

We can now run JUnit tests successfully (from the console frontend):

doppio$ java -cp .:vendor/junit.jar org.junit.runner.JUnitCore test.Math
JUnit version 4.11-SNAPSHOT
...
Time: 0.007

OK (3 tests)

doppio$ ./console/runner.coffee org/junit/runner/JUnitCore --jar=vendor/junit.jar --java=test.Math
JUnit version 4.11-SNAPSHOT
...
Time: 0.962

OK (3 tests)
perimosocordiae commented 11 years ago

The only blocking issue at this point is the zip library. For the console, we use a node.js package (mentioned above) which I think would be non-trivial to make work in the browser. For one, we'd need to more fully implement the node fs and path APIs, but we'd also need to deal with the differences in node's require/exports structure.

We could probably find a more browser-friendly unzipper, but then we'd have to modify it to handle entire archives and writing to "files" and such.

The easiest way forward might actually be to use a Java-based JAR unzipper and run it in Doppio. Assuming we can run it in a reasonable amount of time, of course.

lavelle commented 11 years ago

Not sure if you guys have seen it, but node-zip is based on JSZip, which runs in the browser. Seems to have a few limitations though, so I'm not sure if it would work for Doppio's use cases.

lavelle commented 11 years ago

Alternatively, it might be worth trying to Browserify node-zip, if you need to maintain the Node-like API. Browserifying stuff that does IO can be tricky though, and I'm not sure if it would conflict with BrowserFS.

perimosocordiae commented 11 years ago

Yep, that was one of the reasons I had for going with node-zip in the first place. Now that we have BFS, the transition should be (relatively) straightforward.

jvilk commented 11 years ago

Does it support extracting individual files from the zip file efficiently? I'd like to load the JAR into memory (or perhaps to a larger backing store than localStorage), and only extract individual items when we need them from the zip file's index.

Then maybe we could do something clever, like a ZipFileSystem. (Or not.)

perimosocordiae commented 10 years ago

As of this last commit, we can now do this:

  1. wget https://kmttg.googlecode.com/files/hello.jar (a simple "hello world" JAR file).
  2. Upload hello.jar using the Doppio browser demo interface.
  3. Run java -jar hello.jar Hello in the Doppio browser terminal.
  4. Be amazed!

Note that it doesn't look in the manifest for main files, and it will likely explode your browser for large JAR inputs. (We're loading each file, uncompressed, into /tmp/jars/... (an in-memory BFS backend).

perimosocordiae commented 10 years ago

Marking this as blocked, as we're waiting on BrowserFS to support archive-backed file systems.

jvilk commented 10 years ago

BFS supports archive-backed filesystems.

We're waiting on me to generalize the caching mechanisms so that the archive-backed filesystem doesn't need to decompress the same file each time it's opened.

jvilk commented 10 years ago

This is done. We don't perform caching, but as has been pointed out, the bootstrap classloader hangs onto parsed classfiles anyway until they are cleared out manually, or a new JVM object is constructed.

JAR files work on the classpath, and with the -jar argument in both the console (using node-zip) and in the browser (using BrowserFS's new ZipFS).