繁体   English   中英

类路径中的 Groovy 资源未加载

[英]Groovy resource from classpath not loaded

今天是个好日子。

我在我的 groovy 项目(IDE - Intellij Idea 12.6)中使用 spock 框架进行测试。 我的 spock 规范类将文件名传递给 groovy 对象进行处理(该文件肯定在类路径中),但是当我尝试以这种方式获取该文件时

    def resource = getClass().getClassloader().getResourceAsStream(filepath)
    assert resource != null : "No input stream found for path ${filepath}"
    def rootNode = new XmlParser().parse(resource)

然后resource == null

我尝试调试,在表达式评估窗口中,此代码getClass().getResource(fileName)返回资源。

我试图检查在第一种情况下(在带有代码的类中)和在第二种情况下(表达式评估窗口)中使用的类加载器。

在第一种情况下类加载器是sun.misc.Launcher$AppClassLoader@18dabf1 ,但在表达式评估窗口中类加载器是groovy.lang.GroovyClassLoader$InnerLoader@1e69757我想这就是我的资源为空的原因。

有人可以指导我了解我做错了什么以及如何加载该资源文件?

更新:

改变了资源文件的解析方式。 当文件filepath - 文件的完整路径有效时,但如果文件filepath只是文件名并且该文件在类路径中,则resource == null

更新2

更改资源文件加载方式,清理依赖项,一切正常,我想昨天不是我的日子。

该问题很可能与 Spock 无关。 很难从远处说是什么导致了它,但读取资源最安全的方法是getClass().getClassLoader().getResourceAsStream()Thread.currentThread().getContextClassLoader().getResourceAsStream() ,具体取决于环境.

不确定在执行new File(resource)时 Groovy 会做什么,因为没有File(URL)构造函数(只有File(URI)构造函数)。 在任何情况下,都应尽可能避免从类路径中获取File

这可能是因为 Groovy 可能会以与您认为正在发生的情况不同的方式解释对象的类。 请参阅以下其他 StackOverflow 项目:

为什么 groovy .class 返回的值与 .getClass() 不同

当类错误时,ClassLoader 可能会被引导加载程序和 getClassLoader 返回 null。

所以不要使用像这样的语句

def resource = getClass().getClassloader().getResourceAsStream(filepath)

使用类似的语句指定实际的类

def resource = MyClass.class.getClassLoader().getResourceAsStream(filePath)

在几乎相同的情况下为我工作。

def resource = MyClass.class.getResourceAsStream(fileName)

或者,如果您希望文件内容为字符串:

def str = new String(MyClass.class.getResourceAsStream(fileName).readAllBytes(), StandardCharsets.UTF_8)

请注意:

  1. 使用的是 MyClass,而不是 this.getClass();
  2. 在资源中,您必须创建与类的包相同的目录结构,并将文件放在那里;
  3. fileName 只是文件名,没有任何路径;
  4. 您必须清理并重建您的项目。

暂无
暂无

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

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