biff

Xarlyle0 2025-04-18T14:16:47.474059Z

What is the best way solve conflicts with logging issues? I've been struggling the last week to solve some logging issues among dependencies. I've been trying to put Rama as a backend to a Biff frontend. Simply including the two dependencies together in a deps.edn:

com.rpl/rama {:mvn/version "0.22.0"}
com.biffweb/biff #:git{:url "", :sha "1570ccc", :tag "v1.8.29"}
Results in a java.lang.AbstractMethodError with org.apache.logging.slf4j.SLF4JServiceProvider ; java.lang.AbstractMethodError: Receiver class org.apache.logging.slf4j.SLF4JServiceProvider does not define or inherit an implementation of the resolved method 'abstract java.lang.String getRequestedApiVersion()' of interface org.slf4j.spi.SLF4JServiceProvider. After reading https://lambdaisland.com/blog/2020-06-12-logging-in-clojure-making-sense-of-the-mess, I tried using an exclusion to solve it:
com.rpl/rama {:mvn/version "0.22.0"
                      :exclusions [org.apache.logging.slf4j/SLF4JServiceProvider]}
com.biffweb/biff #:git{:url "", :sha "1570ccc", :tag "v1.8.29"}
org.slf4j/slf4j-simple     {:mvn/version "2.0.0-alpha5"}
But this results in an even more difficult error: Execution error (ExceptionInInitializerError) at java.lang.Class/forName0 (Class.java:-2). I've essentially been bouncing back and forth between these two errors for the last several days, trying different exclusions and slf4j libs.

👀 1
2025-04-18T17:31:28.552939Z

Is there a way I could reproduce that command? With this in deps.edn:

{:deps {com.rpl/rama {:mvn/version "0.22.0"}
        com.biffweb/biff #:git{:url "", :sha "1570ccc", :tag "v1.8.29"}}}
I just get:
$ clj
Error building classpath. Could not find artifact com.rpl:rama:jar:0.22.0 in central ()
maybe it's in a private repo. Anyway--not sure exactly how to solve this, but as a first step you can narrow down what in biff exactly is causing the dependency conflict. e.g. you can replace your deps.edn file with biff's dependencies:
{:deps {com.rpl/rama                   {:mvn/version "0.22.0"}
        better-cond/better-cond        {:mvn/version "2.1.4"}
        buddy/buddy-sign               {:mvn/version "3.4.333"}
        cider/cider-nrepl              {:mvn/version "0.51.1"}
        clj-http/clj-http              {:mvn/version "3.12.3"}
        com.nextjournal/beholder       {:mvn/version "1.0.2"}
        com.xtdb/xtdb-core             {:mvn/version "1.23.1"}
        com.xtdb/xtdb-jdbc             {:mvn/version "1.23.1"}
        com.xtdb/xtdb-rocksdb          {:mvn/version "1.23.1"}
        info.sunng/ring-jetty9-adapter {:mvn/version "0.17.2"}
        jarohen/chime                  {:mvn/version "0.3.3"}
        lambdaisland/uri               {:mvn/version "1.13.95"}
        metosin/malli                  {:mvn/version "0.16.1"}
        metosin/muuntaja               {:mvn/version "0.6.8"}
        metosin/reitit-ring            {:mvn/version "0.6.0"}
        nrepl/nrepl                    {:mvn/version "1.3.1"}
        org.clojure/tools.deps.alpha   {:git/url ""
                                        :sha "8f8fc2571e721301b6d52e191129248355cb8c5a"}
        org.clojure/tools.logging      {:mvn/version "1.2.4"}
        org.clojure/tools.namespace    {:mvn/version "1.4.4"}
        org.postgresql/postgresql      {:mvn/version "42.6.0"}
        refactor-nrepl/refactor-nrepl  {:mvn/version "3.6.0"}
        ring/ring-defaults             {:mvn/version "0.3.4"}
        rum/rum                        {:mvn/version "0.12.11"
                                        :exclusions [cljsjs/react cljsjs/react-dom]}
        com.biffweb/config             {:git/url ""
                                        :git/tag "v0.7.25"
                                        :git/sha "7e920b2"
                                        :deps/root "libs/config"}
        hawk/hawk                      {:mvn/version "0.2.11"}}}
and then try commenting out half the libs etc to figure out which library/libraries are causing issues with rama. If you narrow it down, you could then try upgrading the problematic libs. (you could also expand those libs with their dependencies to drill down further). If isolating and upgrading the problematic libs doesn't work, then maybe the rama people would know what the problem is? I'd be happy to poke around a bit myself too if there's some way for me to reproduce this.

Xarlyle0 2025-04-18T17:32:11.677619Z

Include this in your deps.edn

:mvn/repos {"rama" {:url ""}}

👍 1
Xarlyle0 2025-04-18T17:33:24.668229Z

That'll allow you to grab Rama. This should allow you to start a REPL. Then, trying to evaluate a simple file like this:

(ns mynamespace
  (:use [com.rpl.rama]))
This creates the errors I mentioned.

Xarlyle0 2025-04-18T17:34:45.970729Z

But thanks for the dependency list! That might be a good way to further narrow things down

2025-04-18T17:40:26.647619Z

Looks like it's the jetty adapter:

{:deps {com.rpl/rama                   {:mvn/version "0.22.0"}
        info.sunng/ring-jetty9-adapter {:mvn/version "0.17.2"}}
 :mvn/repos {"rama" {:url ""}}}
Not super surprised--I've had dependency conflict issues from jetty before (e.g. when trying to use the cognitect aws lib). If you're not using websockets then I think there's no difference in using that jetty adapter and the official one. Let's see if switching that out helps...

2025-04-18T17:41:40.943479Z

Apparently not; I still get the error from this:

{:deps {com.rpl/rama            {:mvn/version "0.22.0"}
        ring/ring-jetty-adapter {:mvn/version "1.14.1"}}
 :mvn/repos {"rama" {:url ""}}}

2025-04-18T17:45:04.200349Z

If you run clj -Stree with that deps.edn file and look for the Xs, you can see which dependencies from rama got overridden. I am seeing that rama uses an older version of jetty (9.4.31) and ring... actually looks like rama depends on ring/ring-jetty-adapter 1.8.2. So if we make biff use that, maybe that'll work.

Xarlyle0 2025-04-18T17:45:50.319579Z

Hang on... Just putting rama and

info.sunng/ring-jetty9-adapter {:mvn/version "0.17.2"}
produces the error, but
cider/cider-nrepl              {:mvn/version "0.51.1"}
fixes it!

Xarlyle0 2025-04-18T17:46:09.184879Z

But then, putting

nrepl/nrepl                    {:mvn/version "1.3.1"}
breaks it again!

2025-04-18T17:46:19.298419Z

very curious

Xarlyle0 2025-04-18T17:47:35.414909Z

So, the logging between nrepl, the adapter, and the apache slf4j provider creates weird problems..

2025-04-18T18:01:32.833019Z

Yeah sounds like it... I've also been a separate class not found exception for com.google.common.io.MoreFiles depending on which libs I include/exclude. That apparently comes from guava. So there might also be some issue with one of biff's dependencies using a different guava version or something.

2025-04-18T18:11:44.965419Z

problem seems to be fixed if I just include these two dependencies:

ring/ring-jetty-adapter {:mvn/version "1.8.2"}
        com.google.guava/guava {:mvn/version "29.0-jre"}

Xarlyle0 2025-04-18T18:14:24.200339Z

So, do you think if I add exclusions for the jetty9 adapter and guava, and then manually add those two, would Biff still work?

2025-04-18T18:18:57.015549Z

no need to exclude anything. I just ran the biff starter app with those two dependencies (and rama) added and it does run, and I can require com.rpl.rama. There is one last issue: trying to load the home page in the browser doesn't work because the rama dep has a public/index.html file in its resources, which is... not what a library should be doing. However we can get around that by hacking biff's middleware so it tries requests against its own reitit routes first before checking for static resources:

diff --git a/starter/src/com/example/middleware.clj b/starter/src/com/example/middleware.clj
index 4162bbe..66966af 100644
--- a/starter/src/com/example/middleware.clj
+++ b/starter/src/com/example/middleware.clj
@@ -1,8 +1,11 @@
 (ns com.example.middleware
-  (:require [com.biffweb :as biff]
+  (:require [clojure.string :as str]
+            [com.biffweb :as biff]
             [muuntaja.middleware :as muuntaja]
             [ring.middleware.anti-forgery :as csrf]
-            [ring.middleware.defaults :as rd]))
+            [ring.middleware.defaults :as rd]
+            [ring.middleware.resource :as res]
+            [ring.middleware.content-type :refer [wrap-content-type]]))
 
 (defn wrap-redirect-signed-in [handler]
   (fn [{:keys [session] :as ctx}]
@@ -31,6 +34,20 @@
       (def response* response)
       response)))
 
+(defn wrap-resource [handler]
+  (fn [{:biff.middleware/keys [root index-files]
+        :or {root "public"
+             index-files ["index.html"]}
+        :as ctx}]
+    (let [response (handler ctx)]
+      (if (not= (:status response) 404)
+        response
+        (or (->> index-files
+                 (map #(update ctx :uri str/replace-first #"/?$" (str "/" %)))
+                 (into [ctx])
+                 (some (wrap-content-type #(res/resource-request % root))))
+            response)))))
+
 (defn wrap-site-defaults [handler]
   (-> handler
       biff/wrap-render-rum
@@ -54,7 +71,7 @@
 (defn wrap-base-defaults [handler]
   (-> handler
       biff/wrap-https-scheme
-      biff/wrap-resource
+      wrap-resource
       biff/wrap-internal-error
       biff/wrap-ssl
       biff/wrap-log-requests))

2025-04-18T18:19:25.642579Z

With that last change in place though everything seems to work perfectly, even the websockets.

Xarlyle0 2025-04-18T18:35:43.435159Z

Hmmm. It seems to be working fine when I put all those in 1 deps.edn, but I had it so that the biff project was in a separate deps.edn which is imported through a

:local/root
and doing it like that brings the errors back again. I am using clj -Stree to try and compare the two setups, as I thought they would work identically, but apparently not..

Xarlyle0 2025-04-18T18:42:16.840319Z

Got It! Thank you so much!

Xarlyle0 2025-04-18T18:42:47.846689Z

I still have a little bit to go to get everything set up, but I hope I can get past any further hurdles now

2025-04-18T18:55:28.296789Z

interesting re: the :local/root thing. maybe something to do with clj's dependency resolution... e.g. I think any version that aren't in the top-level deps.edn are basically suggestions. Good luck in any case! Let me know if you get stuck on anything and I can try to poke around a bit more.

chromalchemy 2025-04-25T16:04:50.248809Z

@foo or @xarlyle0 can you post a gist or example code of this integration?

2025-04-25T17:32:21.335099Z

I think what I ended up was to add this to your deps.edn:

{:deps {...
        com.rpl/rama            {:mvn/version "0.22.0"}
        ring/ring-jetty-adapter {:mvn/version "1.8.2"}
        com.google.guava/guava {:mvn/version "29.0-jre"}}
 :mvn/repos {"rama" {:url ""}}
 ...}
and then make https://clojurians.slack.com/archives/C013Y4VG20J/p1745000337015549?thread_ts=1744985807.474059&cid=C013Y4VG20J

👍 1