This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-18
Channels
- # announcements (1)
- # asami (2)
- # babashka (21)
- # beginners (23)
- # cider (5)
- # clj-kondo (10)
- # clojure (31)
- # clojure-europe (3)
- # clojure-nl (1)
- # clojurescript (47)
- # deps-new (1)
- # figwheel-main (7)
- # fulcro (7)
- # gratitude (1)
- # jobs-discuss (2)
- # lein-figwheel (1)
- # lsp (5)
- # off-topic (11)
- # pathom (5)
- # re-frame (1)
- # react (5)
- # reagent (4)
- # releases (1)
- # shadow-cljs (63)
- # tools-deps (16)
- # xtdb (26)
Hey.
Code reloading+Java interface question.
I use ring
and it reloads code when I update my sources and refetch the page.
I have a defprotocol
(I'll call it Interface
) which I instantiate using reify
or defrecord
(the Exception is different in both cases but it says that my object doesn't implement my interface).
I also use a type hint to specify the Interface
just before I call the method.
The exception happens when I call a method on a class after a reload.
This is the text of the exception when using reify
:
java.lang.ClassCastException: class `ReifiedClass` cannot be cast to class `Interface` (`ReifiedClass` is in unnamed module of loader clojure.lang.DynamicClassLoader @33f19df2; `Interface` is in unnamed module of loader clojure.lang.DynamicClassLoader @3e848201)
at <my stack trace>
at compojure.core$wrap_response$fn__3866.invoke(core.clj:158)
at compojure.core$pre_init$fn__3965.invoke(core.clj:328)
at compojure.api.coerce$body_coercer_middleware$fn__17205.invoke(coerce.clj:51)
at compojure.core$pre_init$fn__3967$fn__3970.invoke(core.clj:335)
at compojure.core$wrap_route_middleware$fn__3850.invoke(core.clj:127)
at compojure.core$wrap_route_info$fn__3855.invoke(core.clj:137)
at compojure.core$wrap_route_matches$fn__3859.invoke(core.clj:146)
at compojure.core$wrap_routes$fn__3977.invoke(core.clj:348)
at compojure.api.routes.Route.invoke(routes.clj:74)
Any ideas? 😕
I think it worked previously as I had more sources that are written like that in the past. But for some reason current one fails. My java version is openjdk version "16.0.2" 2021-07-20
It might be that you redefine the protocol after reifying it. A demonstration of a similar thing, although the error is different:
user=> (defprotocol P (f [_]))
P
user=> (def p (reify P (f [_] (println "f"))))
#'user/p
user=> (f p)
f
nil
user=> (defprotocol P (f [_]))
P
user=> (f p)
Execution error (IllegalArgumentException) at user/eval207$fn$G (REPL:1).
No implementation of method: :f of protocol: #'user/P found for class: user$reify__194
user=>
I think it could be the case. I moved the defprotocol
into a different namespace and it didn't produce the error after tinkering.
Probably the reloading mechanism could be smarter. Or it was a recent addition. I also changed my java version to 8 and it resulted in the same exception.
ring's wrap-reload is not smart enough to do protocol redefinition correctly
your choices are to not use protocols, or use a smarter reloading mechanism
(or do a full restart of your jvm every time you edit a file that defines a protocol)
Is there any benefits to separate the test file with the implementation, as in:https://github.com/xtdb/xtdb/blob/224a3dc04b0b9d9d5336c54f0ea9ee0d0aeb003b/crux-test/test/crux/bitemporal_tale_test.clj#L6 ? Or just purely out of personal taste?
If you don't do that, then your production setup will have to have all dependencies and potentially the same setup that you would need only during testing.
That's exactly what I mean - if the test code is separated from the rest of the code, then it's much easier to exclude that code. And if all test code is in a separate directory, then it becomes trivial - you just don't include that directory in the classpath, along with all test dependencies, when building an uberjar.
I asked a similar question in this channel recently: https://clojurians.slack.com/archives/C03S1KBA2/p1631643375454100 The consensus seemed to be “it’s possible but impractical”
Sadly the message there has been hidden by slack. “it’s possible but impractical”. How come it is impractical? And for the wild pattern matching facility mentioned, I remember lein seems have that support, how about deps?
You’d have to note each file you wanted to include in the classpath one-by-one. There’s not any support for wildcards currently
Just started experimenting with a socket REPL running on a remote host. For some reason, the server drops the connection after a short period of inactivity (30-60 seconds):
% telnet localhost 50505
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
user=> (println "x")
x
nil
user=> 1
1
user=> Connection closed by foreign host.
What could be the reason for that?
The port keeps being forwarded - I can reconnect just fine.maybe the network channel itself has an agressive timeout policy ?
i stumbled on a similar issue when i was playing around with amazon's loadbalancer in front of my database instance. sql client just lost connections for initially no apparent reason at all (which was annyoing for long running stats queries, obviously)
you could probably verify that by running the repl over network "locally" on the remote host ... if it locally doesn't close in the given timeframes the issue isn't in the repl
I just checked it with nc
running on the remote - yeah, seems to be the case, so it's not Clojure-related. Thanks!
Here's a curiosity that is just for amusement and maybe understanding Clojure internals better.
I found this weird behavior of map
- it ignores side-effects of lexically bound atoms (not globally bound ones, though, mind you) when mapping a closure. It's only in that case. I know I'm abusing of map
by trying to do side-effects, and that loop
or whatever is the right way. I just discovered this while exploring the behavior of closures, and thought some would find this interesting. Maybe map
deliberately copies closure bindings before doing its work?
Try the second block, but in a do
:
(do
(def a (atom []))
(map #(swap! a conj %) [1 2 3])
@a)
=> []
The root cause has nothing to do with scopes. map
produces a lazy collection - if nothing attempts to iterate over it, the mapping function is never called.
I assume you're doing it all in a REPL - it will evaluate the lazy collection for you when it's a return value. Since do
above hides that value, it's never evaluated.The canonical reference for laziness and effects https://stuartsierra.com/2015/08/25/clojure-donts-lazy-effects
AHHH. Laziness. Thank you.
I've found that gzipping files in clojure via GZIPOutputStream
(for example, like this https://github.com/clojure-cookbook/clojure-cookbook/blob/master/04_local-io/4-21_read-write-gzip.asciidoc) is worse than just using the gzip
linux command for large files. It seems to take more memory and is slower. Is there any way to do this more efficiently purely on the jvm or is just shelling out the way to go?
Hello, how do i use clojure.lang classes in my java 11 classes in a clojure/java leiningen polyglot project? I get:
Compiling 16 source files to <myproj>/target/classes
warning: [options] system modules path not set in conjunction with -source 11
<myclass>.java:3: error: package clojure.java.api is not visible
import clojure.java.api.Clojure;
^
(package clojure.java.api is declared in the unnamed module, but module <mymodule> does not read it)
<myclass>:4: error: package clojure.lang is not visible
import clojure.lang.IFn;
I tried to add requires clojure;
in the module-info.java
file but it does not work either
warning: [options] system modules path not set in conjunction with -source 11
<myprojmodule>/module-info.java:6: error: module not found: clojure
requires clojure;
is there a template that I can use to get started on java/clojure polyglot that works with recent versions of java?
Its been a while I had not used clojure 🙂at some Clojure Conj or something long ago, somebody had a flow diagram of advanced HTTP routing, including handling content-types, accepts, languages, methods, various status codes, etc. Also, iirc, there was a library/framework associated. Does anyone know what I'm thinking of?
ah! found it: https://clojure-liberator.github.io/liberator/tutorial/decision-graph.html
Might have been https://github.com/juxt/yada