简体   繁体   中英

How do use jMusic (a Java library) with Clojure?

I've decided I want to use Clojure's Java interoperability to play with the jMusic library. Because I know Java better than Clojure (by a lot), I'm testing things in Java and then rewriting them as (not-so-idiomatic) Clojure. I'm using Eclipse Luna with the Counterclockwise plugin, and am not using Maven, just Leiningen. As a quick aside, I don't want to use Emacs because I want to focus on learning one tool at a time.

To incorporate jMusic, I've downloaded the file and am right-clicking on the Project folder, selecting Build Path, and selecting Add External Archive. I've done that with both the Clojure project and the Java project. I have the following Java code:

import jm.music.data.Note;
import jm.util.Play;

public final class TestMusic {
    public static void main(String[] args) {
        Play.midi(new Note());
    }
}

This program runs and makes noise without issue. I cannot reproduce this in Clojure. I wrote the following code (which could be wrong, but that's a separate issue):

(ns my-clojure-test.core
  (:use jm.music.data Note)
  (:use jm.util Play))

(. Play midi (. Note))

And I get the following error:

;; Clojure 1.6.0
CompilerException java.io.FileNotFoundException: Could not locate jm/music/data__init.class 
or jm/music/data.clj on classpath: , compiling:(my_clojure_test/core.clj:1:1) 
#<Namespace my-clojure-test.core>

I've tried doing the same right-click on the project and adding an external archive. I've moved the jMusic.jar to src/java, and also extracted its files alongside the .jar.

My project.clj file looks like this:

(defproject my-clojure-test "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.6.0"]
                 [org.clojure/core.logic "0.8.10"]]
  :source-paths ["src" "src/my-clojure-test"]
  :java-source-paths ["src/java"])

How do I get Clojure to recognize the jMusic so I can make the aural "hello world" program play?

EDIT:

The selected answer does work, but do check the comments for more details about what I had to do to get it working, in case anyone else runs into the same problem.

To break down the error message:

CompilerException java.io.FileNotFoundException: Could not locate jm/music/data__init.class 
or jm/music/data.clj on classpath: , compiling:(my_clojure_test/core.clj:1:1) 
#<Namespace my-clojure-test.core>

This is saying that it was looking for either jm/music/data__init.class or jm/music/data.clj . Either one would suffice in order to load the namespace jm.music.data which you have asked for in your ns declaration. Of course there is no such Clojure namespace. This happened because you tried to use use to access classes, and it is designed for accessing namespaces. import is for accessing classes and packages.

(ns my-clojure-test.core
  (:import (jm.music.data Note)
           (jm.util Play)))

The . notation takes a method first, then the class, except when accessing a static method, in which case one should use / . The proper way to invoke a constructor is with the . following the classname, without any separator.

(Play/midi (Note.))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM