Fork me on GitHub
#leiningen
<
2016-05-17
>
cjmurphy04:05:05

I am trying to compile some java code as part of trying to assemble an uberjar. This polyglot clojure/java environment has been fine for development. But when trying to get an uberjar, no matter what I do I always get a 'class not found' exception. How does lein find .class files? They are there but I think that symbolic links may be causing a problem. From the project root directory find . -name "*.class" -print returns nothing. Yet the same find command run after cd java/src produces much output, as expected. Maybe lein is as bad at finding class files as find is! Seems like a filesystem/permissions something kind of problem. Has anyone come across this before? I'm not on a Mac, just regular Linux. Also the class files, when found, are on the intelliJ output path: out/production. But then with lein you don't specify where the class files go??

cjmurphy04:05:20

Obviously I'm pretty confused at the moment. My next step might be to take the links out of the picture. But directory links should work just like directories - so I wonder if there's a way to make that fact more true, so to speak.

cjmurphy05:05:30

... I think my way out of this will be to package up all the Java source code into its own jar, put the jar into maven, have it as a dependency, then try creating the uberjar again...

plexus08:05:38

@cjmurphy: once you have an uberjar it's just java class lookup, meaning it all depends on the classpath. I would start by unzipping your uberjar (it's just a regular zip file) and see if your .class files are in there. If they are but java won't find them, then some classpath entries are missing. These are set in a file calles META-INF/MANIFEST.MF. Either way you probably will have to experiment with leiningen's :resource-paths, the directories listed there should be both added to the uberjar and added to the classpath in the manifest.

cjmurphy09:05:22

My problem wasn't so much creating the uberjar as .class files (that came from java files) needing to be found for compilation to work. And the OS couldn't even find them! Now that I have taken java source code out of the picture (by compiling it elsewhere and packaging it up into jar files in the .m2 repo) I am on the right track again - lein can always find class files in the dependencies you give it.

andrei13:05:07

@cjmurphy: are you trying to create an uberjar and you depend on a local .jar dependency? I had similar issues with that, but I ended up publishing my .jar dependency in our private maven - and from there on everything was ok. I could help if you share your project.clj (or parts of it) with us. Long story short I remember to be a pain to include local jars in the uberjar, no mater how much I played with lein’s :resource-paths.

andrei13:05:22

@cjmurphy: for debugging you can use: lein classpath or/and lein deps :tree - to see if your deps are in the “right place"

cjmurphy13:05:34

It is working fine now. I never even knew you could have lein depend on a jar that wasn't in maven or clojars so didn't go down the route of having a local jar dependency at all. My strategy, which worked, was to bring legacy Java code in only via lein maven (.m2 on the machine) dependencies. My issue now is different - without Figwheel browser can't connect - need to replace what Figwheel was doing. Thanks @plexus and @andrei.

plexus13:05:36

yeah figwheel embeds its own http-kit server. Should be easy to start that yourself.

cjmurphy13:05:24

I have a setup originally from an example sente project. It does seem to start a web server, but somehow I guess Figwheel must have been doing that job all along. Now there's no Figwheel repl waiting for me to connect to the browser, and there's nothing at port 3000. Anyway I guess a bit off topic and I need to think through what's going on... thanks.

cjmurphy14:05:16

I suspect that main.js - all the ClojureScript is not making it into the uberjar. Not even sure how it should look in there. Also there's figwheel namespaces in there. I'm thinking need to create a prod profile in project.clj, but then how to tell the uberjar creation process to use it. I'll take a look at the Untangled example (which is another place I partially got my setup from).

cjmurphy14:05:39

I guess you just do lein cljsbuild once production, then lein uberjar, and it will pick up your production Clojurescript...

cjmurphy15:05:45

It would but lein uberjar cleans the target first. That's why no js was ending up in the jar file 🙁