Specify a Relative Path from a Package for a new File - java

I'm trying to create a File object in order to save my properties file. I need to know how to specify a relative path from my package though because the below code does not work.
try {
File file = new File(new File(Thread.currentThread().getContextClassLoader().getResource("").toURI()), "com/configuration/settings.properties");
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
properties.store(fileOutputStream, null);
}
} catch (IOException | URISyntaxException ioe) {
System.out.println(ioe);
}

Just replace this line:
File file = new File("/com/configuration/settings.properties");
with:
File file = new File(new File(Thread.currentThread().getContextClassLoader().getResource("").toURI()), "com/configuration/settings.properties");

Relative path depends on current working directory from where you are running your program.
If you are running in IDE, IDE may set working directory path to Project directory. And How your program run depends on classpath to jar/claases in your program.

Related

create bunch of files in particular directory

I am trying to create lot of files in particular directory. If directory doesn't exist then it should create the directory and create bunch of files in it.
Whereever my program is running, it should create a "files" directory if it is not there and inside this "files" folder, I want to create bunch of files in it.
I have my below code but it looks like it is creating bunch of folders instead of one folder and all the files in that folder. What wrong I am doing?
for (Entry<String, String> entry : tasks.entrySet()) {
// looks like something is wrong here but can't figure out what wrong I am doing?
File file = new File("files/" + entry.getKey());
file.mkdirs();
try (BufferedWriter writer =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),
StandardCharsets.UTF_8))) {
writer.write(entry.getValue());
} catch (IOException ex) {
// log error
}
}
For example, you're trying to create file C:\Stuff\Things\other.txt
With your current code, you create the folder C:\Stuff\Things\other.txt\
When you attempt to write to the file, moo.txt, it cannot, because you put a folder there (...\other.txt\)
Instead, create the folders up to, but not including the file name, before writing your file (C:\Stuff\Things\)
File file = new File(...);
file.getParentFile().mkdirs();
try(BufferedWriter ...

Can't find resources runnable jar

I can't load an resource file after extracting a project as a runnable jar.
It works in Eclipse but after exporting it throws a FileNotFoundException.
I have tried to put the res folder next to the .jar file but nothing helps. I've tried with JarSplice and got it running with all the libraries but it stops with the resource file. The object file is located in a source folder.
What can I do?
Code
FileReader fr = null;
try {
fr = new FileReader(new File("res/" + fileName + ".obj"));
} catch (FileNotFoundException e) {
System.err.println("Couldn't load object file!");
e.printStackTrace();
}
EDIT: By opening the runnable .jar file in 7zip I can see that the whole /res folder has disappeared during the exporting and the files in the directory now lies directly in the root folder of the .jar file.
Based on your code, the res folder should be placed directly off the present working directory, which should be the directory where you are running the Java command from. For an example, see this question on how to determine the current working directory from inside Java.
Use Path instead of new File(string).
FileReader fr = null;
try {
fr = new FileReader(Paths.get("res/" + fileName + ".obj").toFile());
} catch (FileNotFoundException e) {
System.err.println("Couldn't load object file!");
e.printStackTrace();
}

Java properties file is saved in system32 folder

So, my I have a method that saves some data in a properties file but something weird happens. See, lets say I have the JAR file on desktop. If I open it directly from there (double click, etc) the properties file is saved in the desktop, as should be. However, if you drag the JAR to the Windows start list and open it from there, the properties file will be saved in the System32 folder.
Here is the method:
private void saveAncientsData() {
Properties prop = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream("ancients.data");
File file = new File("ancients.data");
// set the properties value
for (int x = 0; x < currentLvlSpinnerFields.size(); x++) {
prop.setProperty(ancientNames[x], currentLvlSpinnerFields.get(ancientNames[x]).getValue().toString());
}
// save properties to project root folder
prop.store(output, null);
JOptionPane.showMessageDialog(this, "Data successfully saved in \n\n" + file.getCanonicalPath(), "Saved", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Would appreciate any help, since I am clueless.
Thanks in advance!
according to your code you haven't give path of property file to create in desktop.
output = new FileOutputStream("ancients.data");
so your property file will be created in same directory where your jar file exists .
but if you run this .jar file from a parent process your jar file created in the directory where that parent process exists.
i guess when windows starts a specific process exist in win32 directory execute start-up programs .i think it's userinit.exe . so your prop file will be created in System32 directory .
if you want property file to create in desktop you can put your jar file in desktop and add a shortcut to .jar or you can give full-path to your desktop like
output = new FileOutputStream(System.getProperty("user.home") + "/Desktop/"+"ancients.data");
edit
to understand this problem
1) create a folder named example in desktop.and then create 2 folders path1 and path2 .then add .jar to path1 folder
2) double click jar in path1 .and a property file will be created in path1 as you expected .
3) delete property file.open command prompt in path2 . To run Prop.jar file in path1 . type call "pathtodesktop/example/path1/Prop.jar" hit enter.
.property file will be created in path2 instead of path1 that's what happening in your case.

Get file in the resources folder in Java

I want to read the file in my resource folder in my Java project. I used the following code for that
MyClass.class.getResource("/myFile.xsd").getPath();
And I wanted to check the path of the file. But it gives the following path
file:/home/malintha/.m2/repository/org/wso2/carbon/automation/org.wso2.carbon.automation.engine/4.2.0-SNAPSHOT/org.wso2.carbon.automation.engine-4.2.0-SNAPSHOT.jar!/myFile.xsd
I get the file path in the maven repository dependency and it is not getting the file. How can I do this?
You need to give the path of your res folder.
MyClass.class.getResource("/res/path/to/the/file/myFile.xsd").getPath();
Is your resource directory in the classpath?
You are not including resource directory in your path:
MyClass.class.getResource("/${YOUR_RES_DIR_HERE}/myFile.xsd").getPath();
A reliable way to construct a File instance from the resource folder is it to copy the resource as a stream into a temporary File (temp file will be deleted when the JVM exits):
public static File getResourceAsFile(String resourcePath) {
try {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if (in == null) {
return null;
}
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
//copy stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return tempFile;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
It is not possible to access resources of other maven modules. So you need to provide your resource myFile.xsd in your src/main/resources or src/test/resources folder.
The path is correct, though not on the file system, but inside the jar. That is, because the jar was running. A resource never is guaranteed to be a File.
However if you do not want to use resources, you can use a zip file system. However Files.copy would suffice to copy the file outside the jar. Modifying the file inside the jar is a bad idea. Better use the resource as "template" to make an initial copy in the user's home (sub-)directory (System.getProperty("user.home")).
In maven project, lets assume that, we have the file whose name is "config.cnf" and it's location is below.
/src
/main
/resources
/conf
config.cnf
In IDE (Eclipse), I access this file by using ClassLoader.getResource(..) method, but if I ran this application by using jar, I always across "File not found" exception. Finally, I wrote a method which accessing the file by looking at where app works.
public static File getResourceFile(String relativePath)
{
File file = null;
URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
String codeLoaction = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
file = path.toFile();
}else{
//Call from IDE
file = new File(<Class>.class.getClassLoader().getResource(relativePath).getPath());
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return file;
}
If you call this method by sending "conf/config.conf" param, you access this file from both jar and IDE.

How to build jar using Eclipse "Export as jar option" with a properties file

public xFbConfigReader()
{
//props = new Properties();
propsdatabase = new Properties();
try
{
// load a properties file
InputStream dbin = getClass().getResourceAsStream("/properties/database.properties");
propsdatabase.load(dbin);
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
I keep My properties File named 'Database.properties' in a folder where the project is named 'Properties'.
When I do a Export as jar in Eclipse . The Properties Folder is visible.
But When I run the program it shows that there is a NUll point exception in dbin.
So which means I require the proper way to form a jar in Eclipse .Kindly suggest.
The better solution while handling properties file would be reading
static Properties databaseproperties= new Properties();
static {
try {
connectionProps.load(YourClassName.class.getClassLoader()
.getResourceAsStream("databaseproperties.properties"));
} catch (Exception e) {
System.out.println("Exception is " + e.getMessage());
}
}
This is better approch because
we can move our properties file to someother folder.
And infact we can keep properties folder out side of jar. say you can create
a folder called Configuration where you can include all the
properties files. As it is out side of jar you can change the
properties file when ever is required.
For change in properties
file no need to unjar it.
(OR) simply you can make this change no need to think about directory structure
Step 1: Move properties file to SRC
step 2: change this line as
follows
InputStream dbin = getClass().getResourceAsStream("/database.properties");
This is not much different from previous code as it is anyway stays inside the JAR file.
you are getting null pointer exception because properties file is not loaded try to use
FileInputStream to load the properties as follows
FileInputStream dbin = new FileInputStream("/properties/database.properties");
properties.load(dbin);

Categories