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
  • 3,958
  • 6
  • 32
  • 50
Adam Rackis
  • 81,646
  • 52
  • 262
  • 388

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
  • 83,458
  • 7
  • 138
  • 194