Re: ersatz - can not access a member
Hi Joe, I have a new proof of concept that allows ersatz to be embedded into a java program which then allows it to be multi-threaded ( I think. Cool idea. Still testing ). My assumption is that the static variables caused everything to be shared across the process. Removing the static keywords should open the door for multiple instances to be running in the same process. For single threaded apps, using static (as I I think it depends on which level you thread the application. - If you start multiple instances of Ersatz as individual threads of some wrapper application (that's how I understand your concept above) then the Lisp-level problems of threading can be avoided. - If you thread the application (as we did in the previous mails) on the Lisp level, the problems are not the static variables on the Java level, but the fact that all threads share the same Lisp environment (variable bindings, and I/O, 'make', 'protect, and other dynamic environments). These problems are also in the C and asm versions if one would try to thread them. understand it) will speed things up so it may not make sense to remove in the core code. Alex, is that why static is used? Yes, IIRC. 1. Run mkJar to get a PicoLisp.java 2. Find/replace to remove all static keywords 3. Rename main, move logic that calls init loops to separate method This sounds reasonable. It looks a bit like you simulate a fork() on the top level. A true (fork) function in ErsatzLisp would be possible, not sooo simple because it would involve copying all runtime data. I didn't want to do that, because I was afraid of the overhead, but the above way of starting separate instances has probably the same amount of overhead (though much simpler to implement). Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: ersatz - can not access a member
This is the java example I'm trying to duplicate: http://www.simpleframework.org/doc/tutorial/tutorial.php import org.simpleframework.http.core.Container; import org.simpleframework.transport.connect.Connection; import org.simpleframework.transport.connect.SocketConnection; import org.simpleframework.http.Response; import org.simpleframework.http.Request; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.io.PrintStream; public class HelloWorld implements Container { public void handle(Request request, Response response) { PrintStream body = response.getPrintStream(); long time = System.currentTimeMillis(); response.set(Content-Type, text/plain); response.set(Server, HelloWorld/1.0 (Simple 4.0)); response.setDate(Date, time); response.setDate(Last-Modified, time); body.println(Hello World); body.close(); } public static void main(String[] list) throws Exception { Container container = new HelloWorld(); Connection connection = new SocketConnection(container); SocketAddress address = new InetSocketAddress(8080); connection.connect(address); } } On Sat, Jan 28, 2012 at 6:33 AM, Joe Bogner joebog...@gmail.com wrote: I'm trying to write a simple java web server using the simpleframework. I'm close, but I process anything in the method handler: (de handler (request response) (java response 'close)) (setq cont (interface org.simpleframework.http.core.Container 'handle handler)) (setq con (java org.simpleframework.transport.connect.SocketConnection T cont)) (setq addr (java java.net.InetSocketAddress T 8005)) (java con 'connect addr) When I run this and then curl http://localhost:8005 I get the following exception: java.lang.IllegalAccessException: Class PicoLisp$Number can not access a member of class org.simpleframework.http.core.ResponseEntity with modifiers public I've tried every other method I can think of from this doc: http://www.simpleframework.org/doc/javadoc/index.html If I intentionally put a missing method in, it correctly reports it: (de handler (request response) (java response 'close2)) : !? (java response 'close2) java.lang.NoSuchMethodException: close2 If my handler is this, I get a response. (de handler (request response) (prinl response)) : HTTP/1.1 200 OK I need to be able access the request/response to process it. I am not sure if I need to use javac because of the interface but then I'm not sure how I'd add picolisp code to process the request/response. Thanks for any help -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: ersatz - can not access a member
Hello Joe, I'm trying to write a simple java web server using the simpleframework. I'm close, but I process anything in the method handler: OK. I can't reproduce the problem, as I don't have access to that framework. But perhaps I can give some hints to help locate the problem. (de handler (request response) (java response 'close)) (setq cont (interface org.simpleframework.http.core.Container 'handle handler)) (setq con (java org.simpleframework.transport.connect.SocketConnection T cont)) (setq addr (java java.net.InetSocketAddress T 8005)) (java con 'connect addr) One note first: In PicoLisp, it is advisable to use uppercase names for (local) variables, because otherwise there is a risc for name conflicts. For example, the expression (setq con (java org.simpleframework... changes the value of the symbol 'con', which happens to be a function (setting the CDR of a cell). Later calls to that function will crash. This risk also exists for function parameters, so I would write the above as: (de handler (Request Response) (java Response 'close) ) (setq Cont (interface org.simpleframework.http.core.Container 'handle handler) ) (setq Con (java org.simpleframework.transport.connect.SocketConnection T Cont) ) (setq Addr (java java.net.InetSocketAddress T 8005)) (java Con 'connect Addr) But this is probably not the problem here. When I run this and then curl http://localhost:8005 I get the following exception: java.lang.IllegalAccessException: Class PicoLisp$Number can not access a member of class org.simpleframework.http.core.ResponseEntity with modifiers public It would be interesting to see _where_ things get wrong. Could you try to trace the execution? Please call (trace 'java) (trace 'interface) before starting execution. And possibly trace other functions too, e.g. (trace 'handler), or (traceAll) to trace all Lisp-level functions. There must be a situation where perhaps the argument type (number?) doesn't match. Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: ersatz - can not access a member
Hi Alex, Thanks for the response! Here's the output from trace. It's neat to see, but I don't know enough to interpret it: java -DPID=42 -cp .;picolisp.jar;simple-4.1.21.jar PicoLisp lib.l go.l + interface : org.simpleframework.http.core.Container handle ((Request Response) (java Response 'close)) interface = $$Proxy0 java : org.simpleframework.transport.connect.SocketConnection T $$Proxy0 java = $SocketConnection java : java.net.InetSocketAddress T 8005 java = $InetSocketAddress java : $SocketConnection connect $InetSocketAddress java = $InetSocketAddress : java : $ResponseEntity close !? (5 $4354460 $3195425) java.lang.IllegalAccessException: Class PicoLisp$Number can not access a member of class org.simpleframework.http.core.ResponseEntity with modifiers public ? Another question: I started down an alternate path to use java.net.ServerSocket but it doesn't seem to like threads/thread pool calls. Here's a really simple example: : (setq Thread (java java.lang.Thread T (interface java.lang.Runnable 'run '(() (prinl hi)) - $Thread (java Thread start) : - NIL : Exception in thread Thread-1 java.lang.NullPointerException at PicoLisp$Number$1.invoke(Unknown Source) at $Proxy0.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Any clues on this one either? Thank you! Joe On Sat, Jan 28, 2012 at 7:18 AM, Alexander Burger a...@software-lab.de wrote: Hello Joe, I'm trying to write a simple java web server using the simpleframework. I'm close, but I process anything in the method handler: OK. I can't reproduce the problem, as I don't have access to that framework. But perhaps I can give some hints to help locate the problem. (de handler (request response) (java response 'close)) (setq cont (interface org.simpleframework.http.core.Container 'handle handler)) (setq con (java org.simpleframework.transport.connect.SocketConnection T cont)) (setq addr (java java.net.InetSocketAddress T 8005)) (java con 'connect addr) One note first: In PicoLisp, it is advisable to use uppercase names for (local) variables, because otherwise there is a risc for name conflicts. For example, the expression (setq con (java org.simpleframework... changes the value of the symbol 'con', which happens to be a function (setting the CDR of a cell). Later calls to that function will crash. This risk also exists for function parameters, so I would write the above as: (de handler (Request Response) (java Response 'close) ) (setq Cont (interface org.simpleframework.http.core.Container 'handle handler) ) (setq Con (java org.simpleframework.transport.connect.SocketConnection T Cont) ) (setq Addr (java java.net.InetSocketAddress T 8005)) (java Con 'connect Addr) But this is probably not the problem here. When I run this and then curl http://localhost:8005 I get the following exception: java.lang.IllegalAccessException: Class PicoLisp$Number can not access a member of class org.simpleframework.http.core.ResponseEntity with modifiers public It would be interesting to see _where_ things get wrong. Could you try to trace the execution? Please call (trace 'java) (trace 'interface) before starting execution. And possibly trace other functions too, e.g. (trace 'handler), or (traceAll) to trace all Lisp-level functions. There must be a situation where perhaps the argument type (number?) doesn't match. Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: ersatz - can not access a member
Hi Joe, Another question: I started down an alternate path to use java.net.ServerSocket but it doesn't seem to like threads/thread pool calls. Here's a really simple example: : (setq Thread (java java.lang.Thread T (interface java.lang.Runnable 'run '(() (prinl hi)) - $Thread (java Thread start) : - NIL : Exception in thread Thread-1 java.lang.NullPointerException HA! You found a bug in 'interface' :) It seems that 'interface' could not handle correctly functions with empty parameter lists, like the above '(() ..). This resulted in the NullPointer exception. I fixed ersatz/fun.src: 239a240,242 if (arg == null) return w.apply(null, false, null, 0); else { 244a248 } (also uploaded a fixed version). With that: abu:~/pico ersatz/pil + : (setq Thread (java java.lang.Thread T (interface java.lang.Runnable 'run '(() (prinl hi))) ) ) (java Thread start) - $Thread : - NIL : hi BUT! While this simple example works, I'll have to warn stronly to use Java threads in real code. The problem is the same as with the other versions of PicoLisp: Threads cannot be handled cleanly, due to symbol binding conflicts. You'll open a pandora box, because each thread will overwrite the other thread's bindings. Unfortunately, Java doesn't come with a fork() system call ... Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: ersatz - can not access a member
Hi Joe, Thanks for the response! Here's the output from trace. It's neat to see, but I don't know enough to interpret it: OK, this looks helpful (a little ;) If I intermix the previous code with the trace output in the editor (not just in mind as usual), I get: (de handler (Request Response) (java Response 'close) ) (setq Cont (interface org.simpleframework.http.core.Container 'handle handler) ) interface : org.simpleframework.http.core.Container handle ((Request Response) (java Response 'close)) interface = $$Proxy0 'interface' is called with the strng org.., the symbol 'handle', and the list ((Request Response) (java Response 'close)). FYI: The output of 'trace' shows a line with ':' when a function/method is entered, and a line with '=' after the function returned. So we see that 'interface' here returns an object '$$Proxy0'. (setq Con (java org.simpleframework.transport.connect.SocketConnection T Cont) ) java : org.simpleframework.transport.connect.SocketConnection T $$Proxy0 java = $SocketConnection 'Con' is set to an object '$SocketConnection' (setq Addr (java java.net.InetSocketAddress T 8005)) java : java.net.InetSocketAddress T 8005 java = $InetSocketAddress and 'Addr' to an '$InetSocketAddress' (java Con 'connect Addr) java : $SocketConnection connect $InetSocketAddress java = $InetSocketAddress Looks all right so far. Now: : java : $ResponseEntity close !? (5 $4354460 $3195425) java.lang.IllegalAccessException: Class PicoLisp$Number can not access a member of class org.simpleframework.http.core.ResponseEntity with modifiers public This must have happened in the body of 'handler'. We don't have a clear trace of what happened in between. But we see that 'java' is called with and object '$ResponseEntity' (i.e. 'Response' is bound to that object) and the symbol 'close' (java Response 'close) Hmm, I don't know. Is the handler, and the way it is installed, correct? Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: ersatz - can not access a member
Thanks! Regarding threading, I stepped away for a few and the thought crossed my mind as well. I came back tried the main thread do this: (loop (setq Method nope)) And I can see that Method gets overwritten in child threads. Neither bind nor job helps either. Is there any way around this? I supposed I could stick all my symbols in java thread local storage and always refer to symbols by (java ... ) instead of directly calling them. I may try that... Otherwise I'll have to make it single threaded which basically kills the idea of it because of slow pages. If not, it was a fun experiment nonetheless. On Sat, Jan 28, 2012 at 11:59 AM, Alexander Burger a...@software-lab.de wrote: Hi Joe, Another question: I started down an alternate path to use java.net.ServerSocket but it doesn't seem to like threads/thread pool calls. Here's a really simple example: : (setq Thread (java java.lang.Thread T (interface java.lang.Runnable 'run '(() (prinl hi)) - $Thread (java Thread start) : - NIL : Exception in thread Thread-1 java.lang.NullPointerException HA! You found a bug in 'interface' :) It seems that 'interface' could not handle correctly functions with empty parameter lists, like the above '(() ..). This resulted in the NullPointer exception. I fixed ersatz/fun.src: 239a240,242 if (arg == null) return w.apply(null, false, null, 0); else { 244a248 } (also uploaded a fixed version). With that: abu:~/pico ersatz/pil + : (setq Thread (java java.lang.Thread T (interface java.lang.Runnable 'run '(() (prinl hi))) ) ) (java Thread start) - $Thread : - NIL : hi BUT! While this simple example works, I'll have to warn stronly to use Java threads in real code. The problem is the same as with the other versions of PicoLisp: Threads cannot be handled cleanly, due to symbol binding conflicts. You'll open a pandora box, because each thread will overwrite the other thread's bindings. Unfortunately, Java doesn't come with a fork() system call ... Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: ersatz - can not access a member
On January 28, 2012 at 1:18 PM Alexander Burger a...@software-lab.de wrote: Hello Joe, I'm trying to write a simple java web server using the simpleframework. I'm close, but I process anything in the method handler: And this excellent discussion is why we could say that we have official PicoLisp Q/A on Stackoverflow.com This was a perfect fit. I would even ask you Joe to ask the same thing on Stackoverflow.com again. ;-) best regards, Jakob -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe