Hi, I’ve been recently trying to load an in-house lib I. Clojure to play with it without success. I can’t really paste any code here, but I can describe the issue I’m facing. There are two jars in a folder along with bunch of other stuff. The jars just wrap a C++ quants lib as far as I’m aware. If u include these in a java project and call the libs ‘version’ function, fine it works. If I do the same in Clojure, when I invoke ‘version’, I get an error saying some class doesn’t exist. Now I’ve tried every way to include jars in a lein project that Google and AI tools suggest but no luck. I tried looking for the offending class inside the two jars but there’s no such class. All I can gather is this is some weird classloader issue. What can I do here?
What do you mean by "version function" and how are you calling it, and does the error actually give a full class name of a class in one of the jars is not found, or something else?
Let's take a step back. Can you do basic java interop with something like java.time.LocalDate for instance?
> If u include these in a java project and call the libs ‘version’ function, fine it works. How do you include these libs in the java project? My guess is that you also need to augment your classpath when launching clojure to include these libs.
Sorry for late reply.
I'm renaming the libs and obscuring some stuff, don't wanna get in trouble is all.
I'm on windows.
@hiredman Static function.
(ns jq.core (:import [com.xx.xx Q])
Import itself is fine.
(Q/Version)
This throws errors. See below.
@matti.uusitalo117 All other interop is fine. I've only encountered this issue with this lib.
@smith.adriane Just a dummy project in intellij and add external libs and call com.xx.xx.Q/Version()
project.clj:
I put the entire lib folder in resources/q having tried many different things
:resource-paths ["resources/q/q_j_q1.jar" "resources/q/q_j_q2.jar" "resources/q"]
Errors in REPL:
(Q/Version)
; Syntax error (ClassNotFoundException) compiling . at (core.clj:9:3).
; com.xx.xx.q.qs$Scenario
Stacktrace (redacted)
*eI've spent some time on this doing stupid hacks but nothing seems to work. This "missing" class doesn't seem to exist in the jars either.
It may be that the missing class is there on the class path when you are using it from Java
@matti.uusitalo117 I can get the classpath from the run command in intellij project. Is there a way to feed this classpath to lein so it'll use the same?
If you rely purely on IDEA for the classpath management, I'd suggest to reconsider. It's a very, very brittle approach.
Since you have "free-floating" jars around, you should be able to add them to project.clj as well. I don't use Lein myself, but apparently you can add :resource-paths ["path/to/the.jar"].
It is due to importing the outer class, but trying to use the short name with an inner class
Inner and outer classes are a feature of the java language, at the jvm level they are just different classes one named Foo and one named Foo$Bar
@p-himik I already added the jars to resource-paths, please see my comment above.
@hiredman So is the java implementation of Q/Version is faulty? I'm just calling that function in both java and clojure. In java, it works, in Clojure it doesn't. How do I get the Clojure version working? What can I try?
No
Hard to tell with so much redaction, but it looks like you are importing Foo and trying to do (Foo$Bar/whatever)
You need to import Foo$Bar
@hiredman sorry, perhaps I wasn't clear.
java:
System.out.println(com.xx.yy.Q.Version()) -- Works fine.
clojure:
println(com.xx.yy.Q/Version)
Note that the inner class in error is different. It must be some dependency.
> I already added the jars to resource-paths, please see my comment above.
Ah, sorry I missed that, yeah.
> Note that the inner class in error is different. It must be some dependency.
Where does that class come from when everything works?
Is that place on the classpath of the Clojure project, as specified by project.clj?
@p-himik > Where does that class come from when everything works? How do I figure this out? Because I'm not explicitly using it. It was some time ago but I checked the jars for this class but couldn't find where it is. Perhaps I should try again.
One other guess I had was that this inner class was dynamically generated. After all, the jars are wrappers over some C++ quant stuff
But still I don't understand why it'd work in the java case but not in the clj one
> How do I figure this out? I'd ask the web. ;) It's a one-liner in Java that I don't quite recall.
(-> (.getClassLoader clojure.lang.Symbol)
(.getResource "java/util/List.class"))
=> #object[java.net.URL 0x117ec467 "jrt:/java.base/java/util/List.class"]
In your case, you're trying to see where the outer class is located, since the inner class is a part of it and will be in the same file.Both clojure and java version for this fail. I don't have access to source for this lib so I can't check either.
Weird. Does the Java app do something unusual with class loaders? Since you have IDEA, it should be possible to figure out with its debugger how exactly that class is loaded. But I can't help here with detailed steps.
It's failing to find the inner class it seems
This is a question that has (probably) been asked a million times (also good beginner question 😄), but I could not find a definitive answer on the interwebs or on this slack.
Anyway, the question: what is the idiomatic way to compare two datetime strings in Clojure? More precisely, given an input x, such that x is a string formatted as an iso-8601 datetime string (e.g. "2025-01-01T12:00:00Z"). How can I check whether x is before or after y, where y is the current time also formatted as an iso-8601 datetime string?
I almost always default to parsing the strings as java.time.Instant but my colleague suggested using java string's .compareTo method, which is not something I've really seen be used before 🤔
that will compare strings lexicographically https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#compareTo-java.lang.String-
i think for reasonable stuff it will probably work just fine
obviously that will work iff the string rep is lexicographically sortable
From the Wiki article on ISO 8601:
> The lexicographical order of the representation thus corresponds to chronological order, except for date representations involving negative years or time offset.
Not sure why it says that about negative years -
Ah, duh - - goes before digits.-1 would go before -2.