我试图做的是将一个大文件(MIDI soundfont)打包到一个独立的Maven repo/clojar中,然后能够以编程方式将其下拉并从一个单独的项目中使用。这个看似简单的任务比我想象的要复杂得多。
理想的情况是,如果有一种方法可以直接访问这些资源,或者将它们公开为公共变量,或者其他什么。这是我尝试的第一件事——我做了这样的事情:
(ns midi.soundfont.fluid-r3
(:require [clojure.java.io :as io]))
(def sf2
(io/file (io/resource "fluid-r3.sf2")))
但是,我遇到的问题是,io/resource
仅在当前类路径上查找资源文件。当我试图从另一个项目(或从REPL)中请求此命名空间时,我得到:
java.lang.IllegalArgumentException: Not a file: jar:file:/Users/dave/.m2/repository/midi/soundfont/fluid-r3/midi.soundfont.fluid-r3/0.1.0/midi.soundfont.fluid-r3-0.1.0.jar!/fluid-r3.sf2
如果无法直接访问资源,我会很乐意使用一种解决方案,将文件复制到文件系统中的某个路径。我也尝试过这个方法,但在尝试从其他项目运行“将文件复制到文件系统”方法时遇到了相同的问题--io/resource
仍然无法找到该文件,因为它不在当前类路径上。
我发现之前曾有人问过类似的问题,例如:
但是,这些解决方案似乎只适用于复制当前(正在运行的)项目中的资源文件。
有可能做这两件事中的一件吗?
“从外部clojar访问资源文件”
我从这篇文章中找到了这个解决方案。德米特里·索特尼科夫在他的冷冻项目中做到了这一点。
源代码在这里。加载插件
函数将检索所有插件。edn
来自外部Clojar的每个资源目录下。
(ns cryogen-core.plugins
(:require [clojure.edn :as edn]
[clojure.string :as string]
[text-decoration.core :refer :all]))
(defn load-plugin [^java.net.URL url]
(let [{:keys [description init]} (edn/read-string (slurp url))]
(println (green (str "loading module: " description)))
(-> init str (string/split #"/") first symbol require)
((resolve init))))
(defn load-plugins []
(let [plugins (.getResources (ClassLoader/getSystemClassLoader) "plugin.edn")]
(doseq [plugin (enumeration-seq plugins)]
(load-plugin (. ^java.net.URL plugin openStream)))))
如果您不喜欢太多java互操作,那么在石榴库中有一个resources
函数,它可以检索外部Clojar中具有给定名称的所有资源。
(io/resource“fluid-r3.sf2”)
是一个url,而不是一个文件。若您希望它一次全部存储在内存中,您可以slurp
it,或者使用java将其作为流读取。网URL
api(如果需要,在读取时将其写入文件)。
示例:
user> (type (clojure.java.io/resource "text.txt"))
java.net.URL
user> (slurp (clojure.java.io/resource "text.txt"))
"this is a text file\n"
正如dbasch正确解释的那样,io/resource
返回一个URL,而不是一个文件。但是,为什么您能够在REPL上使用io/file
或lein run
打开该URL,而不是从jar打开?这是因为第一种情况下的URL指向文件系统中的普通文件,而使用jar运行时的URL指向jar中的资源,因此它不是正确的文件。
我在这个github回购中做了一个例子。我将把-main
代码复制到这里以供参考:
(defn -main [& args]
(let [r (io/resource "greet")]
(println r)
(println (slurp r))
(with-open [rdr (io/reader r)]
(println (clojure.string/join ", " (line-seq rdr))))
(println (io/file r))))
在运行时使用lein run
显示:
› lein run
#<URL file:/home/nicolas/projects/clojure/resources/resources/greet>
hello
world
hello, world
#<File /home/nicolas/projects/clojure/resources/resources/greet>
运行uberjar显示:
› java -jar target/resources-0.1.0-SNAPSHOT-standalone.jar
#<URL jar:file:/home/nicolas/projects/clojure/resources/target/resources-0.1.0-SNAPSHOT-standalone.jar!/greet>
hello
world
hello, world
Exception in thread "main" java.lang.IllegalArgumentException: Not a file: jar:file:/home/nicolas/projects/clojure/resources/target/resources-0.1.0-SNAPSHOT-standalone.jar!/greet
at clojure.java.io$fn__8588.invoke(io.clj:63)
at clojure.java.io$fn__8572$G__8556__8577.invoke(io.clj:35)
查看#
在Spring中,我们有基于注释和基于XML的配置。虽然第一种配置被推荐用于快速开发,但第二种配置更加灵活,能够处理特殊情况。我们目前有两种配置:为JUnit测试注入模拟和从外部库配置bean。 我还没有为CDI的XML配置找到任何等价物,所以我的问题是,如何处理这种bean的依赖注入?它们来自外部库,需要进行配置,不可能向它们添加任何注释。
在测试其中一个功能时,我遇到了这种错误。到底是什么问题? /用户/user/websprojects/hsu/src/path finding/path finding。spec.js:1从'chai'导入{expect}^^^^^^ 语法错误:无法在WrapSafe(节点:内部/模块/cjs/加载器: 1018:16)的模块外使用导入语句。_compile(节点:内部/模块/cjs/加载器: 1
问题内容: 我正在使用webpack来管理我的React应用程序。现在,我想从此URL导入依赖项: 传统上,我只是将上述代码放在index.html文件中。但是现在如何让webpack加载此网址?以及我的React JS如何使用该依赖关系? 当我启动webpack-dev-server时,将出现以下错误: 然后,我使用一点加载程序来加载URL。以下是使用加载程序的JavaScript代码: 但是启
我使用PyCharm作为Houdini中python代码的编辑器。每当我尝试导入主Houdini库(hou)时,我都会收到一个用PyCharm标记的错误。如果我包含代码段:- 我的代码执行,没有问题,从胡迪尼和我选择的解释器。 我的问题是PyCharm本身。编辑器将“导入后”标记为错误,导入该文件的任何后续文件也将该文件导入的模块标记为错误。因此,我放松了提前输入功能,并获得了过多的错误消息,这使
我有一个Maven项目,在那里我导入了一个外部JAR(通过构建路径),它位于参考库文件夹下。我如何在我的系统中导入它。java类文件?我的意思是字面上的代码“导入??”。这个班是在com上的。实例演示包。我是否需要在某个地方添加依赖项(pom.xml)?
Generators 相关文章 The Basics Of ES6 Generators By Kyle Simpson ES6 generators in depth By Axel Rauschmayer redux-saga 相关文章 Redux nowadays : From actions creators to sagas By Riad Benguella Managing Side