This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-07-13
Channels
- # announcements (1)
- # babashka (28)
- # beginners (49)
- # calva (34)
- # cider (8)
- # clj-kondo (7)
- # clojure (114)
- # clojure-austin (1)
- # clojure-denver (15)
- # clojure-europe (8)
- # clojure-norway (3)
- # clojurescript (83)
- # datahike (1)
- # datomic (5)
- # emacs (6)
- # events (1)
- # helix (11)
- # honeysql (2)
- # hyperfiddle (95)
- # jackdaw (1)
- # jobs-discuss (6)
- # kaocha (5)
- # lsp (15)
- # malli (3)
- # off-topic (171)
- # polylith (17)
- # re-frame (18)
- # releases (1)
- # ring (3)
- # sql (7)
I showed electric at work today and I described it as a way to write "fullstack functions"
how did people respond
they liked it. Took them a while to understand because it was two backend-only devs but I could "hear" it when it clicked for them
People out there writing one function serverless functions. We over here writing the whole application as a function.
Exception on Uberjar build: "Method code too large"
15:46:55,640 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@151bf776 - Registering current configuration as safe fallback point
Execution error (IndexOutOfBoundsException) at clojure.asm.MethodWriter/computeMethodInfoSize (MethodWriter.java:2061).
Method code too large!
Full report at:
/var/folders/3y/0kx0ddld5m116s7p_62h1ynr0000gp/T/clojure-11423849822174727895.edn
Execution error (ExceptionInfo) at clojure.tools.build.tasks.compile-clj/compile-clj (compile_clj.clj:112).
Clojure compilation failed, working dir preserved: /var/folders/3y/0kx0ddld5m116s7p_62h1ynr0000gp/T/compile-clj11185829201170148305
Full report at:
/var/folders/3y/0kx0ddld5m116s7p_62h1ynr0000gp/T/clojure-12005292496436482601.edn
$ cat /var/folders/3y/0kx0ddld5m116s7p_62h1ynr0000gp/T/clojure-1088563969155590368.edn
{:clojure.main/message
"Execution error (IndexOutOfBoundsException) at clojure.asm.MethodWriter/computeMethodInfoSize (MethodWriter.java:2061).\nMethod code too large!\n",
:clojure.main/triage
{:clojure.error/class java.lang.IndexOutOfBoundsException,
:clojure.error/line 2061,
:clojure.error/cause "Method code too large!",
:clojure.error/symbol clojure.asm.MethodWriter/computeMethodInfoSize,
:clojure.error/source "MethodWriter.java",
:clojure.error/phase :execution},
:clojure.main/trace
{:via
[{:type clojure.lang.Compiler$CompilerException,
:message "Syntax error macroexpanding at (prod.clj:1:1).",
:data
{:clojure.error/phase :execution,
:clojure.error/line 1,
:clojure.error/column 1,
:clojure.error/source "prod.clj"},
:at [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3719]}
{:type java.lang.IndexOutOfBoundsException,
:message "Method code too large!",
:at
[clojure.asm.MethodWriter
computeMethodInfoSize
"MethodWriter.java"
2061]}],
:trace
[[clojure.asm.MethodWriter
computeMethodInfoSize
"MethodWriter.java"
2061]
[clojure.asm.ClassWriter toByteArray "ClassWriter.java" 457]
[clojure.lang.Compiler compile "Compiler.java" 7909]
[clojure.lang.RT compile "RT.java" 411]
[clojure.lang.RT load "RT.java" 457]
[clojure.lang.RT load "RT.java" 424]
...
Trying to debug. When I eval my app namespace in REPL, I get this:
ERROR in () (:)
expected: (hyperfiddle.rcf/= (analyze {} (quote (try 1 (catch Exception e 2) (finally 3)))) [(ir/pub (ir/literal nil) (ir/bind 1 1 (ir/pub (ir/apply (assoc (ir/global :hyperfiddle.electric.impl.runtime/latest-first) :hyperfiddle.electric.debug/meta {}) (ir/apply (assoc (ir/global :hyperfiddle.electric.impl.runtime/bind) :hyperfiddle.electric.debug/meta {}) (assoc (ir/global :hyperfiddle.electric.impl.runtime/recover) :hyperfiddle.electric.debug/meta {}) (ir/apply (assoc (ir/global :clojure.core/some-fn) :hyperfiddle.electric.debug/meta {}) (ir/apply (assoc (ir/global :hyperfiddle.electric.impl.runtime/clause) :hyperfiddle.electric.debug/meta {}) (ir/apply (assoc (ir/global :clojure.core/partial) :hyperfiddle.electric.debug/meta {}) (ir/inject 0) (assoc (ir/constant (ir/pub (ir/apply (assoc (ir/global :hyperfiddle.electric.debug/unwrap) :hyperfiddle.electric.debug/meta {}) (assoc (ir/node 0) :hyperfiddle.electric.debug/name (quote hyperfiddle.electric.impl.compiler/exception) :hyperfiddle.electric.debug/scope :dynamic)) (ir/apply (ir/literal {}) (ir/sub 1) (ir/pub (assoc (ir/node 0) :hyperfiddle.electric.debug/name (quote hyperfiddle.electric.impl.compiler/exception) :hyperfiddle.electric.debug/scope :dynamic) (ir/apply (ir/literal {}) (ir/sub 1) (ir/bind 1 1 (ir/literal 2))))))) :hyperfiddle.electric.debug/type :catch :hyperfiddle.electric.debug/args (quote [Exception e]))) (assoc (ir/global :java.lang.Exception) :hyperfiddle.electric.debug/meta {}))) (assoc (ir/constant (ir/literal 1)) :hyperfiddle.electric.debug/type :try :hyperfiddle.electric.debug/meta nil)) (assoc (ir/constant (ir/literal 3)) :hyperfiddle.electric.debug/type :finally)) (ir/apply (ir/literal {}) (ir/sub 1) (ir/pub (ir/literal 0) (ir/apply (ir/literal {}) (ir/sub 1) (ir/bind 2 1 (ir/variable (ir/sub 2))))))))) (ir/do [] (ir/do [(ir/target []) (ir/target []) (ir/target []) ir/source] ir/nop))])
actual: clojure.lang.ExceptionInfo: Unable to resolve symbol: hyperfiddle.electric/trace
{:in [(clojure.core/binding [hyperfiddle.electric/trace hyperfiddle.electric.impl.compiler/exception] 2)]}
at hyperfiddle.electric.impl.compiler$analyze_form.invokeStatic (compiler.clj:643)
hyperfiddle.electric.impl.compiler$analyze_form.invoke (compiler.clj:628)
dunno if it could be related?Fixed by bumping Electric to latest starter app version: v2-alpha-349-ge9996713
We have never seen this
JVM method size is limited to 64k, I think. The way clojure compiles data structure literals, large data structures can exceed this limit. Easiest work around is to split the function into smaller functions
It's possible there was some weird cache thing in target/classes and by changing deps it cleared cache 🤷 ? Not going to investigate further.
Using v349 getting this Method code too large
error again on a project I haven't touched in a while when building uberjar on host machine (not in Docker). I'm guessing it's something Java / deps related and not about Electric, so gonna try clear deps cache and see if it helps.
{:clojure.main/message
"Execution error (IndexOutOfBoundsException) at clojure.asm.MethodWriter/computeMethodInfoSize (MethodWriter.java:2061).\nMethod code too large!\n",
:clojure.main/triage
{:clojure.error/class java.lang.IndexOutOfBoundsException,
:clojure.error/line 2061,
:clojure.error/cause "Method code too large!",
:clojure.error/symbol clojure.asm.MethodWriter/computeMethodInfoSize,
:clojure.error/source "MethodWriter.java",
:clojure.error/phase :execution},
:clojure.main/trace
{:via
[{:type clojure.lang.Compiler$CompilerException,
:message "Syntax error macroexpanding at (prod.clj:1:1).",
:data
{:clojure.error/phase :execution,
:clojure.error/line 1,
:clojure.error/column 1,
:clojure.error/source "prod.clj"},
:at [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3719]}
{:type java.lang.IndexOutOfBoundsException,
:message "Method code too large!",
:at
[clojure.asm.MethodWriter
computeMethodInfoSize
"MethodWriter.java"
2061]}],
:trace
[[clojure.asm.MethodWriter
computeMethodInfoSize
"MethodWriter.java"
2061]
[clojure.asm.ClassWriter toByteArray "ClassWriter.java" 457]
[clojure.lang.Compiler compile "Compiler.java" 7909]
[clojure.lang.RT compile "RT.java" 411]
[clojure.lang.RT load "RT.java" 457]
[clojure.lang.RT load "RT.java" 424]
[clojure.core$load$fn__6908 invoke "core.clj" 6161]
[clojure.core$load invokeStatic "core.clj" 6160]
[clojure.core$load doInvoke "core.clj" 6144]
[clojure.lang.RestFn invoke "RestFn.java" 408]
[clojure.core$load_one invokeStatic "core.clj" 5933]
[clojure.core$load_one invoke "core.clj" 5928]
[clojure.core$load_lib$fn__6850 invoke "core.clj" 5975]
[clojure.core$load_lib invokeStatic "core.clj" 5974]
[clojure.core$load_lib doInvoke "core.clj" 5953]
[clojure.lang.RestFn applyTo "RestFn.java" 142]
[clojure.core$apply invokeStatic "core.clj" 669]
[clojure.core$load_libs invokeStatic "core.clj" 6016]
[clojure.core$load_libs doInvoke "core.clj" 6000]
[clojure.lang.RestFn applyTo "RestFn.java" 137]
[clojure.core$apply invokeStatic "core.clj" 669]
[clojure.core$require invokeStatic "core.clj" 6038]
[clojure.core$require doInvoke "core.clj" 6038]
[clojure.lang.RestFn invoke "RestFn.java" 619]
[prod$loading__6789__auto____140 invoke "prod.clj" 1]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3714]
[clojure.lang.Compiler compile1 "Compiler.java" 7748]
[clojure.lang.Compiler compile1 "Compiler.java" 7738]
[clojure.lang.Compiler compile "Compiler.java" 7815]
[clojure.lang.RT compile "RT.java" 411]
[clojure.lang.RT load "RT.java" 457]
[clojure.lang.RT load "RT.java" 424]
[clojure.core$load$fn__6908 invoke "core.clj" 6161]
[clojure.core$load invokeStatic "core.clj" 6160]
[clojure.core$load doInvoke "core.clj" 6144]
[clojure.lang.RestFn invoke "RestFn.java" 408]
[clojure.core$load_one invokeStatic "core.clj" 5933]
[clojure.core$compile$fn__6913 invoke "core.clj" 6171]
[clojure.core$compile invokeStatic "core.clj" 6171]
[clojure.core$compile invoke "core.clj" 6163]
[user$eval136$fn__137 invoke "compile.clj" 5]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 667]
[clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1990]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1990]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[user$eval136 invokeStatic "compile.clj" 1]
[user$eval136 invoke "compile.clj" 1]
[clojure.lang.Compiler eval "Compiler.java" 7194]
[clojure.lang.Compiler load "Compiler.java" 7653]
[clojure.lang.Compiler loadFile "Compiler.java" 7591]
[clojure.main$load_script invokeStatic "main.clj" 475]
[clojure.main$script_opt invokeStatic "main.clj" 535]
[clojure.main$script_opt invoke "main.clj" 530]
[clojure.main$main invokeStatic "main.clj" 664]
[clojure.main$main doInvoke "main.clj" 616]
[clojure.lang.RestFn applyTo "RestFn.java" 137]
[clojure.lang.Var applyTo "Var.java" 705]
[clojure.main main "main.java" 40]],
:cause "Method code too large!",
:phase :execution}}
Different error happens when building in a Docker:
#26 39.28 -> Closure - Optimizing ...
#26 42.93 Optimizing CLJS Constants took 187ms
#26 159.0 Execution error (StackOverflowError) at com.google.javascript.jscomp.CodeGenerator/add (CodeGenerator.java:201).
#26 159.0 null
#26 159.0
#26 159.0 Full report at:
#26 159.0 /tmp/clojure-11715170771542413787.edn
------
Dockerfile:24
--------------------
22 | ARG REBUILD=unknown
23 | ARG VERSION
24 | >>> RUN clojure -X:build uberjar :jar-name "opentax.jar" :version '"'$VERSION'"' :optimizations :advanced :verbose true
25 |
26 | FROM amazoncorretto:11 AS app
--------------------
ERROR: failed to solve: process "/bin/sh -c clojure -X:build uberjar :jar-name \"opentax.jar\" :version '\"'$VERSION'\"' :optimizations :advanced :verbose true" did not complete successfully: exit code: 1
Pushed to Dokku and it seems to build 🤷 . So must be deps state issue
i am traveling next 4 days but something to check is the heap size JVM flags, we customize this in the starter app
i think this probably is related to electric, we have macroexpansion size problems and compile time memory problems (incremental compilation is the next step)
I'm having issues with core.match: > An error occurred while generating code for the form. > ExceptionInfo: failed compiling constant: interface clojure.lang.IPersistentVector; java.lang.Class is not a valid ClojureScript constant.
namespace:
(ns seshat.core
....
#?(:clj (:require [clojure.core.match :refer [match]]
[seshat.state :refer [bindings]]
[datomic.api :as d])
:cljs (:require [cljs.core.match :refer-macros [match]])))
if ti comment out the first pattern it works. Seems like as soon as I introduce a vector pattern it stops working
I'm not surprised, just wrap it in a clojure lambda (inline or extract a fn) as a workaround
We'd have to take a look at what it is doing, perhaps we are missing some feature, or perhaps it is doing Bad Stuff
oh, hmm
Send me what you have so I can grok the specifics
more complete / real world:
(let [[path query hash] history/location]
(e/server
(match path
[:link :tink & rest]
(new tink/LinkAccount rest query)
[:account type id]
(new account/View (e/client (keyword (name type) id)) hash)
:else
(new NotFound))))))))))
@U05AL1ZH8TW might be worth trying one of the other match libs
I will need to remember how core.match works it has been a long time
@U09K620SG for your reference, here's the macroexpand of a simpler case that also breaks:
(macroexpand '(match 123
[:a :b] "a b"
:else "else"))
=>
(let*
[ocr-56553 123]
(try
(clojure.core/cond
(clojure.core/and (clojure.core/vector? ocr-56553) (clojure.core/== (clojure.core/count ocr-56553) 2))
(try
(clojure.core/let
[ocr-56553_0__56555 (clojure.core/nth ocr-56553 0)]
(clojure.core/cond
(clojure.core/= ocr-56553_0__56555 :a)
(try
(clojure.core/let
[ocr-56553_1__56556 (clojure.core/nth ocr-56553 1)]
(clojure.core/cond (clojure.core/= ocr-56553_1__56556 :b) "a b" :else (throw clojure.core.match/backtrack)))
(catch
Exception
e__38244__auto__
(if
(clojure.core/identical? e__38244__auto__ clojure.core.match/backtrack)
(do (throw clojure.core.match/backtrack))
(throw e__38244__auto__))))
:else
(throw clojure.core.match/backtrack)))
(catch
Exception
e__38244__auto__
(if
(clojure.core/identical? e__38244__auto__ clojure.core.match/backtrack)
(do (throw clojure.core.match/backtrack))
(throw e__38244__auto__))))
:else
(throw clojure.core.match/backtrack))
(catch
Exception
e__38244__auto__
(if (clojure.core/identical? e__38244__auto__ clojure.core.match/backtrack) (do "else") (throw e__38244__auto__)))))
thanks
exceptions as control flow + electric smells like trouble, that hits us right in a problem area of interop
stack trace for that one:
[:dev] Build failure:
------ ERROR -------------------------------------------------------------------
File: /home/s-ol/Documents/other/seshat/src/user.cljs:7:1
--------------------------------------------------------------------------------
4 | hyperfiddle.electric
5 | hyperfiddle.electric-dom2))
6 |
7 | (def electric-main
-------^------------------------------------------------------------------------
An error occurred while generating code for the form.
ExceptionInfo: failed compiling constant: interface clojure.lang.IPersistentVector; java.lang.Class is not a valid ClojureScript constant.
cljs.compiler/fn--4087 (compiler.cljc:306)
cljs.compiler/fn--4087 (compiler.cljc:303)
clojure.lang.MultiFn.invoke (MultiFn.java:229)
cljs.compiler/emit-constant-no-meta (compiler.cljc:285)
cljs.compiler/emit-constant-no-meta (compiler.cljc:277)
cljs.compiler/emit-constant (compiler.cljc:301)
cljs.compiler/emit-constant (compiler.cljc:297)
cljs.compiler/emit-constants-comma-sep/fn--4122/fn--4123 (compiler.cljc:417)
clojure.core/map-indexed/mapi--8638/fn--8639 (core.clj:7378)
it's optimized (i think? in theory?)
is that in a e/server or an e/client?
@U09K620SG any recommendation for core.match alternatives (esp if you've tried them in electric)
we haven't checked any of them
also taking general suggestions then, not finding much tbh since core.match seems to be getting traction
trying https://github.com/dcolthorp/matchure, will report back
But uses spec - we haven't checked that either
actually maybe we have, I think we do have stuff using spec actually
that one doesn't do destructuring, which is half the benefit of using pattern matching for routing
Do you have a one-liner demonstrating the requirement wrt destructuring, do you just mean this : [:account type id]
(e/defn Todo-list []
(e/client
(dom/h1 (dom/text "core.match test"))
(dom/pre
(dom/text
(pr-str
(e/server
(match [:b]
[:a] "A"
[x] x
:else "fail")))))))
this much is working for mei can rep your error, which is also a type error right?
(match 123 x x :else "fail")
works
I'm not sure? it doesn't say type error anywhere but it complains about something being a class rather than a constant
(match 123 [x] x :else "fail")
is a weird compiler error
clj꞉user꞉> (require '[clojure.core.match :refer [match]])
nil
clj꞉user꞉>
(match 123 x x :else "fail")
123
clj꞉user꞉>
(match 123 [x] x :else "fail")
"fail"
at JVM repl this worksso it's confirmed an electric interaction afaict
well the good news is I tested every usage in the basic tutorial and only one failed, the vector match
So my concerns about exception control flow seems to be not an issue
aaaand it worked in clojurescript (e/client), it only fails in e/server
I'll ticket it at this point, it is likely a simple bug in electric
minimal repro is (match [[1]] [[1]] 'pass)
, it's the matching of the vector type. (match [1] [1] 'pass)
passes
Do you really need to match an inner vector? If your paths have static width i dont think you will hit this
The core.match wiki implies this is just an optimization anyway for random access matching
For matching dynamic args the sequence syntax works (as a workaround)
(match [[:foo :bar 1 2 3]]
[([:foo x & args] :seq)] args) ; works
; compare to
(match [[:foo :bar 1 2 3]]
[[:foo x & args]] args) ; crash
cursed syntax thoughDon't you want the route matching to happen on the client anyway?
works
(e/defn Baz [a] (dom/text "Baz" (pr-str a)))
(e/defn Bar [a] (dom/text "Bar" (pr-str a)))
(e/defn Todo-list []
(e/client
(dom/h1 (dom/text "core.match test"))
(dom/pre
(let [page [:foo :bar 1]]
(match [page]
[[:foo :baz a]] (Baz. a)
[[:foo :bar a]] (Bar. a)
:else (dom/text "404"))))))
had moved it to server as a convenience since the views are server-colored so were all wrapped in e/server but yeah I'll try client!
away from computers this weekend but I don't think I had nested vectors? iirc I had this issue with top-level vector matches
you mean fixed arity tuples? (the core.match syntax is cursed, one or both of us may be confused)
in the matches, [] just means “pattern row” according to a footnote at the bottom of one of the wiki pages
> moved [router] to server as a convenience since the views are server-colored so were all wrapped in e/server but yeah I'll try client!
note that the variable inputs to the router are a user interaction on the client, so your DAG looks something like this: user event -> router -> views
. So it doesn't seem to matter whether the router is on the client or server
i.e., both of these factorings are the same:
[client: event] -> [server: router -> views]
[client: event -> router] -> [server -> views]
Note that a UI may have client-only pages (i.e. storing local state in URL), in which case the factorings are no longer the same and co-locating the router with the user interaction becomes preferred to avoid a superfluous round trip
yeah, it has little impact in my case. With "for convenience" I guess I really meant brevity; having one e/server around the whole router block vs one e/server per each View being invoked
might be the case that some network round trips could be eliminated but I'm not attempting any optimization at this point
> in the matches, [] just means “pattern row” according to a footnote at the bottom of one of the wiki pages > hm, indeed I am confused now. Will get back to you about this when I next give it a go
okay, so: e/client (match) is working great, thanks for reminding me to try it out again.
the pattern vs pattern row thing is a bit confusing. I'm currently using a single []
syntax to match against a flat vector-of-strings value:
(e/server
(match hash
[:tx :new]
(new transaction/View "new-tx" {"new-tx" {:tx/label "new transaction"}})
;:tx/value-time (new js/Date)}})
;[:tx id]
;(new transaction/View (js/parseInt id) nil)
nil nil
:else
(new NotFound))
(match path
[:link :tink & rest]
(new tink/LinkAccount rest query)
[:account type id]
(new account/View (e/client (keyword (name type) id)) hash)
:else
(new NotFound))))))))))
this works e/client and fails in e/server with the IPersistentVector error posted abovein the wiki section on https://github.com/clojure/core.match/wiki/Overview#vector-matching they use [[a b]]
which suggests that the "outermmost [] is special", but they also have an example with "https://github.com/clojure/core.match/wiki/Overview#matching-single-variables" without any wrapping which is odd again. I've tried doubling-up to (match [hash] [[*:tx :new*]] (new ...
but am getting the same error on e/servre
i agree that the "single variable" section seems exceptional
I am confident enough now to just state that core.match has cursed syntax and sucks actually