Fork me on GitHub
#java
<
2018-05-08
>
Drew Verlee20:05:04

I have told gradle about my local jar file and it seems to be correctly placing it in my library. However, i want to invoke the clojure functions contained inside of it. I’m able to use invoke clojure functions just fine: require.invoke(Clojure.read("clojure.core") however i’m getting an error when i try to require the namespace of my library:

Could not locate fk_gen/core__init.class or fk_gen/core.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
` The error is really clear. But i’m not sure how to troubleshoot it. I assume i should 1. figure out the classpath my java ...process is looking at. 2. understand what determines the classpath of my functions inside my jar. I understand abstractly what this all about, but the details seem to be eluding me.

hiredman20:05:38

it sounds like you have the clojure jar on the classpath, but not the jar containing your code

hiredman20:05:03

a jar file is just a zip file, so you should be able to unzip the jar and see what files are inside it to verify if it contains your code or not

Drew Verlee20:05:43

@hiredman that sounds right. the fact it doesn’t expand in my editor is troubling lol

Drew Verlee21:05:02

it does contain my code. I’m probably doing something even more basic wrong.

hiredman21:05:24

what do you mean? does it contain a file fk_gen/core.clj or a file fk_gen/core__init.class?

seancorfield21:05:21

And the namespace of your library is fk-gen.core?

Drew Verlee23:05:11

@hiredman if I unzip that jar via jar xf fk-gen-0.3.3-alpha.jarit expands to contain fk_gen/core.clj @seancorfield (ns fk-gen.core...) so yes. I believe thats a valid namespace?

seancorfield23:05:43

And that JAR is on the classpath when you start your Java code? Or should I ask: how are you running your Java code?

Drew Verlee23:05:47

@seancorfield I believe so, though as i said, i’m unsure of how to introspect my class path in different environments. I seem to be making progress as i pulled in the clj files for my library. Now its complaining that it can’t find the dependencies for my library 🙂.

seancorfield23:05:35

Sounds like you didn't build your Clojure code JAR the right way?

seancorfield23:05:48

Java doesn't like you taking shortcuts with dependencies (this is why "local JAR file" is a bad idea in nearly all cases).

Drew Verlee23:05:51

@seancorfield thats possible. it occurs to me that this would need to be a uberjar (contain all the deps) for me to use it locally. But that seems to require a gen-class and a main function… which doesn’t make doesn’t make sense for a library. Do you have a suggestion on a workflow for when you want to interopt by calling clojure code from java? I tried to hit like the first 20 links and mostly got docs which didn’t seem specific answering my question of how to ‘easily’. I’m trying to rush this so I probably just need to back up and read that documentation

Drew Verlee23:05:13

or maybe a uberjar doesn’t require a main entry point… i think the docs i’m reading just word things to imply it.

Drew Verlee23:05:23

right, so importing the uberjar seems to be working. Which hopefully saves the demo i plan on doing tomorrow 🙂. I’ll go back and fill in the blanks later.

seancorfield23:05:49

Uberjar does NOT require gen-class or AOT!

seancorfield23:05:53

You can make an uberjar with zero AOT (well, except Clojure itself since that ships with part/all of it AOT'd, right?) and you can specify clojure.main as the main entry point.

seancorfield23:05:57

To play nice in the Java ecosystem as "just" a library JAR, you need to generate a POM with your dependencies, and have it in a Maven-like repo (or local .m2 cache) for other Java tools to use it easily.

seancorfield23:05:56

So if you create a local JAR, you also need to create a pom.xml, and then you could lein-localrepo install it into .m2 (or put it in a Maven-like shared repo), when Gradle can just be pointed at that coordinate.

seancorfield23:05:27

If your Clojure code uses libraries from Clojars, Gradle will also need to be told to look in Clojars (as well as Maven Central).

seancorfield23:05:47

When we call Clojure from Java, we start the Java process with the classpath that Leiningen or Boot would use to run the Clojure code.