adambard / failjure

Monadic error utilities for general use in Clojure(script) projects
Eclipse Public License 1.0
411 stars 17 forks source link

Please aot compile core.cljs #24

Closed pieterbreed closed 3 years ago

pieterbreed commented 3 years ago

Problem

We have the following issue/exception when we're importing failjure during dev-time (repl-based workflow):

java.lang.NoClassDefFoundError: failjure/core/HasFailed
    at bulk_gateway.rest.accounts$get_acccount_balance.invokeStatic(accounts.clj:68)
    at bulk_gateway.rest.accounts$get_acccount_balance.invoke(accounts.clj:52)
...

Background

We've had similar issues with our own shared libraries that have (defprotocol ... in them and solved it by adding an :out [...] in the project.clj of the client lib project.

Solution

I cloned your repo locally and added an :aot [failjure.core] to failjure's project.clj and our issue goes away after lein install.

As far as I know this should be no-impact change for clients.

(defproject failjure "2.1.1"
  :description "Simple helpers for treating failures as values"
  :url         "https://github.com/adambard/failjure"
  :license     {:name "Eclipse Public License"
                :url "http://www.eclipse.org/legal/epl-v10.html"}

  :dependencies []

  :repl-options {:init-ns failjure.core}

  :plugins [[lein-cljsbuild "1.1.8"]
            [lein-doo "0.1.10"]]

  :aot [failjure.core]

  :profiles
  {:provided {:dependencies [[org.clojure/clojure       "1.10.1"]
                             [org.clojure/clojurescript "1.10.764"]]}}
  :cljsbuild
  {:builds [{:id "test"
             :source-paths ["src" "test"]
             :compiler {:output-to "target/testable.js"
                        :main failjure.runner
                        :target :nodejs
                        :optimizations :none}}]})
pieterbreed commented 3 years ago

Hi @adambard , can confirm that [failjure "2.2.0-SNAPSHOT"] fixes the issue; we've been running it in our services for the past week and the initial problem has been resolved with it.

adambard commented 3 years ago

Excellent news! I have now deployed this as failjure 2.2.0. Thanks for the report (and reminder)!

vemv commented 3 years ago

I added a comment in https://github.com/adambard/failjure/commit/c6e528c1eda6ad5eaab0f1fb2a97e766bf41fdd5

Suggesting that a third-party lib AOT-compiles "fourth-"party code seems quite clearly a fragile idea.

Wouldn't have been a cleaner fix to AOT-compile clojurescript in the consumer app itself? These intricacies can almost always be fixed consumer-side.

(a reproducible failure script would help)

pieterbreed commented 3 years ago

For me, this problem came about in clojure on the JVM. I got a java.lang.NoClassDefFoundError on the protocol interface (failjure/core/HasFailed) itself, when trying to consume failjure directly in our namespaces. We use a (require "namespace") to load our internal ns's rather than (:require ...) due to how we do components, it might have something to do with that, I can't tell.

I don't use failjure for clojurescript (yet) so cannot speak to that aspect.

If upgrading to the new clojure fixes the problem, then that's awesome and aot is not required. But the .class for the JVM Interface needs to be there and isn't at a critical time for us; aot solves that problem.

Happy to hear more of your thoughts.

Pieter

vemv commented 3 years ago

aot solves that problem

I don't mean to be snarky but this can also be phrased as "works around that problem". This is particularly true when there isn't a reproducible problem.

Btw, if facing issues, in Clojurians Slack #clojure it's quite common to find expert help :) it seems worth a shot if everything else fails.

Personally I'd be interested in using failjure, but having AOT in the way is a blocker.

john-shaffer commented 3 years ago

@vemv Since failjure currently has no dependencies, I don't think there's any risk of causing dependency conflicts. Just to double-check, I inspected the jar for failjure 2.2.0. It contains nothing but failjure itself.

vemv commented 3 years ago

However one can observe the following release notes:

image

this can serve as evidence that AOTed Clojure code isn't necessarily compatible across versions.

AFAICT There's no guarantee whatsoever of bytecode compatibility reflected in https://clojure.org/, so it's cautious to follow the community practice of only releasing .clj sources.