当前位置: 首页 > 面试题库 >

如何在Clojure中加载程序资源

潘自强
2023-03-14
问题内容

如何在Clojure程序中加载程序资源,例如图标,字符串,图形元素,脚本等?我使用的项目布局类似于许多Java项目中的布局,在Java项目中,“资源”目录挂在“源”目录上。一个jar文件是从源代码创建的,包括资源,但是我似乎无法像在Java中那样加载资源。

我尝试的第一件事是

(ClassLoader/getSystemResource "resources/myscript.js")

但是永远找不到资源。

您可以使用类似的方法

...
  (let [cls (.getClass net.mydomain.somenamespace)
        strm (.getResourceAsStream cls name)        ]
...

其中name是name要加载的资源的名称,而流是nil

您可以尝试将上下文类加载器与类似

...

(let [thr (Thread/currentThread)
      ldr (.getContextClassLoader thr)
      strem (.getResourceAsStream ldr name)]
...

但是strem总是零。

无奈的是,我试图将资源文件几乎放置在程序的每个目录中。它们被正确地复制到了jar中,但是我似乎还是无法加载它们。

我已经看过该load函数和运行时库的语言源,但并未“获取”它。

任何帮助,将不胜感激。

编辑 :这是一个更具体的例子。在Java中,如果要将MarkDown转换为HTML,则可以使用该showdown.js脚本并编写如下内容:

package scriptingtest;

import java.io.InputStreamReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Example {

    private Object converter;

    html" target="_blank">public String transformMarkDown(String markdownString) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("js");
        try {
            engine.eval(new InputStreamReader(getClass().getResourceAsStream(
                    "resources/showdown.js")));
            converter = engine.eval("new Showdown.converter()");
        } catch (Exception e) {
            return "Failed to create converter";
        }
        try {
            return ((Invocable) engine).invokeMethod(converter, "makeHtml",
                    markdownString).toString();
        } catch (Exception e) {
            return "Conversion failed";
        }
    }

    public static void main(String[] args) {
        System.out.println(new Example().transformMarkDown("plain, *emphasis*, **strong**"));
    }
}

当我创建项目时,所有内容都会被编译并打包到一个jar中。运行时,程序输出<p>plain, <em>emphasis</em>, <strong>strong</strong></p>

从字面意义上翻译成Clojure似乎很简单,但是尝试创建InputStreamReader-似乎无法写出在jar中找到脚本文件所需的代码时遇到了麻烦。

编辑 :添加了“ markdown”标记,因为该帖子给出了两个处理markdown方法的完整示例。


问题答案:

这是目录结构。

继续操作OP中的脚本引擎示例,Clojure等效项为:

(ns com.domain.example
  (:gen-class)
  (:import (java.io InputStreamReader))
  (:import (javax.script ScriptEngineManager ScriptEngine)))

(defn load-resource
  [name]
  (let [rsc-name (str "com/domain/resources/" name)
        thr (Thread/currentThread)
        ldr (.getContextClassLoader thr)]
    (.getResourceAsStream ldr rsc-name)))

(defn markdown-to-html
  [mkdn]
  (let [manager (new ScriptEngineManager)
        engine (.getEngineByName manager "js")
        is (InputStreamReader. (load-resource "showdown.js"))
        _ (.eval engine is)
        cnv-arg (str "new Showdown.converter().makeHtml(\"" mkdn "\")")]
    (.eval engine cnv-arg)))

(defn -main
  []
  (println (markdown-to-html "plain, *emphasis*, **strong**")))

请注意,该资源的路径是com/domain/resources针对此代码的,而不是com/domain/scriptingtest/resourcesJava版本。在clojure版本中,源文件example.clj位于中com/domain。在Java版本中,源文件Example.java位于com/domain/scriptingtest软件包中。

在我的IDE
NetBeans中设置项目时,Java项目向导会要求提供源的封装包。Clojure插件enclojure要求一个名称空间,而不是一个包。我以前从未注意到这种差异。因此,预期的目录结构中的“
off-by-one”错误。



 类似资料:
  • 问题内容: 我有作为Java类的资源束,可从数据库中读取值。当我更新数据库时,我需要重新加载捆绑软件,但我不知道如何。有人帮忙吗? 鉴于我使用捆绑如下: 问题答案: 要么 调用此方法将重新加载资源,它将刷新包 参考

  • 如何避免在生产uberjar中加载此代码,但仍然可以从开发和测试期间运行时的动态重新编译中受益?

  • 我正在尝试在我的多租户应用程序中实现假客户概念。我有两个微服务。在其中一个微服务中,我编写了从数据库获取数据的API。我需要在我的其他微服务中使用这些数据。为此,我使用了假客户概念。我需要第二个微服务加载期间的数据。但这并没有发生。我有以下错误 这是我的基于数据源的MultitenantConnectionProviderImpl。类,我在其中编写了伪客户机逻辑 这是一个虚拟客户端。我将第二个微服

  • Clojure/Leiningen/Eclipse(和Java)newby。我试图让Eclipse加载Clojure/Leiningen项目,但在搜索Lein插件解决方案时,我看到了令人困惑/矛盾的结果。 Eclipse IDE for Java开发者版本:Juno Service Release 2构建id:20130225-0426(Windows 8) 我在中有以下用户配置文件。lein\p

  • 我制作了一个简单的applet,它加载了包含在中的图像。我制作的jar文件。该项目有一个名为“kap12”的包和一个名为“U1”的类。我有一个名为“resrc”的文件夹,其中包含我的图像。此文件夹位于根目录中(与kap12文件夹相同)。 这是目录结构: 当我在Eclipse中使用Appletviewer(没有.jar)运行该程序时,它运行得很好。它定位并显示图像。但当我用html运行它时。然后程序