简体   繁体   中英

Java getResourceAsStream JAR inside WAR

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.

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();

}

它应该可以工作,但是您需要注意使用正确的类加载器。

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.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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