2013-11-26 59 views
1

美好的一天每个人。来自classpath的Groovy资源未加载

我在我的groovy项目(IDE - Intellij Idea 12.6)中使用spock框架进行测试。我斯波克规范类传递文件名,常规的处理对象(即文件在类路径肯定的),但是当我试图让该文件这样

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

然后resource == null

我试过调试,在Expression Evaluation窗口中,这段代码getClass().getResource(fileName)返回资源。

我试着检查第一种情况下(类代码中)使用哪个类加载器,第二种情况下(表达式评估窗口)。

在第一种情况下类加载器是[email protected],但在Expression Evaluation窗口类加载器中是[email protected]我想这就是我的资源为空的原因。

有人可以指导我做什么我做错了,我怎么能加载该资源文件?

UPDATE:

改变了资源文件被解析。当filepath - 完整的文件路径这个工程,但如果filepath只是文件名,并在类路径文件,然后resource == null

UPDATE2

更改装载的方式资源文件,清理依赖位,一切都工作,我想昨天不是我的一天。

+1

只传递文件名只有当资源与'getClass()'引用的类位于同一个包中时才有效,并且只有在使用'Class#getResourceStream'(而不是'ClassLoader#getResourceStream')时才有效。 –

回答

6

问题很可能与Spock无关。很难从远处说出造成它的原因,但根据环境,读取资源的最安全方法是getClass().getClassLoader().getResourceAsStream()Thread.currentThread().getContextClassLoader().getResourceAsStream()

由于没有File(URL)构造函数(只有File(URI)构造函数),所以不确定Groovy在做什么时会做什么new File(resource)。无论如何,尽可能避免从类路径获取File

+0

正在尝试getClass()。getClassLoader()。getResourceAsStream()和Thread.currentThread()。getContextClassLoader()。getResourceAsStream()方法,结果是相同的资源为null。你能否详细说明为什么应该避免从类路径获取文件?在我的情况下,我需要读取xml文件,然后处理它 – artjomka

+1

请注意,这些方法所期望的参数不同于getClass()。getResource()'期望的参数(请查看文档)。对于从类路径获取'File'时可能遇到的问题,请参阅https://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html#comment-825410(注释和主要文章)。为了处理一个XML文件,一个'InputStream'通常工作正常。 –

+0

是的,我想Spock与这个问题无关,必须是类加载器... – artjomka

2

这很可能是因为Groovy可能会以不同的方式解释对象的类,以至于您认为发生了什么。请参见下面的其他StackOverflow的项目:

Why does groovy .class return a different value than .getClass()

当类是错误的,那么ClassLoader的可能通过引导加载程序和getClassLoader返回null。

因此,而不是使用像

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

一个语句中指定使用的语句实际的类象

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

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