java - reading config file in same directory as jar file - java

I have a simple program in Intellij that I made just to test out reading file path of config file.
I created a simple test case where I would use a timer to print "Hello world" periodically in N intervals where N is in milliseconds and N is configurable.
This is the code:
public void schedule() throws Exception {
Properties props=new Properties();
String path ="./config.properties";
FileInputStream fis=new FileInputStream(path);
BufferedReader in1=new BufferedReader(new InputStreamReader(fis));
// InputStream in = getClass().getResourceAsStream("/config.properties");
props.load(in1);
in1.close();
int value=Integer.parseInt(props.getProperty("value"));
Timer t=new Timer();
t.scheduleAtFixedRate(
new TimerTask() {
#Override
public void run() {
// System.out.println("HELEOELE");
try {
// test.index();
System.out.println("hello ");
} catch (Exception e) {
e.printStackTrace();
}
}
},
0,
value);
}
What I did was I set value as N in a config file where it can be changed by anyone without touching the actual code. So I compiled the jar file, and I placed both config.properties and jar file in same folder or directory. I want to be able to change make N changeable so I don't need to re-compile the jar again and again everytime.
Note: the config properties file is created manually and placed in same directory as the jar. And I am executing the jar in command prompt.
However, it seems when I try to run it, it doesn't recognize the file path.
"main" java.io.FileNotFoundException: .\config.properties (The system cannot find the file specified)
I've looked into many issues regarding reading config files outside of jar file and none of them worked for me. Am I doing any mistake here?

./config.properties is a relative path that points to a config.properties file in the current working directory.
The current working directory, unless changed by System.setProperty("user.dir", newPath), will be the directory from which you launched the JVM currently handling your code.
To get your jar to work as it currently is, you have two ways available :
copy the config.properties file to the directory you are executing java from
change the directory you are running java from to the one that contains the config.properties
You may also consider letting the user specify where to get the properties file from :
String path = System.getProperty("propertiesLocation", "config.properties");
You would then be able to specify a location for the property file when calling your jar :
java -jar /path/to/your.jar -DpropertiesLocation=/path/to/your.properties
Or call it as you did before to search for the properties at its default location of config.properties in the current working directory.

Related

Copying File In Current Working Directory is Not Working

private void copyFile() throws IOException {
Path destination;
String currentWorkingDir = System.getProperty("user.dir");
File fileToCopy = component.getArchiveServerFile();
if (path.contains(File.separator)) {
destination = Paths.get(path);
} else {
destination = Paths.get(currentWorkingDir + File.separator + path);
}
if (!Files.exists(destination)) {
try {
Files.createDirectories(destination);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
FileUtils.copyFileToDirectory(fileToCopy, new File(destination.toString()));
}
}
Basically what I'm trying to do here is copying a file in some location using the path provided in the class's constructor. The logic is like this:
If the path has file separator, I consider it a full path and copy the file at the end.
If the path doesn't have file separator, I copy the file in the working directory from which the .exe file was launched.
So far, only the first option works (the full path). For some reason, the working directory option is not working and I can't figure out why.
UPDATE: If I just change the following line:
String currentWorkingDir = System.getProperty("user.dir");
to
String currentWorkingDir = System.getProperty("user.home");
It works. So I'm guessing the problem is coming from user.dir? Maybe at runtime, the folder is already being used and as a result, it can't copy the file into it?
The weird thing is, I don't have any exceptions or error, but nothing happens as well.
UPDATE 2: I think the problem here is that I'm trying to copy a file which is embedded in the application (.exe file) that I'm executing during runtime, and java can't copy it while the current working directory is being used by the application.
UPDATE 3:
Since this copy method is used in an external library, I had to come up with another way (other than logs) to see the content of system property user.dir. So I wrote I little program to create a file and write in it the value return by the property.
To my surprise, the path is not where my application was launched. It was in:
C:\Users\jj\AppData\Local\Temp\2\e4j1263.tmp_dir1602852411
Which is weird because I launched the program from :
C:\Users\jj\workspace\installer\product\target\
Any idea why I'm getting this unexpected value for user.dir?

{Java} File exists but still showing FileNotFoundException Error

I need to read a .txt file of integers into a 2d array but when I try to read in the file I get a runetime error saying that the specified file cannot be found. This is the first time I've tried to read in a file so I just need direction on how to do it but I couldn't find an answer this basic.
I have the file of integers named "num1.txt" saved in the same folder as as my java file, so I'm wondering if I don't understand how eclipse and java decide where the file is.
public static void main(String[] args) throws FileNotFoundException
{
int i;
int j;
i=0;
j=0;
int connect4Array[][] = new int[6][7];
Scanner readFile = new Scanner(new File("num1.txt"));
while(readFile.hasNextInt())
{
for(i=0;i<connect4Array.length;i++)
{
connect4Array[i++][j]=readFile.nextInt();
for(j=0;j<connect4Array[j].length;j++)
{
connect4Array[i][j++]=readFile.nextInt();
}
}
}
First of all, it is NOT a compilation error. It is a runtime error. You need to learn the difference ... and to say the right thing, or else people won't understand what you are talking about.
I have the file of integers named "num1.txt" saved in the same folder as as my java file.
The problem is that you are trying to access the file in the running application's current directory ... but the current directory is not the place that you think / hope it is.
So where is the application's current directory? It depends on how you ran the application!
If you run the java app from a shell, then the current directory will default to the shell's current directory.
You can change it by cd-ing before you run java ... and I think you can also specify it using -Duser.dir=<pathname>.
If you run the java app from Eclipse, then the current directory will default to the project directory. That is probably different to the directory containing the source code.
You can specify a different current directory in the Eclipse settings for your application's launcher.
Alternatively, use an absolute path for the file, or put it into your application's JAR file and read it as a "resource".
move the file to where the src folder located.
because the default is project directory in your workspace.
you can use getProperty to check current directory.
String CurrentDir = System.getProperty("user.dir");
System.out.println("Current working directory : " + CurrentDir);

How to create executable file in Java using Netbeans

I made a cache simulator program for a homework, I decided to use java. I want to create an executable jar file that will work on any system, but the problem is that my program gathers data from an external text file. How can I include that text file inside the jar so that there won't be any problem when executing file? By the way, I am using NetBeans IDE.
If you don't need to write to the file, copy into the src directory. You will no longer be able to access like a File, but instead will need to use Class#getResource, passing it the path from the top of the source tree to where the file is stored.
For example, if you put it in src/data, then you'd need to use getClass().getResource("/data/..."), passing it what ever name the file is...
Clean and build...
Yes and I said Yes. To really make your jarfiles along with the text files. Please ensure that links to the folder on which the text files is where properly coded and well linked.
The three Examplary Method below should get you working irrespective of any IDEs. Please rate this and give me a shout if you still need further help.......Sectona
Method 1
Step 1:- Locate your folder that contain your java file by using cd command.
Step 2:- Once your enter your folder location then view your java file by dir
command.
Step 3:- Compile your java file using
javac file.java
Step 4:- view class file by type dir command.
Step 5:- Now you want to create a manifest file.
I)Go to folder<br>
II)Right-click->New->Text Document
III)open text document. Type main class name ,
Main-Class: main-class-name
IV)Save this file your wish like MyManifest.txt
Step 6:- To create executable jar file type
jar cfm JarFileName.jar MyManifest.txt JavaFike1.class JavaFile2.class
Step 7:- Now you see the Executable jar file on your folder. Click the file to
Run.
Step 8:- To run this file via command prompt then type
java -jar JarFileName.jar
Step 9:- You done this..........Sectona
Method 2
The basic format of the command for creating a JAR file is:
jar cf jar-file input-file(s)
The options and arguments used in this command are:
The c option indicates that you want to create a JAR file.
The f option indicates that you want the output to go to a file rather than to stdout.
jar-file is the name that you want the resulting JAR file to have. You can use any filename for a JAR file. By convention, JAR filenames are given a .jar extension, though this is not required.
The input-file(s) argument is a space-separated list of one or more files that you want to include in your JAR file. The input-file(s) argument can contain the wildcard * symbol. If any of the "input-files" are directories, the contents of those directories are added to the JAR archive recursively.
Method 3
import java.io.*;
import java.util.jar.*;
public class CreateJar {
public static int buffer = 10240;
protected void createJarArchive(File jarFile, File[] listFiles) {
try {
byte b[] = new byte[buffer];
FileOutputStream fout = new FileOutputStream(jarFile);
JarOutputStream out = new JarOutputStream(fout, new Manifest());
for (int i = 0; i < listFiles.length; i++) {
if (listFiles[i] == null || !listFiles[i].exists()|| listFiles[i].isDirectory())
System.out.println();
JarEntry addFiles = new JarEntry(listFiles[i].getName());
addFiles.setTime(listFiles[i].lastModified());
out.putNextEntry(addFiles);
FileInputStream fin = new FileInputStream(listFiles[i]);
while (true) {
int len = fin.read(b, 0, b.length);
if (len <= 0)
break;
out.write(b, 0, len);
}
fin.close();
}
out.close();
fout.close();
System.out.println("Jar File is created successfully.");
} catch (Exception ex) {}
}
public static void main(String[]args){
CreateJar jar=new CreateJar();
File folder = new File("C://Answers//Examples.txt");
File[] files = folder.listFiles();
File file=new File("C://Answers//Examples//Examples.jar");
jar.createJarArchive(file, files);
}
}
You can keep any file in classpath and read as class path resource. Sample code is given below.
InputStream in = this.getClass().getClassLoader().getResourceAsStream("yourinputFile.txt");
Your jar will be class path, that means you can keep your file in root folder of java source which will get added to jar file while building it.

java.io.FileNotFoundException (File not found) using Scanner. What's wrong in my code?

I've a .txt file ("file.txt") in my netbeans "/build/classes" directory.
In the same directory there is the .class file compiled for the following code:
try {
File f = new File("file.txt");
Scanner sc = new Scanner(f);
}
catch (IOException e) {
System.out.println(e);
}
Debugging the code (breakpoint in "Scanner sc ..") an exception is launched and the following is printed:
java.io.FileNotFoundException: file.txt (the system can't find the
specified file)
I also tried using "/file.txt" and "//file.txt" but same result.
Thank you in advance for any hint
If you just use new File("pathtofile") that path is relative to your current working directory, which is not at all necessarily where your class files are.
If you are sure that the file is somewhere on your classpath, you could use the following pattern instead:
URL path = ClassLoader.getSystemResource("file.txt");
if(path==null) {
//The file was not found, insert error handling here
}
File f = new File(path.toURI());
The JVM will look for the file in the current working directory.
Where this is depends on your IDE settings (how your program is executed).
To figure out where it expects file.txt to be located, you could do
System.out.println(new File("."));
If it for instance outputs
/some/path/project/build
you should place file.txt in the build directory (or specify the proper path relative to the build directory).
Try:
File f = new File("./build/classes/file.txt");
Use "." to denote the current directory
String path = "./build/classes/file.txt";
File f = new File(path);
File Object loads, looking for match in its current directory.... which is Directly in Your project folder where your class files are loaded not in your source ..... put the file directly in the project folder

How to pass a text file as a argument?

Im trying to write a program to read a text file through args but when i run it, it always says the file can't be found even though i placed it inside the same folder as the main.java that im running.
Does anyone know the solution to my problem or a better way of reading a text file?
Do not use relative paths in java.io.File.
It will become relative to the current working directory which is dependent on the way how you run the application which in turn is not controllable from inside your application. It will only lead to portability trouble. If you run it from inside Eclipse, the path will be relative to /path/to/eclipse/workspace/projectname. If you run it from inside command console, it will be relative to currently opened folder (even though when you run the code by absolute path!). If you run it by doubleclicking the JAR, it will be relative to the root folder of the JAR. If you run it in a webserver, it will be relative to the /path/to/webserver/binaries. Etcetera.
Always use absolute paths in java.io.File, no excuses.
For best portability and less headache with absolute paths, just place the file in a path covered by the runtime classpath (or add its path to the runtime classpath). This way you can get the file by Class#getResource() or its content by Class#getResourceAsStream(). If it's in the same folder (package) as your current class, then it's already in the classpath. To access it, just do:
public MyClass() {
URL url = getClass().getResource("filename.txt");
File file = new File(url.getPath());
InputStream input = new FileInputStream(file);
// ...
}
or
public MyClass() {
InputStream input = getClass().getResourceAsStream("filename.txt");
// ...
}
Try giving an absolute path to the filename.
Also, post the code so that we can see what exactly you're trying.
When you are opening a file with a relative file name in Java (and in general) it opens it relative to the working directory.
you can find the current working directory of your process using
String workindDir = new File(".").getAbsoultePath()
Make sure you are running your program from the correct directory (or change the file name so that it will be relative to where you are running it from).
If you're using Eclipse (or a similar IDE), the problem arises from the fact that your program is run from a few directories above where the actual source is located. Try moving your file up a level or two in the project tree.
Check out this question for more detail.
The simplest solution is to create a new file, then see where the output file is. That is the correct place to put your input file into.
If you put the file and the class working with it under same package can you use this:
Class A {
void readFile (String fileName) {
Url tmp = A.class.getResource (fileName);
// Or Url tmp = this.getClass().getResource (fileName);
File tmpFile = File (tmp);
if (tmpFile.exists())
System.out.print("I found the file.")
}
}
It will help if you read about classloaders.
say I have a text file input.txt which is located on the desktop
and input.txt has the following content
i came
i saw
i left
and below is the java code for reading that text file
public class ReadInputFromTextFile {
public static void main(String[] args) throws Exception
{
File file = new File(
"/Users/viveksingh/desktop/input.txt");
BufferedReader br
= new BufferedReader(new FileReader(file));
String st;
while ((st = br.readLine()) != null)
System.out.println(st);
}
}
output on the console:
i came
i saw
i left

Categories

Resources