Fork me on GitHub

You probably have a good reason but just out of curiosity, why aren't you using one of the projects that have solved this already for Minecraft like Paper or Fabric?


Fabric still uses mappings to intermediate class names for everything in net.minecraft


It does seem that in Paper you get the deobfuscated classes


unzip -l PaperMC/cache/patched_1.17.1.jar | grep minecraft > /tmp/nms_classes.txt


i'm interacting with this "messed up" java API that routinely has 10-15 args to functions, most of which I just have to set to nil. Is there a nicer way of writing something like this?


(.callFn api param1 nil nil nil nil nil nil nil nil nil nil nil nil nil ...)


wrap this call to a function and use it instead

(defn call-java-api [param]
  (.callFn api param nil nil ...))


that would hide things where specific calls are reused, but usually it's a call once situation for each. so parts of the code get littered with these calls with 14 nils in them. but I guess you're right; the only sensible way out of it is to write my own wrapper api that accepts the params I need


@U52RNHDRN Are those 14 nils just default values? if so

(defn call-fn-api [api {:keys [a b c]}]
  (.callFn api a b c))

☝️ 1

(call-fn-api api {:a 12 :c 4})


hi, please help how i can create java *Map*<*String*,*Class*<?>> in clojure? I assume just {"boo" SomeClass} not exactly the same? 🙂


It is exactly the same :)


not sure if a type hint would suffice? {"foo" ^SomeClass someClass}


"suffice" - generics only exist inside javac, so the type hint is just noise, there's nothing there for it to help


(Generics in Java are erased, meaning at the bytecode level it’s all the same)


And for the pedantic&curious, there’s exactly one corner case where this isn’t true - 🙂


ah, that easy awsome, thanks a lot!


java.awt.FontRenderContext has two constructors of arity 3:

public FontRenderContext(AffineTransform tx, boolean isAntiAliased, boolean usesFractionalMetrics)
public FontRenderContext(AffineTransform tx, Object aaHint, Object fmHint)
I'm not seemingly able to call the first one (with booleans) and always getting the second Object one. I can work around this but is it possible to guide the compiler to choose that one at all?
(let [^Boolean aliased true
      ^Boolean fractional true]
  (FontRenderContext. (AffineTransform.) aliased fractional))
(FontRenderContext. (AffineTransform.) true true)
both yield > Execution error (IllegalArgumentException) at java.awt.font.FontRenderContext/<init> ( > AA hint:true whereas this does not throw an error:
(FontRenderContext. (AffineTransform.)


What if you replace ^Boolean with ^boolean?


ah that works. i messed up the wrapper.


This should be a simple question for y’all. What’s the industry standard for logging in Clojure? I could make a function like so:

(defn log [msg]
  (println msg)
But I want to hear your opinions.


I've been happy with timbre

Joshua Suskalo16:08:17 is basically the standard for libraries. For end-user applications you get the choice between an implementation of tools.logging like logback or something like timbre. You shoultn't use timbre for libraries though because it tries to force the whole application to use it.


I honestly have no idea what the upside to timbre is (besides aesthetics).

💯 2

logback is the actual industry standard


tools.logging is fine

Joshua Suskalo16:08:16

Logback is an implementation of SLF4J. In the Java world it's often more SLF4J which is the standard, and logback is just the goto default implementation. tools.logging is a clojure frontend for SLF4J (and a couple others), so it's a good option.

dorab16:08:42 Also, look at Sean Corfield's use of log4j2 in the place of logback.


In babashka I went with timbre since it's quite handy for scripts to not require any XML files along with the script. It's available through the facade


I would like more such "interface" libraries where the impl is chosen at runtime, so libraries aren't directly tied to a specific impl. E.g. for JSON, we could have a thing instead of directly using, cheshire or jsonista

💯 2
👍 2

Timbre fell out of favor for Juxt In practice it's pretty great, pleasure to use. Still I do find it has it flaws that can show up with advanced-ish usages. Java rejection turns out to be a mistake in a JVM lang. is a nice rich choice - does not depend on other Pedes parts. also deserves a honorable mention


We’ve been using timbre in production for years and years.


that exists separatedly and uncoordinatedly from its parent is just bad tbh.


We started out with tools.logging, switched to Timbre, then switched back to tools.logging, backed by log4j2 now (we like the variety of config options and that it can reload its configuration while its running). But logging in Java is just a gigantic can of worms.


countdown to a logging lib called ivermectin rimshot


I've just been using tools.logging with logback or log4j2. I'd recommend against any other Java backends, they all have known prod issues (either performance or deadlocks) under high load and stress. I have not tried timbre


timbre definitely does not improve performance


I had built a slf4j -> clojure Var adapter, wish I made it public


you could use it instead of logback or log4j


I’ve been using timbre for the longest time and generally have no issues with it, but my needs are pretty simple atm. Do the other tools like tools.logging support ClojureScript as well? (as far as I can tell - no, but please correct me if I’m wrong)


Does clojurescript need anything besides console#log?


Maaaaybe for node? But even that’s fairly questionable. The reason you need a logging framework for the JVM is 1) to order messages from many threads, and 2) because there are multiple places you might want messages to go (e.g. stdout/a file/a socket).


I could imagine wanting more features if you are running node, but no tools.logging contains no cljs or cljc code, and is full of interop

👍 1

For new project we have used mulog which allows us to created very meaningful log events and easily search through them It's so effective to use and a joy to develop with, we are going to refactor our other projects to use it.


^ looks very nice 👀 , will need to take a closer look, thanks