Originally posted by David O'Meara:
Personally I'd only touch an application with that sort code if EFH had written it![]()
Originally posted by Ernest Friedman-Hill:
Our friend hasn't shared with us what exactly he's working on, but I've imagined it's some kind of "homework server." Students submit assignments that include a main() and write to System.out like most student programs; then his server loads the class up and runs it, displaying the output.
Originally posted by othman El Moulat:
for david suggestion :
is it possible to call java from external command to load class ? does this require that a jdk be installed on machine ?
does tomcat contain the java.exe program to execute classes ? where and how should i do that ?
Originally posted by othman El Moulat:
i'm curious to know why it won't scale well for large number of users ?
Originally posted by Ernest Friedman-Hill:
How many java.exe's can your server run simultaneously before it runs out of memory? 50? 100? Probably not 1,000? How about 10,000?
Ernest Friedman-Hill wrote:I imagine that with enough care, you could have each student class loaded by an individual classloader that provided a local copy of java.lang.System, such that that student's program had its own private System.out, which you could then redirect with impunity. It'd be tricky, and involve plenty of dark magic, but it should be possible.
Ernest Friedman-Hill wrote:
1) Create a custom class loader MyClassLoader. Give MyClassLoader setOut(), getOut(), setErr(), getErr() methods, so it can keep track of its own set of output streams. You'd pretty much have to do this anyway -- if you're compiling and loading student programs, you're going to do it with a classloader, one instance per program, so this hardest part of the problem is something you're already going to do. You must use a separate instance of MyClassLoader to load each application, but of course, you were going to anyway.
2) Create a subclass of OutputStream "MyOutputStream" and override the write() methods to do the following peculiar dance when called:
Look up the call stack, one frame at a time. At each frame, ask the class for the ClassLoader that loaded it. If you find an instance of MyClassLoader, call getOut() or getErr() (which one could be controlled by a constructor parameter) and forward the call to that object. If you get to the top of the stack without finding a MyClassLoader, forward the call to the original System.out (or System.err), which you've saved as a member variable in MyOutputStream.
3) Use System.setOut()/setErr() to replace the original streams -- after saving them, of course -- with instances of MyOutputStream wrapped in PrintStreams.
4) When you want to load an application, create a MyClassLoader, and create whatever OutputStreams you want to store the output -- i.e., ByteArrayOutputStreams -- and put then into the ClassLoader.
Ishan Jayawardene wrote:
Hi Ernest,
Thanks for the quick reply! Let's see if I understood this correctly... After step 3, all standard IO of this JVM will go through MyOutputStream?
Ernest Friedman-Hill wrote:
MyOutputStream will forward to whatever System.out was before MyOutputStream was installed for all code not invoked by code loaded by a MyClassLoader; i.e., if there are other web apps in this same container, they should continue to operate as normal.
Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters? |