5

For a class, I need to write some JVM code, and I'm hoping to use Clojure. I got it to work with the bottom part of the software stack, but I can't manage to make it work in between the GUI layer sitting on top and the bottom part. My main problem is getting the Java GUI to recognize my Clojure files. I want to use Leiningen for this, but the Java compiling solution doesn't seem to account for this interoperation. The answer here seems to be exactly what I need. I don't understand where to put the code and such (just not quite enough details). Does anyone have any tips?

I tried making a plugin, but it doesn't seem to work. I know my case is definitely on the fringe of problems, but a solution would make using Clojure in a classroom setting much easier.

Thanks!

MORE DETAILS:

I didn't have much luck with using a compiled Clojure jar. I need to create a (ugh) stateful Clojure class (i.e. the methods can't be static). The code for my class (src/final_project/MyLinkLayer.clj) looks like

(ns final_project.MyLinkLayer
  (:gen-class))

(defn -init[s] (print s))
(defn -send [dest data len] (println data))
(defn -recv [trans] (println trans))
(defn -status [] (println "I am a status!"))
(defn -command [cmd value] (println (str cmd " with value=" value)))

My project.clj is

(defproject final_project "0.1.0-SNAPSHOT"
  :description "A simulated MAC layer."
  :dependencies [[org.clojure/clojure "1.4.0"]
                 [local/classFiles "1"]]
  :aot [final_project.MyLinkLayer])

The class compiles ("lein compile") fine into "target/classes/final_project/", but the methods don't show up. I can load the class via jar (using Maven in the top Java part of my project imports of the package work well enough). I even checked the .class file with Eclipse, and the only methods generated are those from Object. Any thoughts? Also, once I actually get to the "stateful" part of my Clojure class, does anyone have any ideas? Thanks in advance.

Community
  • 1
  • 1
kwenholz
  • 163
  • 7
  • They actually let you use Clojure in class? Damn, over here they always insist on Java (well to be fair, by now there are so many JVM languages that you can't really allow a class to use all of them without running into a royal mess). – Cubic Nov 03 '12 at 09:08
  • Yeah. It's pretty exciting, but since it's such a risk and experiment for my professor, I basically have to make it look easy if anyone else ever has a chance of using it. That's part of why I hesitate to adopt the Maven solution below. Leiningen is much "nicer". – kwenholz Nov 03 '12 at 16:20

1 Answers1

2

When I write projects that use both Clojure and Java, then I normally use Maven rather than Leiningen - for the simple reasons that most of the Java tools (e.g. Eclipse) understand Maven better than they understand Leiningen at present.

Here's an example pom.xml that I use for polyglot Clojure/Java projects:

Note the key features:

  • use of clojure-maven-plugin
  • configuration of the Clojure source directories to be considered as resources - this ensures the .clj files are treated as resources, are bundled in any .jar files produced and can be dynamically loaded at runtime (this might solve the problem you are seeing with Java failing to recognise your .clj files)
  • Inclusion of clojars.org as a repository - pretty much essential for serious Clojure development!
mikera
  • 105,238
  • 25
  • 256
  • 415
  • Thanks for the help. Is there a good resource for getting started with this sort of work? Your pom.xml makes some sense, but I'm not versed in Maven at all. Do you know of a good place to start learning, quickly? Leiningen has been awesome until this problem came up. . . . – kwenholz Nov 03 '12 at 04:43
  • You can learn Maven either by using the command line (more complex, more powerful) or using your IDE integration (easier, though you may need to drop into the command line for more advanced operations). I personally learned it the IDE route using Eclipse - see http://wiki.eclipse.org/Maven_Integration for info and tutorials – mikera Nov 03 '12 at 06:33
  • Okay thanks. I'm not a fan of Eclipse, so I'll try by command line. If I can get it to work under Maven (sounds like it will) and can't get the Leiningen solution working in the next few days, then I'll mark yours as the answer. Thanks! – kwenholz Nov 03 '12 at 16:21
  • Unfortunately, even using Maven I don't seem to be getting the results I need. It looks like I'll have to resort to compiling my Clojure as a jar and then sticking that in with the Java code. Thanks! – kwenholz Nov 05 '12 at 03:58
  • Thanks for the help. Your answer basically got me headed in the correct direction. In general, sandwiches of languages are bad business, no exception here. Maven is pretty powerful, but I ended up just compiling the Clojure to a jar and building the Java separately. Thanks! – kwenholz Nov 06 '12 at 01:34
  • If you want to sandwich within a single project, you don't want to use gen-class - you want to grab the clojure IFns directly from java and call them. – MichaelBlume Oct 29 '13 at 23:06
  • @MichaelBlume not if your clojure code exposes an OO api I think – matanster Mar 29 '17 at 11:09