java

2018-05-08T20:54:04.000588Z

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.

2018-05-08T20:57:38.000553Z

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

2018-05-08T20:58:03.000724Z

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

2018-05-08T20:58:43.000181Z

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

2018-05-08T21:09:02.000466Z

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

2018-05-08T21:10:24.000001Z

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

seancorfield 2018-05-08T21:15:21.000468Z

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

2018-05-08T23:08:11.000144Z

@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?

seancorfield 2018-05-08T23:09:43.000348Z

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

2018-05-08T23:18:47.000243Z

@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 🙂.

seancorfield 2018-05-08T23:24:35.000199Z

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

seancorfield 2018-05-08T23:25:48.000147Z

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

2018-05-08T23:32:51.000284Z

@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

2018-05-08T23:34:13.000173Z

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

2018-05-08T23:37:23.000084Z

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.

seancorfield 2018-05-08T23:42:49.000054Z

Uberjar does NOT require gen-class or AOT!

seancorfield 2018-05-08T23:43:53.000250Z

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.

seancorfield 2018-05-08T23:44:57.000305Z

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.

seancorfield 2018-05-08T23:45:56.000315Z

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.

seancorfield 2018-05-08T23:46:27.000003Z

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

seancorfield 2018-05-08T23:47:47.000040Z

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.