未加载类路径中的Groovy资源

未加载类路径中的Groovy资源,groovy,resources,classloader,Groovy,Resources,Classloader,大家好 我在groovy项目(IDE-IntellijIDEA 12.6)中使用spock框架进行测试。我的spock规范类将文件名传递给groovy对象进行处理(该文件肯定在类路径中),但当我尝试以这种方式获取该文件时 def resource = getClass().getClassloader().getResourceAsStream(filepath) assert resource != null : "No input stream found for path

大家好

我在groovy项目(IDE-IntellijIDEA 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


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

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


不确定Groovy在执行
新建文件(资源)
时做了什么,因为没有
文件(URL)
构造函数(只有
文件(URI)
构造函数)。在任何情况下,都应尽可能避免从类路径获取
文件。

这可能是因为Groovy对对象类的解释可能与您所认为的不同。请参阅以下其他StackOverflow项:

当类出错时,类加载器可能会被引导加载器调用,getClassLoader返回null

所以不要用像这样的语句

def resource = getClass().getClassloader().getResourceAsStream(filepath)
def resource = MyClass.class.getClassLoader().getResourceAsStream(filePath)
使用如下语句指定实际类

def resource = getClass().getClassloader().getResourceAsStream(filepath)
def resource = MyClass.class.getClassLoader().getResourceAsStream(filePath)

在几乎相同的环境中为我工作。

尝试了getClass().getClassLoader().getResourceAsStream()和Thread.currentThread().getContextClassLoader().getResourceAsStream()方法,结果是相同的资源为空。您能详细说明为什么应该避免从类路径获取文件吗?在我的例子中,我需要读取xml文件,然后对其进行处理。请注意,这些方法预期的参数与
getClass().getResource()
预期的参数不同(请查看文档)。有关从类路径获取
文件时可能遇到的问题,请参阅(注释和主要文章)。对于处理XML文件,
InputStream
通常可以正常工作。是的,我想Spock与这个问题无关,一定是类加载器的问题……嗨,我认为解决方案是正确的。尝试类似的方法:URI filePath=this.class.getResource('/path\u in_classpath').toURI()File=new File(filePath)仅当资源与
getClass()
引用的类位于同一个包中时,并且仅当使用
class\getResourceStream
时,传递文件名的新文件(filePath)才有效(而不是
ClassLoader#getResourceStream
)。