Reputation: 5500
I have a Java webapp WAR file that depends on multiple jars in it's WEB-INF\lib directory. One of these JARS needs to load some config files by doing class.getClassLoader().getResourceAsStream(...)
. However the InputStream resturns null. Is there a problem with taking this approach when the JAR is inside a WAR? The app is deployed on Tomcat6.
EDIT MORE INFO:
I'm tring to load in SQL queries from files so I can run them. These are located in a separate DAO jar within the web app's WAR, under WEB-INF/lib
mywebapp.war
-- WEB-INF
-- lib
-- mydao.jar
---- com/companyname/queries
-- query1.sql
-- query2.sql
-- query3.sql
...
CODE USING TO LOAD CLASSES
public class QueryLoader {
private static final Logger LOGGER = Logger.getLogger(QueryLoader.class.getName());
public String loadQuery(String fileName) {
final String newline = "\n";
BufferedReader reader = new BufferedReader(new InputStreamReader(
QueryLoader.class.getClassLoader().getResourceAsStream(
"/com/companyname/queries/" + fileName)));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append(newline);
}
} catch (IOException e) {
LOGGER.error(e);
}
I have also tried changing the getResourceAsStream line to
Thread.currentThread().getContextClassLoader().getResourceAsStream(
without success.
My development environment is MS Windows Vista and but I encounter the same error when running it on this environment and on Ubuntu.
Upvotes: 4
Views: 8704
Reputation: 5500
Managed to get it to work by using Spring's resource loader instead
public String loadQuery(String fileName) {
final String newline = "\n";
ApplicationContext ctx = new ClassPathXmlApplicationContext();
Resource res = ctx.getResource("classpath:/com/msi/queries/" + fileName);
BufferedReader reader;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(res.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append(newline);
}
} catch (IOException e) {
LOGGER.error(e);
}
return sb.toString();
}
Upvotes: 3
Reputation: 137567
Assuming you're not making the rookie mistake of putting QueryLoader
in a different JAR, the only problem I can see is that you're using File.separator
yet appear (from your use of \
) to be using Windows. When using getResourceAsStream
, the separator is always a forward slash (/
) just as if you're using a URL.
If I change that I get this:
QueryLoader.class.getClassLoader().getResourceAsStream(
"/com/companyname/queries/" + fileName)
Of course, if QueryLoader
is in the com.companyname.queries
package (along with the queries themselves) then you should simply do this:
QueryLoader.class.getResourceAsStream(fileName)
Simple as that. (It's documented that Class.getResourceAsStream
qualifies relative filenames with the name of the containing package.)
Upvotes: 3
Reputation: 120771
It should work, but you need to take care that you use the correct class loader.
Upvotes: 2