我已经在我知道之前曾经工作过的事情上被困了好几天。我可能遗漏了一些明显的东西。任何帮助将不胜感激。
在我的 Clojure 程序中,我想访问最初用 Java 编写的类中的方法。让我们使用一个具体的例子:org.infoml.jaxb.ObjectFactory。这些类位于 .jar 文件 (infoml-classes-1.0.jar
) 中,该文件是可双击的 Java 应用程序。如果打开 jar 文件,您会看到 Java 类包的顶级部分的文件夹:
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(通过 C-c C-k 或 (load-file "src/infwb/cardmaker.clj")
)时,出现以下异常:
Could not initialize class org.infoml.jaxb.ObjectFactory
[Thrown class java.lang.NoClassDefFoundError]
我已经重启了我的机器,试图消除作为问题根源的无意的污垢。我在 Internet 上研究了几件事——没有运气。我查看了 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 Java 互操作访问它们。这是一个例子
(ns cardmaker.core
(:import [java.util Blah Blah]))
要运行这个程序,你有很多不同的选择。查看leiningen docs .看起来您正在使用 emacs,因此请参阅 swank clojure .以这种方式使用 leiningen 应该可以解决您的类路径问题。
关于java - 如何从我的 Clojure 程序中访问 JAR 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6259573/