繁体   English   中英

如何从我的 Clojure 程序中访问 JAR 类?

[英]How do I access JAR classes from within my Clojure program?

我已经被困在我知道我以前曾经工作过的事情上好几天了。 我可能遗漏了一些明显的东西。 任何帮助,将不胜感激。

在我的 Clojure 程序中,我想访问最初用 Java 编写的类中的方法。 让我们使用一个具体的例子:org.infoml.jaxb.ObjectFactory。 这些类位于 a.jar 文件 ( infoml-classes-1.0.jar ) 中,这是一个可双击的 Java 应用程序。 如果您打开 jar 文件,您会看到 Java 类的 package 的顶级段的文件夹:

macscooter:infoml-classes-1.0 folder gw$ find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
.
|____META-INF
| |____MANIFEST.MF
|____org
| |____infoml
| | |____infocardOrganizer  <<<<<< Java application's classes
| | | |____AFileFilter.class

      |  ... many classes omitted here

| | | |____UniqueContentListener.class
| | | |____UniqueContentModel.class
| | |____jaxb
| | | |____AgentContainerLocationType.class
| | | |____AgentType.class

      |  ... many classes omitted here

| | | |____ObjectFactory.class   <<<<<< HERE IT IS

      |  ... many classes omitted here

| | | |____TableRowType.class
| | | |____TableType.class
macscooter:infoml-classes-1.0 folder gw$

在我的 Clojure 程序中,我导入它(从文件cardmaker.clj ):

(ns infwb.cardmaker
  (:gen-class)
  (:import
   (javax.xml.bind  JAXBContext  JAXBException  Marshaller
            Unmarshaller)
    (org.infoml.jaxb        ContentAgentContainerLocationType
            InfomlFile  InfomlType  ObjectFactory  PType  <<<<<< HERE IT IS
            RichTextWithExactType
            SelectorsType
            SimpleRichTextType)
   (java.io  ByteArrayOutputStream IOException)))

当我打印出 REPL 看到的类路径时,它就在那里(如infoml-classes-1.0.jar ):

infwb.cardmaker> (doseq [p (.getURLs (java.lang.ClassLoader/getSystemClassLoader))] (println (.getPath p)))
/Users/gw/tech/clojurestuff/cljprojects/infwb/src/
/Users/gw/tech/clojurestuff/cljprojects/infwb/test/
/Users/gw/tech/clojurestuff/cljprojects/infwb/classes/
/Users/gw/tech/clojurestuff/cljprojects/infwb/lib/clojure-1.3.0-SNAPSHOT.jar
/Users/gw/tech/clojurestuff/cljprojects/infwb/lib/clojure-contrib-1.2.0.jar
/Users/gw/tech/clojurestuff/cljprojects/infwb/lib/infoml-classes-1.0.jar  <<<<<< HERE IT IS
/Users/gw/tech/clojurestuff/cljprojects/infwb/lib/piccolo2dcore-1.3.jar
/Users/gw/tech/clojurestuff/cljprojects/infwb/lib/piccolo2dextras-1.3.jar
/Users/gw/tech/clojurestuff/cljprojects/infwb/lib/sxqj-beta2.jar
/Users/gw/tech/clojurestuff/cljprojects/infwb/lib/dev/clojure-1.2.0.jar
/Users/gw/tech/clojurestuff/cljprojects/infwb/lib/dev/swank-clojure-1.3.0-20110104.084027-21.jar
nil
infwb.cardmaker>

但是,当我尝试编译文件 cardmaker.clj (通过 Cc Ck 或(load-file "src/infwb/cardmaker.clj")时,我得到以下异常:

Could not initialize class org.infoml.jaxb.ObjectFactory
  [Thrown class java.lang.NoClassDefFoundError]

我已经重新启动我的机器以尝试消除无意中的杂物作为问题的根源。 我在互联网上研究了几件事——没有运气。 我查看了 MANIFEST.MF 文件以获取线索,并将 jar 文件删除为我需要的类。 我现在已经在上面睡过两次了——仍然没有解决办法。

在 Clojure 中使用现有的 Java 类是一件有用的事情。 我很感激任何人都可以给我的帮助。 谢谢。


附录:我的问题是由多种因素引起的,包括缺少 jar 文件。 @kotarak 的回答很到位。 谢谢。

我不是 100% 确定我完全明白你的问题,但如果你只是想从 Clojure 程序访问你的 Java 类,我会使用leiningen 安装 leiningen 后,大致如下:

lein new cardmaker
cd cardmaker
lein deps

将您的 jar 文件放在 lib 目录中。

在此之后,您将获得如下所示的目录结构:

├── README
├── classes
├── lib
│   ├── clojure-1.2.1.jar
│   └── infoml-classes-1.0.jar
├── project.clj
├── src
│   └── cardmaker
│       └── core.clj
└── test
    └── cardmaker
        └── test
            └── core.clj

现在,您可以在 Clojure 程序中导入您的 Java 类,并可以通过 Clojure ZD5238A7880E1EA21381 互操作访问它们。 这是一个例子

(ns cardmaker.core
  (:import [java.util Blah Blah]))

要运行这个程序,你有很多不同的选择。 请参阅leiningen 文档 看起来您正在使用 emacs ,所以请参阅swank clojure 以这种方式使用 leiningen 应该可以解决您的类路径问题。

我使用以下代码导入 Java 类:

  (ns my.namespace
    (:import [java.io DataInputStream File FileInputStream BufferedInputStream])
    (:import [my.package MyClassOne MyClassTwo])
    ....

如果相关的 Java 类在类路径上(如果它们在 a.jar 中就可以了),这应该可以工作。

要测试这些是否在类路径中,您还可以在 REPL 中执行以下操作:

  (import 'my.package.MyClassOne)

import类的方式很好。 显然ObjectFactory class 无法初始化,因为它需要的其他一些 class 不在类路径中。 查找完整的堆栈跟踪以找出缺少哪个 class 以使ObjectFactory正常工作。 正如@mikera 建议的那样,您可以在 Repl 中使用(import 'org.infoml.jaxb.ObjectFactory)来执行此操作。 (除非 emacs 吃掉你的堆栈跟踪......)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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