Java Class Read a Yaml Inside Jar - java

I am trying to read a file inside my jar from another class inside the jar. However I am continually getting the same error: Caught: class java.io.FileNotFoundException while attempting to read metrics: metrics.yml
At first I had my code do something like this, assuming it was from the path of the class:
String yamlPath = ".." + File.separator + ".." + File.separator + ".." + File.separator + ".." + File.separator + "myYaml.yml";
InputStream in = new FileInputStream(new File(yamlPath));
InputStreamReader isr = new InputStreamReader(in);
BufferedReader input = new BufferedReader(isr);
yamlObj = (HashMap) javaYAML.load(input);
I also did this assuming it might take the path from the base of the jar:
String yamlPath = "myYaml.yml";
InputStream in = new FileInputStream(new File(yamlPath));
InputStreamReader isr = new InputStreamReader(in);
BufferedReader input = new BufferedReader(isr);
yamlObj = (HashMap) javaYAML.load(input);
I then noticed this thread How to read a file from jar in Java? and found out that I needed a "/" before my path. I tried both methods above using the slash as well.
String yamlPath = File.seperator + ".." + File.separator + ".." + File.separator + ".." + File.separator + ".." + File.separator + "myYaml.yml";
OR
String yamlPath = File.seperator + "myYaml.yml";
I am completely lost on what to do about this error now. Is there something I am not getting about the jar structure? Why can my file not be found. Thanks in advance for any help / information.
Sorry, I forgot to mention where it is in the JAR:
The class is in the following path: com/a/b/c/myclass.class
The yaml is in the following path: myYaml.yml

File inside Jar is no longer a File, Change inputStream creation with this
InputStream in = YourClass.class.getResourceAsStream("myYaml.yml");
Assuming your .yml file is at root of jar

InputStream is = this.getClass().getClassLoader().getResourceAsStream("file");

Somehow for me, i have to add '/' in front of the file name.
InputStream resourceAsStream = Xx.class.getResourceAsStream("/test.yml");
From java doc:
Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').
And after i checked more detailed information, my solution is same as
InputStream in = Xx.class.getClassLoader().getResourceAsStream("test.yml");

Related

Normalization does not solve Fortify error

Recently we added checking with Fortify to our code during build.
Following there are 2 lines of code, both lines cause 2 critical errors in Fortify: "Path manipulation".
Notice that I added the call to normalize() just to avoid that, and for the same reason I used a Path instead of String.
But now, instead of having 1 error as previously, I have 2 errors (in both lines).
Path normalizedPath = Paths.get(aPath + "/" + aStringFromDB + "/" + aFileName + ".txt").normalize();
BufferedOutputStream b = new BufferedOutputStream(new FileOutputStream(new File(String.valueOf(normalizedPath))));
What am I doing wrong?
It came out that the "normalize" of Path was not considered by Fortify.
The solution was to import and use the Apache normalize():
// import org.apache.commons.io.FilenameUtils;
String normalizedPath = FilenameUtils.normalize((aPath + "/" + aStringFromDB + "/" + aFileName + ".txt");
BufferedOutputStream b = new BufferedOutputStream(new FileOutputStream(new File(normalizedPath)));

"FileNotFoundException" while opening file from jar, while it definitely exists [duplicate]

I am trying to read a file inside my jar from another class inside the jar. However I am continually getting the same error: Caught: class java.io.FileNotFoundException while attempting to read metrics: metrics.yml
At first I had my code do something like this, assuming it was from the path of the class:
String yamlPath = ".." + File.separator + ".." + File.separator + ".." + File.separator + ".." + File.separator + "myYaml.yml";
InputStream in = new FileInputStream(new File(yamlPath));
InputStreamReader isr = new InputStreamReader(in);
BufferedReader input = new BufferedReader(isr);
yamlObj = (HashMap) javaYAML.load(input);
I also did this assuming it might take the path from the base of the jar:
String yamlPath = "myYaml.yml";
InputStream in = new FileInputStream(new File(yamlPath));
InputStreamReader isr = new InputStreamReader(in);
BufferedReader input = new BufferedReader(isr);
yamlObj = (HashMap) javaYAML.load(input);
I then noticed this thread How to read a file from jar in Java? and found out that I needed a "/" before my path. I tried both methods above using the slash as well.
String yamlPath = File.seperator + ".." + File.separator + ".." + File.separator + ".." + File.separator + ".." + File.separator + "myYaml.yml";
OR
String yamlPath = File.seperator + "myYaml.yml";
I am completely lost on what to do about this error now. Is there something I am not getting about the jar structure? Why can my file not be found. Thanks in advance for any help / information.
Sorry, I forgot to mention where it is in the JAR:
The class is in the following path: com/a/b/c/myclass.class
The yaml is in the following path: myYaml.yml
File inside Jar is no longer a File, Change inputStream creation with this
InputStream in = YourClass.class.getResourceAsStream("myYaml.yml");
Assuming your .yml file is at root of jar
InputStream is = this.getClass().getClassLoader().getResourceAsStream("file");
Somehow for me, i have to add '/' in front of the file name.
InputStream resourceAsStream = Xx.class.getResourceAsStream("/test.yml");
From java doc:
Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').
And after i checked more detailed information, my solution is same as
InputStream in = Xx.class.getClassLoader().getResourceAsStream("test.yml");

Getting the right slash for each platform

I have a JFilechooser to select a filename and path to store some data. But I also want to store an additional file in the same path, same name but different extension. So:
File file = filechooser.getSelectedFile();
String path = file.getParent();
String filename1 = file.getName();
// Check the extension .ext1 has been added, else add it
if(!filename1.endswith(".ext1")){
filename2 = filename1 + ".ext2";
filename1 += ".ext1";
}
else{
filename2 = filename1;
filename2 = filename2.substring(0, filename2.length-4) + "ext2";
}
// And now, if I want the full path for these files:
System.out.println(path); // E.g. prints "/home/test" withtout the ending slash
System.out.println(path + filename1); // E.g. prints "/home/testfilename1.ext1"
Of course I could add the "/" in the middle of the two strings, but I want it to be platform independent, and in Windows it should be "\" (even if a Windows path file C:\users\test/filename1.ext1 would probably work).
I can think of many dirty ways of doing this which would make the python developer I'm carrying inside cry, but which one would be the most clean and fancy one?
You can use the constants in the File class:
File.separator // e.g. / or \
File.pathSeparator // e.g. : or ;
or for your path + filename1 you can do
File file = new File(path, filename1);
System.out.println(file);
Just use the File class:
System.out.println(new File(file.getParent(), "filename1"));
You can use:
System.getProperty("file.separator");

Create a File in a folder

In Java, I have a File object representing a folder:
String folderName = "/home/vektor/folder";
File folder = new File(folderName);
Now I want to create another File representing a file in this folder. I want to avoid doing a string concatenation like this:
String fileName = "test.txt";
File file = new File(folderName + "/" + fileName);
Because if I go deeper in creating this structure, I will come up with something like this:
File deepFile = new File(folderName + "/" + anotherFolderName + ... + "/" + fileName);
I would instead like to do something like
File betterFile = folder.createUnder(fileName);
Or even:
File otherFile = SomeFileUtils.createFileInFolder(folder, fileName);
Do you know of such solution?
Note: It's quite OK to use "/" because Java will translate it to "\" for Windows, but it is not clean - I should use something like "file.separator" from System.getProperties().
Look at the Javadoc for File and you will see that the constructor takes a File object as parent.
Use the following form:
File deepFile = new File(folder, fileName);
I would use
String folderName =
String fileName =
File under = new File(folderName, fileName);
or
File folderFile =
String fileName =
File under = new File(folderFile, fileName);
simple as that ;)

create a text file in a folder

I want to create a text file into that folder that I am creating here.
File dir = new File("crawl_html");
dir.mkdir();
String hash = MD5Util.md5Hex(url1.toString());
System.out.println("hash:-" + hash);
File file = new File(""+dir+"\""+hash+".txt");
But this code doesn't create the text file into that folder..Instead it makes the text file outside that folder..
One of java.io.File's constructors takes a parent directory. You can do this instead:
final File parentDir = new File("crawl_html");
parentDir.mkdir();
final String hash = "abc";
final String fileName = hash + ".txt";
final File file = new File(parentDir, fileName);
file.createNewFile(); // Creates file crawl_html/abc.txt
What you need is
File file = new File(dir, hash + ".txt");
The key here is the File(File parent, String child) constructor. It creates a file with the specified name under the provided parent directory (provided that directory exists, of course).
The line
new File(""+dir+"\""+hash+".txt");
makes a file named crawl_html"the_hash.txt, because \" inside a String literal is used to represent a double quote caracter, not a backslash. \\ must be used to represent a backslash.
Use the File constructor taking a File (directory) as the first argument, and a file name as a second argument:
new File(dir, hash + ".txt");
your path-delimiter seems off
try:
File file = new File ( "" + dir + "/" + hash + ".txt" );

Categories

Resources