I have a problem accessing VFS resources in JBoss using ClassLoader#getResources(-)
.
I want to list all classpath resources (WEB-INF/classes/*
) of some web application (*.war
), so I can start with something like:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Enumeration<URL> resources = cl.getResources("");
while (resources.hasMoreElements()) {
Path path = Paths.get(resources.nextElement().toURI());
InputStream is = Files.newInputStream(path);
}
If I use this code in JBoss AS 7.1 which deploys the application in exploded mode - it works correctly.
As soon as you try to deploy it not in an exploded mode but as an *.war
archive it starts throwing the NoSuchFileException
.
I assume it's because the non-exploded archive uses virtual filesystem and all such loaded resources starts with `vfs:
; in my case it was e.g. vfs:///content/WEB-INF/classes/someResource/
.
Therefore the used Path
was equal to /content/WEB-INF/classes/someResource
and it was treated as a path that doesn't exist (it starts with root-node, slash) and throws an exception.
Just forget for a while about all those cases when the resources was loaded using the HTTP, FTP or others; I'm also not interested in scanning jar's within the classpath. I just want to read all file-based resources on the classpath root.
The problem is I need to enter each resource and find out if this is a folder - if so, list its all elements. That's why the Path
element would be very useful here.
The problem is - what is the correct way you should list all resources within your web application?
It seems that resources with vfs: prefix was loaded by some special JBoss classloader, right?
Hence, will I be even able to access the resources in a portable manner (code that will work for JBoss, Glassfish, TomEE, ...)?
EDIT: To give you the context why I need the above: I would like to scan all *.properties
files within the classpath and be able to access them with CDI. It has been described here.
Right now I'm switching from old File
objects in favour of NIO.2 Paths, Files and basically: input streams.
However, both approaches have the same problem with the vfs:/ resources.
Does the following work?
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Enumeration<URL> resources = cl.getResources("");
while (resources.hasMoreElements()) {
InputStream is = resources.nextElement().openStream();
}