This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-30
Channels
- # announcements (41)
- # aws (2)
- # aws-lambda (1)
- # babashka (51)
- # babashka-sci-dev (15)
- # beginners (56)
- # calva (15)
- # cider (8)
- # clojars (6)
- # clojure (107)
- # clojure-dev (6)
- # clojure-europe (33)
- # clojure-france (3)
- # clojure-nl (4)
- # clojure-sg (2)
- # clojure-uk (8)
- # clojurescript (16)
- # cursive (11)
- # data-oriented-programming (1)
- # datomic (4)
- # events (11)
- # fulcro (15)
- # graphql (6)
- # helix (17)
- # holy-lambda (1)
- # improve-getting-started (14)
- # integrant (39)
- # jobs (14)
- # lsp (36)
- # malli (3)
- # nrepl (8)
- # off-topic (26)
- # other-languages (1)
- # polylith (21)
- # portal (7)
- # practicalli (17)
- # re-frame (7)
- # react (4)
- # reitit (1)
- # remote-jobs (6)
- # sci (1)
- # shadow-cljs (45)
- # spacemacs (12)
- # tools-deps (5)
- # xtdb (26)
Hi everyone!
I've been migrating a codebase to Polylith and ran into a particularly annoying issue. The codebase uses Malli for validation and makes use of a custom default registry. Now the way that works in Malli is that you have to set a JVM opt -Dmalli.registry/type=custom
that seemingly clears the registry on start, and then allows you to override the default registry without throwing an exception.
Now the problem is that when I go and run poly test
, Malli fails with an invalid-schema error because... the Polylith CLI also uses Malli for validation and of course doesn't initialize our custom registry.
Unless there's a better solution, my question would be: Is there a way that I can pass JVM opts to the JVM running the tests and not the one running the Polylith CLI?
poly test
uses a single JVM but creates isolated classloaders for each project when running tests.
You would need to specify that JVM option in a way that the poly
script's JVM will pick up. I use the tool via a :poly
alias in deps.edn
so I can easily add JVM options there. I haven't looked at the poly
script but I suspect there is an environment variable you can set for that...
I'm afraid that's how I'm reproducing issue.
I first tried setting JVM_OPTS
as suggested in the readme, and it didn't work (Malli threw an exception because it wasn't picking up the option), but overriding my local _JAVA_OPTIONS
did which led to the error.
Then I tried using Polylith from a deps.edn
alias, where I can set :jvm-opts
, but that leads to the same error.
Gotcha. Hmm, I guess that's the problem with a global registry and the ability to customize it in ways that are incompatible with other tooling 😞
Perhaps Polylith should consider migrating off Malli to avoid this sort of conflict?
There is no option at the moment to pass JVM options to the test runner’s classloader. I haven’t thought about this need before. I also don’t understand why it collides with Polylith’s use of malli since the classloader we create supposed to be isolated.
@U04V70XH6 Global state sucks, but who could've seen that one coming? 😂 . By the way, thank you for helping me again with another issue related to the same underlying problem. I was the guy who tried to pass JVM opts to tools.build to get Malli to compile with our custom registry the other day. @U2BDZ9JG3 They're probably correctly isolated, it's just that the only way I can set JVM opts is globally, affecting the Polylith CLI probably way before it has a chance to spawn a classloader for testing our code. If a way to set opts specific to our classloader were to appear, that'd be great for this kind of usecase. Right now I think I'll just have to rip out the problem at its root: avoid mutating global state and pass in the custom registry manually wherever it's needed.
Yeah, I think avoiding global state is always a good thing, when possible. I’ll look into the classloader to see if we can pass jvm options to it
@U02FU034U15 What you might be able to do is write a "test fixture" that sets that JVM property directly at runtime. You can have per-project test fixtures now in Polylith.
For example, in our workspace.edn
file we have:
"worldsingles" {:alias "ws"
:test {:setup-fn worldsingles.application.fixtures/pre-test
:teardown-fn worldsingles.application.fixtures/post-test}}
@U2BDZ9JG3 Thank you! @U04V70XH6 I'll try doing that in the setup function just in case, we do have a commented out line that does it right before setting the registry and that does not work for whatever reason.
I assume something that Malli does on init is the problem.
That's why I suggested the Polylith :setup-fn
approach -- it's run independently before your tests are loaded. But you might still need to somehow force Malli to reinitialize?
There's the chance that if the setup-fn is executed before Malli runs, that might just do it. Because I'm not sure if there's a way to reload Malli unless there's a way I can hack it on the JVM side. I'll give the test-setup approach a go and report back 👍
Y'all are great you know that? One (System/setProperty "malli.registry/type" "custom")
later inside the test setup and the suite is all green.
Thank you so much!
@U2BDZ9JG3 This also means that instead of adding features to the classloading code, a small note on the test setup section of the README could work in its stead!
Awesome! I’m glad that its resolved already 🎉
@U02FU034U15 Really glad to hear that worked! We do some heavy-lifting in our :setup-fn
(and undo it in :teardown-fn
) which helps our test suite run a lot faster, compared to running that setup/teardown around each ns of tests or even, heaven forbid, around each individual test!
A happy ending and really great work guys!