0

I have a Clojure project I created with lein new. My Clojure files are all within a src folder, and all seem to be compiled when I run lein uberjar (I see errors in them when things are missing).

Within src, I have a folder myns with junk.clj in it. That file has

(ns myns.junk)

(defn sq [x] (* x x))

After loading the jar created by lein uberjar in my java project, I can import and call that function via

import myns.junk$sq;

public class JavaApplication1 {
    public static void main(String[] args) {
        System.out.println(junk$sq.invokeStatic(5));       
    }  
}

But I can't, for the life of me, figure out how to import functions from files that are not in a folder. Top-level files in my src folder seem invisible and unable to be imported on the Java side.

How do I tell Clojure to put similar functions in top-level files into some namespace that Java can import?

Amr Eladawy
  • 4,193
  • 7
  • 34
  • 52
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393

1 Answers1

1

Single-segment namespaces (ie, (ns myns)) are strongly discouraged for exactly the reason that you have observed. They lead to classes with the name myns$foo, in the default package. The default package is super weird in a lot of ways, and Java developers never use it except for the tiniest of hello world programs. In particular, you cannot import a class from the default package, because there is no package name to import it from.

See Is the use of Java's default package a bad practice? for more examples of reasons it is bad to use the default package; and because single-segment namespaces in Clojure are implemented by putting classes into the default package, this implies you also should not use single-segment namespaces.

amalloy
  • 89,153
  • 8
  • 140
  • 205