I've made a function(Java) that is supposed to read bytes from a file and print them to the console:
public void loadPixels(int size){
ClassLoader cl = this.getClass().getClassLoader();
pixels = new byte[size];
try{
InputStream stream = cl.getResource("res/" + fileName).openStream();
stream.read(pixels);
System.out.println(pixels.toString());
stream.close();
}catch(Exception e){
e.printStackTrace();
}
}
The problem is, I'm getting a NullPointerException on the line
InputStream stream = cl.getResource("res/" + fileName).openStream();
For the file I'm trying to open, the name is "font.spt", which is also the value held by fileName. This file is within the folder "res" in the project's root directory, and I'm currently using the Eclipse IDE.
Is my approach to the path for the file wrong, or is something else the issue?
To recap: fileName points to "font.spt", which is under the "res" folder in the bin directory.
EDIT: the "res" folder containing the .spt file is now under the "bin" for the project, rather than the root directory, but I still get the error. When running from the IDE or as an exported .jar, I still get the NullPointerException, where am I supposed to put these files? Can someone give me a screenshot or example?
By default, Eclipse will copy all non .java files it finds in the project's Source Locations to the Output Folder when it builds. So one option is to just place your resource files under the source folder along with your source code. However, a better option is to use a separate resources folder for non-Java files and declare that as an additional Source Location (via your project's Java Build Path properties). That's how Maven and Gradle projects are organized, too.
For example, you might have:
MyProject\
src\
java\
com\
....*.java
resources\
fonts\
font.spt
With both src\java\ and src\resources\ defined as Source Locations in the Build Path. Then your code to load the file would be like:
getResource("fonts/" + fileName)
Something to consider: use Gradle or Maven to manage your builds, both of which enforce/provide a project structure similar to this anyway.
Related
I've created a maven based java project which has resources directory (src/java/resources) and in it some xml files and maven copies them into target/classes/resources (target/classes is my classpath).
To know the content of an xml file, I use:
new FileInputStream(Main.class.getClassLoader().getResource("Configuration.xml").getPath());
Main.class.getClassLoader().getResource("Configuration.xml").getPath() gives me the full path of the xml: "c:\project...\Configuration.xml".
This works well on intellij.
but when I compile and package the project into a jar file I get:
Exception in thread "main" java.io.FileNotFoundException:
file:\C:\project\target\project-12.50.14-SNAPSHOT-jar-with-dependencies
.jar!\Configuration.xml
(The filename, directory name, or volume label syntax is incorrect)
That because the path: \C:\project\target\project-12.50.14-SNAPSHOT-jar-with-dependencies
.jar!\Configuration.xml cannot be a parameter into FileInputStream().
I cannot replace the getResource() to getResourceAsStream().
I need a way to adjust my jar and resources to work like it work on intellij.
I also change the xml resources files content during run-time so that is another problem with keeping them inside a jar.
Can anyone offer me a solution in which I don't have to change me code, and instead change my resources directory structure, or change the classpath, or something else that will keep my code working?
Thanks.
Update: Changed to use File, not Path.
That is because getResource returns a URL, and not all urls are files on disk, i.e. can be converted to a Path. As javadoc says "Returns [...] an empty string if [path part] does not exist".
If it absolutely must be a File or FileInputStream, because some other code you cannot change requires it, then copy the content to a temporary file:
File file = File.createTempFile("Configuration", ".xml");
try {
try {InputStream in = Main.class.getClassLoader().getResourceAsStream("Configuration.xml")) {
Files.copy(in, file.toPath()); // requires Java 7
}
// use file here, or:
try {FileInputStream in = new FileInputStream(file)) {
// use file stream here
}
} finally {
file.delete();
}
The above code could be optimized to not copy if resource is a file, but since that's only for development mode, and production mode is always a Jar and will always need the copy, using copy in development mode helps test the code.
I really need your help to solve my own problem. Now, I'm dealing with small code app. In that project folder contain some resource files (*.xlsx, *.png,...). I placed them in current folder with code file. I just wonder that when I run my code in netbean ide, it just worked find.
After I build code project, I get a jar file in "dist" directory. I run it. It open normally since app used JFrame as user interface. However, when I execute some function of that app, it showed me the error log. Here is the error message:
java.io.FileNotFoundException:
src\sample.xlsx (The system cannot find the path specified)
What's the matter out there?
Here is some pieces of my code:
copyFile(new File("src\\sample.xlsx"),
new File(txtout.getText()+"\\sample.xlsx"));
Node: copyFile function is used for copy file from source to dest.
Here is my project folder structure in Netbean IDE:
Project Name
Source Pakage(src)
myClass.java, sample.xlsx, etc
First, never reference src directly, the directory will not exist once the program is built. Second, you can not access resources which have been embedded within in the application context via a File reference, they simply no longer exist on the file system.
Instead, you need to use Class#getResource or Class#getResourceAsStream
URL url = getClass().getResource("/sample.xlsx");
InputStream is = getClass().getResourceAsStream("/sample.xlsx");
// Don't forget to manage your streams appropriately...
Well you can create a folder named resources under the src folder put your resources in it and use them in your code by using getResourceAsStream() and getResource() methods that can access the embedded resources.Clean and Build will compile the code and embed the contents of the resources folder into the application’s .jar file.
Ways of Accessing resources :
String pathToImage = "resources/images/filling.png";
InputStream stream= ClassName.class.getResourceAsStream(pathToImage );
String pathToImage = "resources/images/filling.png";
InputStream stream= ClassName.class.getResource(pathToImage );
please refer the link information
I'm struggling to reference a .dat file in my java project in Eclipse. My file structure looks like this:
I'm trying to reference 'GeoIPLite.dat' from my 'LookupCountry.java' file. When I say "Reference" I actually mean just getting a String object of the path and then sending that as a parameter to a class that is located under the 'Referenced Libraries' in a jar.
My code in LookupCountry.java is as follow:
try{
String dbFile = "../resources/GeoIPLite.dat"
// TRIED ALL THESE AS WELL:
//String dbFile = "/../resources/GeoIPLite.dat"
//String dbFile = "/resources/GeoIPLite.dat"
//String dbFile = "resources/GeoIPLite.dat"
//Some more code calling the jar file......
}catch(IOException e){
//Handles exception
}
So basically I get a IOException that gets thrown from the jar saying that the path to the .dat file is incorrect.
Any ideas??
Use the same package structure in your resource folder as you did in your src folder. Add your resource folder as a source folder in Eclipse (see screenshot). Place the .dat file, in the resource folder, relative to the class that is going to use it. You should see your resource files then along side your compiled classes.
In your code, reference the resource file like so:
this.getClass().getResource("foo.txt");
In Eclipse, for example, when you run a class, you configure it as to where the 'current folder' is. From the menu: Run > Run Configuration ... and select the one you are using.
Then click the 'Arguments' tab and check the working directory.
Your path should be relative to the location shown there. (In the clipped image it shows the default which is the base folder of the project itself.)
You would open the file as new File("resources/GeoIPLite.dat") with the default working directory.
I need to read a text file when I start my program. I'm using eclipse and started a new java project. In my project folder I got the "src" folder and the standard "JRE System Library" + staedteliste.txt... I just don't know where to put the text file. I literally tried every folder I could think off....I cannot use a "hard coded" path because the text file needs to be included with my app...
I use the following code to read the file, but I get this error:
Error:java.io.FileNotFoundException:staedteliste.txt(No such file or directory)
public class Test {
ArrayList<String[]> values;
public static void main(String[] args) {
// TODO Auto-generated method stub
URL url = Test.class.getClassLoader().getResource("src/mjb/staedteliste.txt");
System.out.println(url.getPath()); // I get a nullpointerexception here!
loadList();
}
public static void loadList() {
BufferedReader reader;
String zeile = null;
try {
reader = new BufferedReader(new FileReader("src/mjb/staedteliste.txt"));
zeile = reader.readLine();
ArrayList<String[]> values = new ArrayList<String[]>();
while (zeile != null) {
values.add(zeile.split(";"));
zeile = reader.readLine();
}
System.out.println(values.size());
System.out.println(zeile);
} catch (IOException e) {
System.err.println("Error :"+e);
}
}
}
Ask first yourself: Is your file an internal component of your application?
(That usually implies that it's packed inside your JAR, or WAR if it is a web-app; typically, it's some configuration file or static resource, read-only).
If the answer is yes, you don't want to specify an absolute path for the file. But you neither want to access it with a relative path (as your example), because Java assumes that path is relative to the "current directory". Usually the preferred way for this scenario is to load it relatively from the classpath.
Java provides you the classLoader.getResource() method for doing this. And Eclipse (in the normal setup) assumes src/ is to be in the root of your classpath, so that, after compiling, it copies everything to your output directory ( bin/ ), the java files in compiled form ( .class ), the rest as is.
So, for example, if you place your file in src/Files/myfile.txt, it will be copied at compile time to bin/Files/myfile.txt ; and, at runtime, bin/ will be in (the root of) your classpath. So, by calling getResource("/Files/myfile.txt") (in some of its variants) you will be able to read it.
Edited: Further, if your file is conceptually tied to a java class (eg, some com.example.MyClass has a MyClass.cfg associated configuration file), you can use the getResource() method from the class and use a (resource) relative path: MyClass.getResource("MyClass.cfg"). The file then will be searched in the classpath, but with the class package pre-appended. So that, in this scenario, you'll typically place your MyClass.cfg and MyClass.java files in the same directory.
One path to take is to
Add the file you're working with to the classpath
Use the resource loader to locate the file:
URL url = Test.class.getClassLoader().getResource("myfile.txt");
System.out.println(url.getPath());
...
Open it
Suppose you have a project called "TestProject" on Eclipse and your workspace folder is located at E:/eclipse/workspace. When you build an Eclipse project, your classpath is then e:/eclipse/workspace/TestProject. When you try to read "staedteliste.txt", you're trying to access the file at e:/eclipse/workspace/TestProject/staedteliste.txt.
If you want to have a separate folder for your project, then create the Files folder under TestProject and then access the file with (the relative path) /Files/staedteliste.txt. If you put the file under the src folder, then you have to access it using /src/staedteliste.txt. A Files folder inside the src folder would be /src/Files/staedteliste.txt
Instead of using the the relative path you can use the absolute one by adding e:/eclipse/workspace/ at the beginning, but using the relative path is better because you can move the project without worrying about refactoring as long as the project folder structure is the same.
Just create a folder Files under src and put your file there.
This will look like src/Files/myFile.txt
Note:
In your code you need to specify like this Files/myFile.txt
e.g.
getResource("Files/myFile.txt");
So when you build your project and run the .jar file this should be able to work.
Depending on your Java class package name, you're probably 4 or 5 levels down the directory structure.
If your Java class package is, for example, com.stackoverflow.project, then your class is located at src/com/stackoverflow/project.
You can either move up the directory structure with multiple ../, or you can move the text file to the same package as your class. It would be easier to move the text file.
MJB
Please try this
In eclipse "Right click" on the text file u wanna use,
see and copy the complete path stored in HDD like (if in UNIX "/home/sjaisawal/Space-11.4-template/provisioning/devenv/Test/src/testpath/testfile.txt")
put this complete path and try.
if it works then class-path issue else GOK :)
If this is a simple project, you should be able to drag the txt file right into the project folder. Specifically, the "project folder" would be the highest level folder. I tried to do this (for a homework project that I'm doing) by putting the txt file in the src folder, but that didn't work. But finally I figured out to put it in the project file.
A good tutorial for this is http://www.vogella.com/articles/JavaIO/article.html. I used this as an intro to i/o and it helped.
Take a look at this video
All what you have to do is to select your file (assuming it's same simple form of txt file), then drag it to the project in Eclipse and then drop it there. Choose Copy instead of Link as it's more flexible. That's it - I just tried that.
You should probably take a look at the various flavours of getResource in the ClassLoader class: https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ClassLoader.html.
In my Java app I need to get some files and directories.
This is the program structure:
./main.java
./package1/guiclass.java
./package1/resources/resourcesloader.java
./package1/resources/repository/modules/ -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks -> this is the file I need to get
guiclass loads the resourcesloader class which will load my resources (directory and file).
As to the file, I tried
resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()
in order to get the real path, but this way does not work.
I have no idea which path to use for the directory.
I had problems with using the getClass().getResource("filename.txt") method.
Upon reading the Java docs instructions, if your resource is not in the same package as the class you are trying to access the resource from, then you have to give it relative path starting with '/'. The recommended strategy is to put your resource files under a "resources" folder in the root directory. So for example if you have the structure:
src/main/com/mycompany/myapp
then you can add a resources folder as recommended by maven in:
src/main/resources
furthermore you can add subfolders in the resources folder
src/main/resources/textfiles
and say that your file is called myfile.txt so you have
src/main/resources/textfiles/myfile.txt
Now here is where the stupid path problem comes in. Say you have a class in your com.mycompany.myapp package, and you want to access the myfile.txt file from your resource folder. Some say you need to give the:
"/main/resources/textfiles/myfile.txt" path
or
"/resources/textfiles/myfile.txt"
both of these are wrong. After I ran mvn clean compile, the files and folders are copied in the:
myapp/target/classes
folder. But the resources folder is not there, just the folders in the resources folder. So you have:
myapp/target/classes/textfiles/myfile.txt
myapp/target/classes/com/mycompany/myapp/*
so the correct path to give to the getClass().getResource("") method is:
"/textfiles/myfile.txt"
here it is:
getClass().getResource("/textfiles/myfile.txt")
This will no longer return null, but will return your class.
It is strange to me, that the "resources" folder is not copied as well, but only the subfolders and files directly in the "resources" folder. It would seem logical to me that the "resources" folder would also be found under `"myapp/target/classes"
Supply the path relative to the classloader, not the class you're getting the loader from. For instance:
resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
In the hopes of providing additional information for those who don't pick this up as quickly as others, I'd like to provide my scenario as it has a slightly different setup. My project was setup with the following directory structure (using Eclipse):
Project/
src/ // application source code
org/
myproject/
MyClass.java
test/ // unit tests
res/ // resources
images/ // PNG images for icons
my-image.png
xml/ // XSD files for validating XML files with JAXB
my-schema.xsd
conf/ // default .conf file for Log4j
log4j.conf
lib/ // libraries added to build-path via project settings
I was having issues loading my resources from the res directory. I wanted all my resources separate from my source code (simply for managment/organization purposes). So, what I had to do was add the res directory to the build-path and then access the resource via:
static final ClassLoader loader = MyClass.class.getClassLoader();
// in some function
loader.getResource("images/my-image.png");
loader.getResource("xml/my-schema.xsd");
loader.getResource("conf/log4j.conf");
NOTE: The / is omitted from the beginning of the resource string because I am using ClassLoader.getResource(String) instead of Class.getResource(String).
When you use 'getResource' on a Class, a relative path is resolved based on the package the Class is in. When you use 'getResource' on a ClassLoader, a relative path is resolved based on the root folder.
If you use an absolute path, both 'getResource' methods will start at the root folder.
#GianCarlo:
You can try calling System property user.dir that will give you root of your java project and then do append this path to your relative path for example:
String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;
// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);
For those using eclipse + maven. Say you try to access the file images/pic.jpg in src/main/resources. Doing it this way :
ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());
is perfectly correct, but may result in a null pointer exception. Seems like eclipse doesn't recognize the folders in the maven directory structure as source folders right away. By removing and the src/main/resources folder from the project's source folders list and putting it back (project>properties>java build path> source>remove/add Folder), I was able to solve this.
resourcesloader.class.getClass()
Can be broken down to:
Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();
Which means you're trying to load the resource using a bootstrap class.
Instead you probably want something like:
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()
If only javac warned about calling static methods on non-static contexts...
Doe the following work?
resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks")
Is there a reason you can't specify the full path including the package?
Going with the two answers as mentioned above. The first one
resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()
Should be one and same thing?
In Order to obtain real path to the file you can try this:
URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;
Resourceloader is classname here.
"resources/repository/SSL-Key/cert.jks" is relative path to the file. If you had your guiclass in ./package1/java with rest of folder structure remaining, you would take "../resources/repository/SSL-Key/cert.jks" as relative path because of rules defining relative path.
This way you can read your file with BufferedReader. DO NOT USE THE STRING to identify the path to the file, because if you have spaces or some characters from not english alphabet in your path, you will get problems and the file will not be found.
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(fileUrl.openStream()));
I made a small modification on #jonathan.cone's one liner ( by adding .getFile() ) to avoid null pointer exception, and setting the path to data directory. Here's what worked for me :
String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();
Use this:
resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
One of the stable way to work across all OS would be toget System.getProperty("user.dir")
String filePath = System.getProperty("user.dir") + "/path/to/file.extension";
Path path = Paths.get(filePath);
if (Files.exists(path)) {
return true;
}