Clojure 与 Java 互操作:如何调用 class?

Clojure interop with Java: how to call a class?

我有一个 Java 应用程序,在这个地址有一个 class,在标准 Maven 布局中:

src/main/java/com/ollio/nlp/Transformer.java 

我想要的class和方法是这样的:

package com.ollio.nlp;

public class Transformer {
    public String transform(String JSONInput) {

我将 jar 工件本地存储在我的 Clojure 应用程序中的这个地址:

maven_repository/local/nlp/1.0-SNAPSHOT/nlp-1.0-SNAPSHOT.jar 

我尝试了十几种变体将其导入我的 Clojure 应用程序,例如:

 (:import
    [com.ollio.nlp.Transformer])

但我一直收到错误 "No such namespace"。

导入这个的正确方法是什么?

已编辑:

这是我目前尝试执行导入语句的方式:

(ns slick.query
  (:import
    [nlp.*])

我也试过:

(ns slick.query
  (:import
    [com.ollio.nlp.*])

我尝试了一些其他变体。

project.clj 文件如下所示:

(defproject slick "0.1"
  :description "slick is  an API for other ollio services, such as our mobile app."
  :dependencies [[org.clojure/clojure "1.6.0"]
             [com.taoensso/timbre "3.2.1"]
             [dire "0.5.1"]
             [slingshot "0.10.3"]
             [ring "1.4.0-RC1"]
             [clj-time "0.6.0"]
             [org.clojure/data.json "0.2.5"]
             [compojure "1.3.4"]
             [com.novemberain/monger "2.0.1"]
             [org.clojure/tools.namespace "0.2.4"]
             [manifold "0.1.0"]
             [me.raynes/fs "1.4.4"]
             [org.clojure/core.incubator "0.1.3"]
             [clj-stacktrace "0.2.7"]
             [overtone/at-at "1.2.0"]
             [ring/ring-json "0.3.1"]
             [clj-http "1.1.2"]
             [org.clojure/core.cache "0.6.4"]
             [cheshire "5.5.0"]
             [org.clojure/core.match "0.3.0-alpha4"]
             [local/nlp "1.0-SNAPSHOT"]]
  :repositories {"local" ~(str (.toURI (java.io.File. "maven_repository")))}
  :disable-implicit-clean true
  :source-paths      ["src/clojure"]
  :java-source-paths ["src/java"]
  :main slick.core
  :aot :all
  :jvm-opts ["-Xms100m" "-Xmx1000m" "-XX:-UseCompressedOops"])

如果您在一个项目中混合使用 java 和 clojure 源代码,您应该首先查看 lein 文档:https://github.com/technomancy/leiningen/blob/master/doc/MIXED_PROJECTS.md

此外,如果您发布了 project.clj 和 java/clojure 来源的布局,将更容易发现缺失的内容。

您可能想将 :import 语句中的最后一个句点更改为 space:

(ns mynamespace
  (:import [com.ollio.nlp Transformer]))

(编辑:您不能在此处使用通配符。必须明确列出 com.ollio.nlp 中的每个 class,并以 space 分隔。)这将允许您使用Transformer不合格:

(.transform (Transformer. <add constructor args here>) my-json-input)

正如@noisesmith 所说,:import 语句应该是 ns 声明的一部分。

项目的设置方式也很有可能存在问题。你没有给出任何迹象表明这是可能的,但我相信当一个人开始使用 Java 互操作时它经常发生。 (无论如何,它发生在我身上。)所以@AlanThompson 的建议可能是相关的。

您也只需删除 :import 语句,并使用完全限定形式的 Java class 名称,例如:

(.transform (com.ollio.nlp.Transformer. <add constructor args here>) my-json-input)

如果您在执行此操作时遇到错误,则可能是设置有问题(除非您使用 class 不正确)。

(我不确定这些有多大帮助。Alan Thompson 的回答可能是合适的。)