Java - class.getResource returns null - java

I am using the following to get the URL of this particular file, but it returns null. Does anyone have any suggestions as to the problem or an alternate way to do this?
URL url = ExchangeInterceptor.class.getResource("GeoIP.dat");

For those who use Intellij Idea: check for Settings > Build, Execution, Deployment > Compiler > Resource patterns.
The setting contains all extensions that should be interpreted as resources. If an extension does not comply to any pattern here, class.getResource will return null for resources using this extension.

The path is relative to the classpath root and if you don't give an absolute path, it is looking in the same package as the class you're using (in this case ExchangeInterceptor). To find something in the root use /GeoIP.dat.

Use the getResource method of the class' ClassLoader
URL url = ExchangeInterceptor.class.getClassLoader().getResource("GeoIP.dat");

I solved this problem by pointing out the resource root on IDEA.
Initially the directory was so and the icon was a plain folder icon
Before
Right click on a directory (or just the project name) -> Mark directory As -> Resource Root.
After
Recompile & rejoice :P

I've faced with the similar problem. From Java SE API for getResource​(String name) :
If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.
So I've added '/' before my directory : MyClass.class.getResource("/dir_name/").
In your case try to add '/' before your file name:
URL url = ExchangeInterceptor.class.getResource("/GeoIP.dat");

If you're using Gradle and IntelliJ, and changing Resource patterns didn't work, and your resource roots are set correctly...you can try this:
Settings > Build, Execution, Delpoyment > Build Tools > Gradle > Runner > Delegate IDE build/run actions to gradle. (IntelliJ 2017.3.3)
Source: https://youtrack.jetbrains.com/issue/IDEA-176738#comment=27-2518612

Just in case someone still has problems to understand that:
.getResource() grants you access to the local bin folder. That means, your resources need to be located in YourProject/bin/package/. The root folder is YourProject/bin/ and can be accssed by adding the prefix / to the String argument, like iirekm said.

No, that is the right way afaik. Make sure the resource is on your classpath. This is often the cause of these types of problems.

While using IntelliJ, I generated the project as a JavaFX app and then added maven framework support to it. Turns out, I then placed my resource in src/main/resources and had to add ./ behind every resource name that while using them in the code.
Also as stated in a previous answer, only loading the resource by a classLoader worked.
So for me, the final URL loading was done using:
URL url = getClass().getClassLoader().getResource(String.format(".%ssample.fxml", File.separatorChar));
The File.separatorChar returns / on *nix and \ on windows.

This is my example solution. Work for me.
The project structure:
• Source Packages
• game
• Game.java
• game.images
• tas_right.png
In the game class:
URL path=this.getClass().getClassLoader().getResource("images/tas_right.png")

Where do you have put this GeoIP.dat? In the same package as ExchangeInterceptor, or in the "root" package. If in the same package, your code is OK, if in the root - add '/' prefix.
Maybe you're using M2Eclipse? If configured incorrectly, it also may result in such problems. Another cause of such problems may be: misconfigured classloaders, misconfigured OSGi, ...

The file needs to be in the classpath, e.g.: -
bin/my/package/GeoIP.dat
The / prefix seems to be a lie. The following would work.
URL url = ExchangeInterceptor.class.getResource("my/package/GeoIP.dat");
I suspect the issue is that you do not have the file in the classpath.

I was able to fix it by adding "./" to the beginning of the file like this:
getClass().getClassLoader().getResource("./file.txt")

Instead of having the resource file in the same folder as your source files, create a resources folder parallel to the java source folder.
Before:
src
main
java
MyClass.java
file.bin
file.txt
After:
src
main
java
MyClass.java
resources
file.bin
file.txt

I use Intellij version Ultimate 2019.3
Go to
Settings -> Compiler -> Resource patterns.
Click ok.
Rerun Application/Server.
In my case, i included the jks in the project!

say you have :
titleLabel.setIcon(new ImageIcon(getClass().getResource("/uz/assets/icon.png")));//wrong !!
rightclick on the folder(mine is assets) an set Mark Directory as Resources
if you dont see that rightclick on project name and pickup Open module settings
Rightclick on resorces folder(assets in my case)
and select 'Resources'
Now go back to the above java instruction and remove path BUT leave /
like:
titleLabel.setIcon(new ImageIcon(getClass().getResource("/icon.png")));// correct one

A warning to all using the Path or Paths classes in Java: if you are on the god forsaken operating system known as Windows you will not be able to use Path.of or Paths.get as this will put backslashes in your path which Java will attempt to load and promptly fail. Instead use this:
Path.of(paths...).toString().replace(File.separator, "/")
You should always use this as it is OS independent. If anyone has a better or built in way please comment, I was unable to find one.

Strangely effective in my case (IJ 2022.1.4) was: close project (for example, quit IDEA), delete the /.idea folder completely (egg, rm -rd .idea), open project. When it re-imports the project, it runs as expected. Note: you loose about everything not included in gradle configs.

I realized using new File(location) works just fine in #dev and can also access files outside the /project folder

In case of eclipse.
Just a hint. Your code could be correct, but your jre configuration not. I ran into the the same error, nothing helped, until i checked the eclipse settings.
Make sure, that you set your execution environment right.
Preferences -> Java -> Installed JREs -> use "jdk..." as compatible JRE

First, you need to make sure you are accessing the right file on the right path. You can verify that by getClass().getResource("GeoIP.dat").getAbsolutePath().
Secondly, the path specifier is case-sensitive, so make sure your file is not named "geoIP.dat" or "GeoIP.DAT".

Related

How to get root of my WATIR project?

Due to a project requirement I had to move from Selenium 2.0 to Watir and Cucumber framework. Earlier we were using Java and often set the default file path as:
System.setProperty("webdriver.chrome.driver",System.getProperty("user.dir")+"/browsers/chromedriver.exe");
Now I am trying to set up something similar in Ruby also, but being new to Ruby, I'm failing to get the root directory of the project. It only gets the path of the file which the current user is working using __FILE__ or Dir.pwd.
My Watir project structure is like this:
root
-config
-features
-pages
-step_definitions
-support
-hooks.rb
-browsers
...
...
I want to specify in hooks.rb that if the parameter passed is "Chrome", then run the Chrome browser, and when it is "FF" run the Firefox browser, but it always gives me the current working directory path and I need the root directory.
I am on WINDOWS 7, Using Ruby version 1.9.3p551.
Ruby's File class has several different methods that are useful for what you're trying to do, so read the documentation for absolute_path, expand_path, realdirpath and realpath.
I'd recommend starting with absolute_path:
Converts a pathname to an absolute pathname. Relative paths are referenced from the current working directory of the process unless dir_string is given, in which case it will be used as the starting point. If the given pathname starts with a “~” it is NOT expanded, it is treated as a normal directory name.
I built the path from your hooks.rb to the root directory in my tests directory on my Desktop, and added this code to hooks.rb:
PATH_TO_ROOT = File.absolute_path('../..', File.dirname(__FILE__))
Running it shows:
PATH_TO_ROOT # => "/Users/ttm/Desktop/tests/ruby/root"
You'll always have to maintain the '../..' relative string but that is easier than hard-wiring your code with a fixed absolute path.
I tend to put code similar to this in any project that has multiple directories, especially when I'm calling library files. Write your code correctly, and you can do it once assigning the value to a constant, and you can then reference that constant wherever you need to know the absolute path to the installation.
book = Roo::Excel.new(File.join(File.absolute_path('../..', File.dirname(__FILE__)),"config/data/test.xls"))
It's a lot easier than that:
path_to_book = File.absolute_path('../../config/data/test.xls', File.dirname(__FILE__))
path_to_book # => "/Users/ttm/Desktop/tests/ruby/root/config/data/test.xls"
File.dirname(__FILE__) is the anchor for your relative path. Simply define the relative path to the file you want and let Ruby do the rest.
"Relative path to your project directory" talks about relative pathing in Ruby.
The answer to your question is going to be specific to the code that you are trying to use in your hooks.rb. If you could post a sample of what code you are using for this from your hooks.rb, that would be great. But the answer to your question is likely going to be some combination of the following:
File.join(File.dirname(__FILE__), '../../')
Where the first parameter is your current directory (root\features\support) and the second parameter is going to be the relative path to your root directory ('../../').

how to provide relative address to read a file in java

what I want to ask seems so simple and crazy but since I am so beginner I dare to ask you guys.
I want to give relative address to read a file in eclipse java. my java file is in common package and json file is in resources package in the same project. but I do not know how to provide relative address to that.
BufferedReader in = new BufferedReader(new FileReader("/?/file.json"));
so I have a project:
> src/main/java
>com.project.cc.restful.common
>com.project.cc.restful.resources
any help?
thanks!
What you need is a path that is relative to your working directory. The working directory is a configurable parameter. In eclipse the default is usually the root folder of the project (not the source code folder!). It can be configured in the "Run Configurations.." menu.
To be sure, run your application once with System.out.println(System.getProperty("user.dir")) to see the absolute path to your working directory. Once you have that, use ../../Resources (or something similar) to get to the resources directory using a relative path.

Accessing a different folder using classloader

URL root = Thread.currentThread().getContextClassLoader().getResource(packageName.replace(".", "/"));
i use the above statement to access .class files given a package name. But in some cases i need to access the files from \build\test\classes instead of \build\classes. How do i modify the above statement?
You are having problems with your classpath.
${project}/build/test/classes and ${project}/build/classes folders suggest that you have either used Ant to compile your code, or checked "Allow output folders for source folders" option in Eclipse's "New Java Project" dialog.
You should configure you project to compile all source files into the same output folder, in your case /build/classes.
If you use classloader to load a resource the path you give it is not absolute to entire filesystem even if it starts with /.
InputStream is = this.getClass().getResourceAsStream("/some/resource");
This actually means find this file ${project}/build/classes/some/resource.
And in order to get that resource at the target location the easiest way is to place it in ${project}/src/some/resource.
Although you should consider using Maven and m2eclipse if your using Eclipse.

Resource loading in Java not working as it should

This is the well known problem of loading resources from a jar file. This is not the first time I've tried to do this, but now it doesn't work the way I expect it to.
Normally I try to load the Resources with this.getClass.getResource("foo.png"), or getResourceAsStream()and it works. Now however it does not. The Resource is always null.
If I let System.out.println(this.getClass.getResource("")) print me the path (from eclipse) it shows /path/to/eclipseproject/package/structure/. Running this from a jar it just shows rsrc:package/structure
If I recall correctly this should print the path to the jar. Furthermore I thought this would print the package structure in both cases. Am I doing something wrong?
Here is the thing...
When Extracting the file from the Jar use:
this.getClass.getResource("/foo.png")
When running from a runnable Jar use, to reference an external file in the Jar folder path:
this.getClass.getResource("foo.png")
// When running this from Eclipse, it would refer to files in project root!
I have a code in the lower level determining where I'm running from to determine the correct path.
Doe this get the path you need?
this.getClass().getClassLoader().getResource("<your class name>.class").getPath();
See also this question for more on this issue.
Unless you prepend the path to the resources with '/', Class.getResource() will search for the resource in class package. E.g.: tld.domain.Foo.class.getResource("Bar.txt") will search for tld/domain/Bar.txt
Check the URLClassLoader for all the gory details, but it really depends on whether you are trying to access a ressource in the jar,
using a class loaded inside the same jar, in this case your file 'root' is the root of the jar
using a class loaded outside the jar (your eclipse case) where the root is your 'working directory'
To access resources inside a jar from outside, you should use something like
URL url = new URL( "jar", "", "file:" + jar.getCanonicalPath( ) + "!/" + localPathResource );
url.openStream(...)
This answer provides an explanation of how to load class resources from JAR files, even when the class is not in the JAR file and not in the Class-Path specified in the JAR file's manifest. There are also links to code.

Java (maven web app), getting full file path for file in resources folder?

I'm working with a project that is setup using the standard Maven directory structure so I have a folder called "resources" and within this I have made a folder called "fonts" and then put a file in it. I need to pass in the full String file path (of a file that is located, within my project structure, at resources/fonts/somefont.ttf) to an object I am using, from a 3rd party library, as below, I have searched on this for a while but have become a bit confused as to the proper way to do this. I have tried as below but it isn't able to find it. I looked at using ResourceBundle but that seemed to involve making an actual File object when I just need the path to pass into a method like the one below (don't have the actual method call in front of me so just giving an example from my memory):
FontFactory.somemethod("resources/fonts/somefont.ttf");
I had thought there was a way, with a project with standard Maven directory structure to get a file from the resource folder without having to use the full relative path from the class / package. Any advice on this is greatly appreciated.
I don't want to use a hard-coded path since different developers who work on the project have different setups and I want to include this as part of the project so that they get it directly when they checkout the project source.
This is for a web application (Struts 1.3 app) and when I look into the exploded WAR file (which I am running the project off of through Tomcat), the file is at:
<Exploded war dir>/resources/fonts/somefont.ttf
Code:
import java.io.File;
import org.springframework.core.io.*;
public String getFontFilePath(String classpathRelativePath) {
Resource rsrc = new ClassPathResource(classpathRelativePath);
return rsrc.getFile().getAbsolutePath();
}
In your case, classpathRelativePath would be something like "/resources/fonts/somefont.ttf".
You can use the below mentioned to get the path of the file:
String fileName = "/filename.extension"; //use forward slash to recognize your file
String path = this.getClass().getResource(fileName).toString();
use/pass the path to your methods.
If your resources directory is in the root of your war, that means resources/fonts/somefont.ttf would be a "virtual path" where that file is available. You can get the "real path"--the absolute file system path--from the ServletContext. Note (in the docs) that this only works if the WAR is exploded. If your container runs the app from the war file without expanding it, this method won't work.
You can look up the answer to the question on similar lines which I had
Loading XML Files during Maven Test run
The answer given by BobG should work. Though you need to keep in mind that path for the resource file is relative to path of the current class. Both resources and java source files are in classpath

Categories