Reading a Txt-File in a jar-File in Java - java

I've write a Java programm and packaged it the usual way in a jar-File - unfortunately is needs to read in a txt-File. Thats way the programm failed to start on other computer machines because it could not find the txt-file.
At the same time Im using many images in my programm but here there is no such problem: I "copy" the images to the eclipse home directory, so that they are packaged in the jar-File and usable through following command:
BufferedImage buffImage=ImageIO.read(ClassName.class.getClassLoader()
.getResourceAsStream("your/class/pathName/));
There is something similar for simple textfiles which then can be use as a normal new File()?
Edit
Ive try to solve my problem with this solution:
package footballQuestioner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.security.auth.login.Configuration;
public class attempter {
public static void main(String[] args) {
example ex = new example();
}
}
class example {
public example() {
String line = null;
BufferedReader buff = new BufferedReader(new InputStreamReader(
Configuration.class
.getResourceAsStream("footballQuestioner/BackUpFile")));
do {
try {
line = buff.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (line != null);
}
}
But it gives always an NullPointerException...do I have forgotten something?
Here is as required my file structure of my jar-File:

You can load the file from the ClassPath by doing something like this:
ClassLoader cl = getClass().getClassLoader()
cl.getResourceAsStream("TextFile.txt");
this should also work:
getClass().getResourceAsStream(fileName);
File always points to a file in the filesystem, so I think you will have to deal with a stream.

There are no "files" in a jar but you can get your text file as a resource (URL) or as an InputStream. An InputStream can be passed into a Scanner which can help you read your file.
You state:
But it gives always an NullPointerException...do I have forgotten something?
It means that likely your resource path, "footballQuestioner/BackUpFile" is wrong. You need to start looking for the resource relative to your class files. You need to make sure to spell your file name and its extension correctly. Are you missing a .txt extension here?
Edit
What if you try simply:
BufferedReader buff = new BufferedReader(new InputStreamReader(
Configuration.class.getResourceAsStream("BackUpFile")));

Related

Unable to locate and load file in Eclipse IDE, File not found

I'm new to Java, and I am facing this issue in Eclipse. Even after pointing it to the correct file, it shows a file not Found Error.
I am trying to compile code from a Java file using the Java Compiler API.
The code words fine in Visual Studio with setting everything in root, But gives this error in Eclipse with all these directories.
Also, why are there three different src folders in the image?
My project structure
package com.example.app;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.IOException;
public class compilier {
public static void main(String[] args) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null, new File("com/example/app/Code.java").getAbsolutePath());
if (result == 0)
{
System.out.println("File Compiled");
}
try {
String package_dir = "/demo/src/main/java/com/example/app";
try{
ProcessBuilder builder = new ProcessBuilder("java", package_dir.concat("/Code"));
builder.redirectErrorStream(true);
File outfile = new File((package_dir.concat("/output.txt")));
builder.redirectOutput();
builder.start();
if (outfile.length() > 3000)
{
System.out.println("Exceeded buffer limit");
System.exit(1);
}
} catch(IOException e) {
e.printStackTrace();
}
} catch (Exception err) {
System.out.println("Error!");
err.printStackTrace();
}
}
}
Error Message
Your path looks wrong. The /demo directory would need to be in the root of your current drive.
Also, the output of a Maven build is found in the target directory. The Java class files are generated there, and the resource files are copied over from src/main/res hierarchy. The .Java files are lost. You could add a Maven task to copy the .Java files but this would be very nonstandard.
Finally you need to load resource files using the classpath. There are lots of examples on the Internet. Otherwise you may end up with a project that finds the file in Eclipse but not when deployed in a .jar or .war file.
Happy hunting.

Properties file not loading and updating for relative path but working fine for absolute path

I am trying to access a properties file from the src/main/resources folder but when I try to load the file using a relative path it is not getting updated. But it is working fine for an absolute path.
I need the dynamic web project to work across all platforms.
public static void loadUsers() {
try(
FileInputStream in = new FileInputStream("C:\\Users\\SohamGuha\\Documents\\work-coding\\work-coding\\src\\main\\resources\\users.properties")) {
// write code to load all the users from the property file
// FileInputStream in = new FileInputStream("classpath:users.properties");
users.load(in);
System.out.println(users);
in.close();
}
catch(Exception e){
e.printStackTrace();
}
First of all you are using Spring, at least that is what the tags at the bottom say. Secondly C:\\Users\\SohamGuha\\Documents\\work-coding\\work-coding\\src\\main\\resources\\users.properties is the root of your classpath. Instead of loading a File use the Spring resource abstraction.
As this is part of the classpath you can simply use the ClassPathResource to obtain a proper InputStream. This will work regardless of which environment you are in.
try( InputStream in = new ClassPathResource("users.properties").getInputStream()) {
//write code to load all the users from the property file
//FileInputStream in = new FileInputStream("classpath:users.properties");
users.load(in);
System.out.println(users);
} catch(Exception e){
e.printStackTrace();
}
NOTE: you are already using a try with resources so you don't need to close the InputStream that is already handled for you.
Changing things inside your application simply won't work, as this would mean you could change resources (read classes) in your jar which would be quite a security risk! If you want something to be changable you will have to make it a file outside of the classpath and directly on the file-system.
Try the following code
import java.io.FileInputStream;
import java.io.IOException;
public class LoadUsers {
public static void main(String[] args) throws IOException {
try(FileInputStream fis=new FileInputStream("src/main/resources/users.properties")){
Properties users=new Properties();
users.load(fis);
System.out.println(users);
}catch(IOException ioe) {
ioe.printStackTrace();
}
}
}

FileInputStream look into root of Jar

I have a FileInputStream in a class in the package com.nishu.ld28.utilities, and I want to access sound files in the folder Sounds, which is not in the com.nishu.ld28 package. I specify the path for loading like so:
"sounds/merry_xmas.wav"
And then try to load it like this:
new BufferedInputStream(new FileInputStream(path))
When I export the jar, the command line prompt that I run it through says it can't find the file. I know how to access the files when I am running the program in Eclipse, but I can't figure out how to point the FileInputStream to the Sounds folder when I export it.
Edit: As requested, here's my code:
public void loadSound(String path) {
WaveData data = null;
data = WaveData.create(GameSound.class.getClassLoader().getResourceAsStream(path));
int buffer = alGenBuffers();
alBufferData(buffer, data.format, data.data, data.samplerate);
data.dispose();
source = alGenSources();
alSourcei(source, AL_BUFFER, buffer);
}
WaveData accepts an InputStream or other types of IO.
You don't need a FileInputStream, because you aren't reading from the filesystem. Use the InputStream returned by ClassLoader.getResourceAsStream(String res) or Class.getResourceAsStream(String res). So either
in = ClassLoader.getResourceAsStream("sounds/merry_xmas.wav");
or
in = getClass().getResourceAsStream("/sounds/merry_xmas.wav");
Note the leading slash in the second example.
I would put the com.nishu.ld28.utilities in the same package of your class , let's call it MyClass.
Your package:
Your code:
package com.nishu.ld28.utilities;
import java.io.InputStream;
public class MyClass {
public static void main(String[] args) {
InputStream is = MyClass.class.getResourceAsStream("sound/merry_xmas.wav");
System.out.format("is is null ? => %s", is==null);
}
}
Output
is is null ? => false

[Class].class.getResourceAsStream(...) returns null when used in JAR files in certain directories?

I have a very strange problem. It appears that loading resources from inside a JAR file sometimes works and sometimes doesn't.
The Jar file consists only of the class files, the manifest and the test.txt.
When I pack it with Eclipse, it usually works well (the contents of test.txt can be accessed) but in some directories, the Resourceproblem.class.getResourceAsStream("/test.txt") returns null - although it's the same Jar file!
For example when I double click the jar file \\remotecomputer\folder\subfolder\test.jar the test.txt inside the jar file could not be found. But it's also sometimes (?) the case when the path name is very long and contains spaces (at least on Windows XP SP3).
Any ideas?
Sample code:
import java.io.*;
import javax.swing.*;
public class Resourceproblem {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Resourceproblem();
}
});
}
private Resourceproblem() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
JTextArea text = new JTextArea();
text.setEditable(false);
frame.add(text);
frame.setVisible(true);
try {
InputStream in = Resourceproblem.class.getResourceAsStream("/test.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = br.readLine();
br.close();
in.close();
text.setText(line);
} catch(Exception ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
pw.flush();
String s = sw.toString();
pw.close();
ex.printStackTrace();
text.setText(s);
}
}
}
test.txt ist just a text file with a line for checking if the loading was successful.
I have an idea, but I have little confidence that I know what your problem is.
I used eclipse to create a jar file from your example source several times; I stored the jar file in c:\local and in c:\local\one\two three\four, using Win7.
I am unfamiliar with the use of "/" at the front of the resource filename in the getResourceAsStream() call. Your sample program worked in each case either with or without the "/", but I would recommend removing it and seeing if that solves your problem. The file, in that case, goes in the same directory as the class that is accessing it.
I would have thought that the "/" would cause the program to look for the file at the root directory of the file system, but that doesn't seem to happen...

Accessing file from package

suppose I put a file a.txt in package com.xyz and the try access it like following. Will it work?
Hi All,
import com.xyz.*;
public class Hello
{
File f = new File("a.txt");
...
}
It is not working for me. Is there any workaround?
Use Class.getResource() or Class.getResourceAsStream(). see for example the Sun demo source at http://jc.unternet.net/src/java/com/sun/WatermarkDemo/WatermarkDemo.java
I will offer the same answer as jcomeau_ictx, but a lot shorter (around 30 lines in one file as opposed to >380 in 1 source file of 5), ..and with a screenshot. ;)
import javax.swing.*;
import java.net.URL;
class GetResource {
GetResource() {
Class cl = this.getClass();
final URL url = cl.getResource( cl.getName() + ".java" );
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JEditorPane ep = new JEditorPane();
try {
ep.setPage(url);
JScrollPane sp = new JScrollPane(ep);
sp.setPreferredSize(new java.awt.Dimension(400,196));
JOptionPane.showMessageDialog(null, sp);
} catch(Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(
null,
e.getMessage() + " See trace for details.");
}
}
});
}
public static void main(String[] args) {
new GetResource();
}
}
Based on your responses to the comments above. If you are looking for a work around, just specify the path to the .txt file on the file system. Putting it in a package does not help.
new File ("a.txt")
looks for a file on the the file system and not within a package.
Please also read the javadocs on File:
http://download.oracle.com/javase/6/docs/api/java/io/File.html
However I do not see the rationale in putting the file inside a package unless you would want to use it as a resource. In which case #jcomeau_ictx has the right solution
It's depend on your class path of java from where you can run this class. If both are in same place then it will work. Then no need to define path in file. But the file was not in the classpath dir then must be define path of that file otherwise file not found.

Categories