简体   繁体   中英

FileNotFoundException:file:xxx\.m2\repository\xxxx\xxx\xxx.jar!\filename, when running main from IDEA

I have a project that build from eclplse, and a java class that main method runs well but fail to run when I try to run it from IDEA.

The main method will initially try to load a properties file from classbath by below code from ANOTHER dependency project(wemq-client):

 filePath = this.getClass().getClassLoader().getResource(fileName).getPath();
 ....//something else

 prop = new Properties();
 prop.load(new FileInputStream(new File(filePath)));

But when I run in InteliJ, I have following error:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at .....
Caused by: java.lang.RuntimeException: java.io.FileNotFoundException: file:\C:\Users\jaskeylin\.m2\repository\cn\webank\wemq\wemq-client\0.1.3\wemq-client-0.1.3.jar!\wemq-client.properties (文件名、目录名或卷标语法不正确。)

which 文件名、目录名或卷标语法不正确。 means file name or dictionary name syntax not correct.

We can see from the error statck that it tries to find this file from maven repo's package jar file. Why is that? How can I fix it.

PS: If you are suggesting I modify the code, please also explain why this works from eclipse, since this works quite fine from my teamates, there is only me who hopes to use IDEA

As you can see from the file name in the error message, you're trying to open file wemq-client.properties inside file wemq-client-0.1.3.jar using a FileInputStream . You cannot do that. You can only open real files on the file system, not files inside archives.

In short, NEVER EVER do getResource(...).getPath() . There is a reason the getResource(String) method returns a URL , and not a File . Because the resource may not be a file.

Instead, use the getResourceAsStream(String) , and give that InputStream directly to the load(InputStream) method.

As always, remember to close your resources, preferably using try-with-resources.

prop = new Properties();
try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName)) {
    prop.load(inputStream);
}

Or use any alternate version of getResourceAsStream() as suggested in answer by @SanjitKumarMishra .

You can use the getResource(String) method if you want, but you must then open the stream using the URL.openStream() method.

URL fileUrl = this.getClass().getClassLoader().getResource(fileName);
....//something else

prop = new Properties();
try (InputStream inputStream = fileUrl.openStream()) {
    prop.load(inputStream);
}

The reason it works inside Eclipse, is that you're running directly off files on the file system, however when you package and deploy your code, it's packaged inside jar files, and you get the error you see.

you cannot using FileInputStream to read files in jar, you can using someclass.class.getResourceAsStream(name) to read the file

just

 prop = new Properties();
 prop.load(this.getClass().getResourceAsStream(fileName));

If you are loading the class from an Application Server, so your should use Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName) instead of this.getClass().getClassLoader().getResourceAsStream(fileName) . this.getClass().getResourceAsStream() will also work.

Read this article for more detailed information about that particular problem.

You can use HTTPSERVLETREQUEST to get file path.

HttpServletRequest request = ServletActionContext.getRequest();

String filePath = request.getSession().getServletContext().getRealPath("/")+filename;

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