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
> <[email protected] <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 <[email protected]>
> >>> 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 [email protected]
> >>> Note that posts from new members are moderated - please be patient
> with
> >>> your first post.
> >>> To unsubscribe from this group, send email to
> >>> [email protected]
> >>> 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 [email protected]<javascript:>
> > Note that posts from new members are moderated - please be patient with
> your
> > first post.
> > To unsubscribe from this group, send email to
> > [email protected] <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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en