So, now I do this: (defn run-server [port] (let [server-socket (ServerSocket. port "localhost")] (while (not (. server-socket isClosed)) (listen-and-respond server-socket who-is-here-now))))
(defn -main [& args] (let [port (Integer/parseInt (first args))] (println "Server is starting") (println "port: " port) (run-server port))) I am leaving out most of the code for the sake of clarity. I think these 2 functions are the only ones that need to be shared. I still get this error: Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number at who_is_logged_in.core$run_server.invoke(core.clj:27) Line 27 is: (defn run-server [port] Apparently Clojure thinks that port is a string instead of a number? I thought I fixed that problem with this line: (let [port (Integer/parseInt (first args))] Even if it is a string, I am confused why Clojure feels the argument of this function needs to be cast to a number. I would think the error would happen further into the code, when "port" is actually used. On Tuesday, August 28, 2012 10:36:15 PM UTC-4, Aaron Cohen wrote: > > Larry, > > You are missing a bit of important code from the example in the blog > post. > > In his original example, "echo" is a function (note the code block > that begins, (defn echo ...). > > His "listen-and-respond" function is what handles reading from the > ServerSocket, and responding back on the socket with the output (the > result of callin the service function). > > The ServerSocket constructor he invokes takes a single argument, > the port number. There is no constructor that takes a hostname as a > string, which is where all your attempts are failing (as you can see > from the javadoc for ServerSocket here: > http://docs.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html). > > Also, trying to take the "what-to-do" command line parameter and > treat it as a symbol is a total red herring. You should not normally > need to use the symbol function in "typical" clojure code, it is more > usually needed for macro manipulation. > > So: > > 1) Remove "localhost" from your constructor invocation. > 2) Your command line argument what-to-do is kind of nonsense. > "listen-and-respond" is expecting a fn as its 2nd argument > > > For instance: > > (defn run-server [port what-to-do] > (let [server-socket (ServerSocket. port)] > (while (not (. server-socket isClosed)) > (listen-and-respond server-socket what-to-do)))) > > # I don't know if the following works, but something close to it probably > will > (defn dumb-service [word] > (fn [input output] > (loop [line (.readLine input)] > (if-not (= line "")) > (recur (.readLine input)) > (-> output > (.println word) > .flush > .close))))) > > (defn -main [& args] > (let [port (Integer/parseInt (first args)) > word (second args))] > (println "Server is starting") > (println "port: " port) > (println (second args)) > (run-server port (dumb-service word)))) > > > On Tue, Aug 28, 2012 at 8:25 PM, larry google groups > <lawrenc...@gmail.com <javascript:>> wrote: > > I apologize about the beginner questions. I am new to Clojure. > > > > If I do this: > > > > (defn run-server [port what-to-do] > > (let [server-socket (ServerSocket. port "localhost")] > > (while (not (. server-socket isClosed)) > > (listen-and-respond server-socket what-to-do)))) > > > > (defn -main [& args] > > (let [port (Integer/parseInt (first args)) > > service (symbol (second args))] > > (println "Server is starting") > > (println "port: " port) > > (println (second args)) > > (println (symbol (second args))) > > (println "service: " service) > > (run-server port service))) > > > > And on the command line I call it like: > > > > java -jar who-is-logged-in-1.0-standalone.jar 3456 "who-is-here-now" > > > > This prints out: > > > > Server is starting > > port: 3456 > > who-is-here-now > > who-is-here-now > > service: who-is-here-now > > > > but then I get this error: > > > > Exception in thread "main" java.lang.ClassCastException: > java.lang.String > > cannot be cast to java.lang.Number > > at who_is_logged_in.core$run_server.invoke(core.clj:27) > > > > Line 27 is: > > > > (defn run-server [port what-to-do] > > > > The only way I can read the error message is to think that the code is > > trying to assign the value of what-to-do to the (integer) "port". > > > > What have I done wrong? > > > > > > > > > > On Tuesday, August 28, 2012 12:47:44 PM UTC-4, larry google groups > wrote: > >> > >> >Command line arguments that are not strings need to be converted > >> > prior to use by your main function. > >> > >> That makes sense, I need to cast it to a symbol, yes? I have a problem > >> with that though. At the REPL I tried something like this: > >> > >> (def hey (resolve (symbol what-to-do))) > >> > >> which worked great at the REPL, but in my code I get "nil" returned > from > >> resolve. If I do this: > >> > >> (defn -main [& args] > >> (let [port (Integer/parseInt (first args)) > >> service (resolve (symbol (second args)))] > >> (println "Server is starting") > >> (println "port: " port) > >> (println (second args)) > >> (println (symbol (second args))) > >> (println "service: " service) > >> (run-server port service))) > >> > >> And call it like this: > >> > >> java -jar who-is-logged-in-1.0.0-SNAPSHOT-standalone.jar 3456 > >> "who-is-here-now" > >> > >> Everything looks correct till the final line when I get "nil": > >> > >> Server is starting > >> port: 3456 > >> who-is-here-now > >> who-is-here-now > >> service: nil > >> > >> > >> > >> > >> > >> > >> > >> > >> On Tuesday, August 28, 2012 6:53:24 AM UTC-4, Jon_Boone wrote: > >>> > >>> Command line arguments that are not strings need to be converted prior > to > >>> use by your main function. > >>> > >>> Look at the code for the port number and do the same for the service. > >>> > >>> --jon > >>> > >>> > >>> On Aug 28, 2012, at 2:42, larry google groups <lawrenc...@gmail.com> > >>> wrote: > >>> > >>> > >>> So, this started when I read Keith Swallow's article on a simple web > >>> server: > >>> > >>> http://keithcelt.com/a-simple-web-server-in-clojure > >>> > >>> I took his code and ran "lein new" to create a new project and I copy > and > >>> pasted his code to core.clj and made some minor adjustments, adding > >>> gen-class and main so I could run this from the command line. My main > >>> function looked like this: > >>> > >>> (defn -main [& args] > >>> (let [port (Integer/parseInt (first args))] > >>> (println "Server is starting") > >>> (run-server port echo))) > >>> > >>> Which called his function: > >>> > >>> (defn run-server [port service] > >>> (let [server-socket (create-socket port)] > >>> (while (not (. server-socket isClosed)) > >>> > >>> (listen-and-respond server-socket service)))) > >>> > >>> I compiled that and ran "lein uberjar" and then ran it from the > command > >>> line and it worked great. > >>> > >>> Then, to make it slightly more flexible, I wanted to hand in the name > of > >>> the service from the command line. So I made a minor change: > >>> > >>> > >>> (defn run-server [port what-to-do] > >>> (let [server-socket (ServerSocket. "localhost" port)] > >>> (while (not (. server-socket isClosed)) > >>> (listen-and-respond server-socket what-to-do)))) > >>> > >>> (defn -main [& args] > >>> (let [port (Integer/parseInt (first args)) > >>> service (second args)] > >>> (println "Server is starting") > >>> (println "port: " port) > >>> (println "service: " service) > >>> (run-server port service))) > >>> > >>> I compiled this and ran it. And now this line: > >>> > >>> (defn run-server [port what-to-do] > >>> > >>> Gets this error: > >>> > >>> Exception in thread "main" java.lang.ClassCastException: > java.lang.String > >>> cannot be cast to java.lang.Number > >>> at who_is_logged_in.core$run_server.invoke(core.clj:27) > >>> > >>> I'm calling it from the command line with: > >>> > >>> java -jar who-is-logged-in-1.0.0-SNAPSHOT-standalone.jar 3456 > >>> who-is-here-now > >>> > >>> I also tried putting the service name in quotes: > >>> > >>> java -jar who-is-logged-in-1.0.0-SNAPSHOT-standalone.jar 3456 > >>> "who-is-here-now" > >>> > >>> Can anyone tell me what is wrong? Why does Clojure think I'm trying to > >>> cast "who-is-here-now" to a number? > >>> > >>> > >>> > >>> -- > >>> You received this message because you are subscribed to the Google > >>> Groups "Clojure" group. > >>> To post to this group, send email to clo...@googlegroups.com > >>> Note that posts from new members are moderated - please be patient > with > >>> your first post. > >>> To unsubscribe from this group, send email to > >>> clojure+u...@googlegroups.com > >>> For more options, visit this group at > >>> http://groups.google.com/group/clojure?hl=en > > > > -- > > You received this message because you are subscribed to the Google > > Groups "Clojure" group. > > To post to this group, send email to clo...@googlegroups.com<javascript:> > > Note that posts from new members are moderated - please be patient with > your > > first post. > > To unsubscribe from this group, send email to > > clojure+u...@googlegroups.com <javascript:> > > For more options, visit this group at > > http://groups.google.com/group/clojure?hl=en > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en