As long as you're working purely in Clojure, Leiningen mostly protects you
from having to know about the JVM and its infamous classpath. But when
you're trying to interoperate with Java code, you need to know a few things.

So, here's the very minimum I think you need to know to understand what is
happening here. When you start a JVM, it has a notion of a classpath. This
can come from your environment variables, but usually does not, especially
when your code is started by Leiningen, so printing out your $CLASSPATH
variable would not help you there. There is a `lein classpath` command that
can help you see what's happening.

The classpath is a series of locations (mostly directories, but also often
JAR files) in which the JVM is going to look for code. When you give a
fully-qualified Java class name, the JVM will look for the equivalent path
into every directory of the classpath. So if your classpath is
/dir1:/dir2/code, for example, and your code is referencing
my.package.MyClass, the JVM will look for /dir1/my/package/MyClass.class,
and if that does not exist, it will then look for
/dir2/code/my/package/MyClass.class.

Where your files are on your disk does not matter; what matters is where
they are relative to your classpath root folders.

Note that your home directory is *not* in your $CLASSPATH in your example
(the current directory is).

Now, as to accessing these from Clojure:

$ cd $(mktemp -d)
$ lein new app t
Generating a project called t based on the 'app' template.
$ cd t
$ vim project.clj
$ vim src/MyClass.java
$ cat project.clj(defproject t "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME";
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]]
  :main ^:skip-aot t.core
  :target-path "target/%s"
  :java-source-paths ["src"]
  :profiles {:uberjar {:aot :all}})
$ cat src/MyClass.java
public class MyClass {
    public static void hello() {
        System.out.println("hello");
    }}
$ vim src/t/core.clj
$ cat src/t/core.clj(ns t.core
  (:import [MyClass])
  (:gen-class))
(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (MyClass/hello))
$ lein run
Compiling 1 source files to target/base+system+user+dev/classes
hello
$ tree target
target
├── base+system+user+dev
│   ├── classes
│   │   ├── META-INF
│   │   │   └── maven
│   │   │       └── t
│   │   │           └── t
│   │   │               └── pom.properties
│   │   └── MyClass.class
│   └── stale
│       └── leiningen.core.classpath.extract-native-dependencies
├── base+system+user+dev+b9e56754
│   └── stale
│       └── leiningen.core.classpath.extract-native-dependencies
└── base+system+user+dev+offline
    └── stale
        └── leiningen.core.classpath.extract-native-dependencies

11 directories, 5 files
$ lein classpath
test:src:dev-resources:resources:target/base+system+user+dev/classes:~/.m2/repository/cider/cider-nrepl/0.10.2/cider-nrepl-0.10.2.jar:~/.m2/repository/org/tcrawley/dynapath/0.2.3/dynapath-0.2.3.jar:~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar:~/.m2/repository/org/clojure/tools.nrepl/0.2.12/tools.nrepl-0.2.12.jar:~/.m2/repository/clojure-complete/clojure-complete/0.2.4/clojure-complete-0.2.4.jar
$


In this case, Leiningen is arranging for the MyClass.java file to be
compiled to MyClass.class, and for the result to be available in the
classpath of the running Clojure program. So, really, all you have to do to
access your Java code from Clojure is make sure it is on the classpath and
import it. One easy way to put existing, compiled .class files in the
classpath generated from Leiningen is to put them in resources, though it
would be better to either have the Java code as part of the project (in
:java-source-paths) or to package it as a Maven dependency.

I should mention, though, that using the default package (i.e. no package
declaration, i.e. having your java code directly at one of the roots of the
classpath) like that is generally considered bad form, as much in Java as
in Clojure, partly due to the risk of name clashes and partly because some
tooling just does not support it.

So, in summary:

1) Yes, as long as the .class files are on your classpath. You can also
call (import '[MyClass]) from the REPL if you are not running code from a
namespace.
2) It does not matter where on your disk these files are; your current
import statement is correct for any XXX/pirate_phrases/ directory as long
as XXX itself is on the classpath.


Hope that helped.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to