Read a source file for a custom ant task - java

I want to open a source file for my custom ant task. I thought this would be easy, because surely the class loader get resource would immediately find the source file for me. Wrong!
Here's my code:
//build the name of the template
StringBuilder sb = new StringBuilder(VersionTemplate.class.getName());
sb.append(".java");
String templateName = sb.toString();
//find the template
InputStream inputStream = VersionTemplate.class.getResourceAsStream(templateName);
inputStream is always null.
Any ideas?

Try:
templateName = templateName.replaceAll(".","/");
InputStream inputStream = VersionTemplate.class.getClassLoader().
getResourceAsStream(templateName);
Please make sure ".java" file is present in the same package as compile ".class" files.

It occurred to me after the fact that getResource() looks on the class path, which is not where the source code is. I ended up simply just coding a relative path to the code.
Thanks for the help.

Related

How to get the path of a file inside a project to read it with OpenCSV

I have a CSV file inside a folder that's inside the source folder but I can't get to it.
I got it to work with what I've found on internet:
URL url = getClass().getResource("/csv/recetas.csv");
File file = new File(url.getPath());
FileReader fileReader = new FileReader(file);
CSVReader csvReader = new CSVReader(fileReader, ',', '"', 1);
but it only works when I run it in the IDE. When I build the jar and try to run it, the FileReader can't find the file, it doesn't throw error for URL or File.
Here is my project folder so you can understand me. Thanks.
InputStream in = getClass().getResourceAsStream("/csv/recetas.csv");
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
CSVReader(reader, ',', '"', 1);
Resources are class path "files" possibly packed in a jar. They are not File, and are read-only.
Also for compatibility, give the charset explicitly.
The getClass().getResource() uses the class loader to load the resource. This means that your csv file will not be visible unless it is in the classpath.
Looking at your code and your problem again, getClass().getResource() seems redundant to me as the constructor of File(...) accepts a file path depicted as String.
See:
https://docs.oracle.com/javase/7/docs/api/java/io/File.html
Quote:
File(String pathname) Creates a new File instance by converting the
given pathname string into an abstract pathname.
To make your program more versatile I would recommend you to avoid hardcoding the file path as the csv file can be anywhere within the file system and it may not always be called recetas.csv.
What people typically would do is to make the java program accept an option like --csv. Then let the user specify the filepath and your code will just be new File(theSpecifiedPath).

How to not hard-code a file path

I'd like to calculate the path of a file placed into Source Packages using this implementation:
URL pathSource = this.getClass().getResource("saveItem.xml");
When I try to create a new File like the code below:
File xmlFile = new File(pathSource.toString());
And I try to use it to create a document like this:
Document document = builder.parse(xmlFile);
This give me the java.io.FileNotFoundException.
How can I calculate the file path without hard-coding?
PS: I already used pathSource.getPath() but it doesn't work either.
I would like to use a similar implementation:
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
PPS: The structure is the following:
You can't access a resource that inside a JAR file as a File instance. You can only get an InputStream to it.
As such, the following line
File xmlFile = new File(pathSource.toString());
won't work properly and when an attempt is made to read it later, a FileNotFoundException will be thrown.
Assuming you're trying to parse a XML file using DocumentBuilder, you can use the parse(InputStream) method:
try (InputStream stream = this.getClass().getResourceAsStream("saveItem.xml")) {
Document document = builder.parse(stream);
}
Short answer - saveItem.xml is not in the classpath.
If it is a web application, then file may be added to WEB-INF/classes folder.
Edit:
Try this.getClass().getResourceAsStream() too.
getClass().getResource("saveItem.xml");
looks for the file in the same package (which are directories when you look at the file system) as the class that getClass() returns.
Make sure the file is in there. Also make sure it's really in there when you run your code, there's a difference between your source folder and the target or bin folder where the compiled class files are placed.
Also check what pathSource.toString() contains.

java.lang.NullPointerException while getting a filepath in Java (executing through a jar file)

I am getting an NPE at the point of getting path of a File (an sh file in assets folder).
I have tried to read about NPE i detail from the following thread, but this actually could not solve my problem.
What is a NullPointerException, and how do I fix it?
Following is my code snippet:
File absPathofBash;
url = ClassLoader.class.getResource("assets/forbackingup.sh");
absPathofBash = new File(url.getPath());
Later I'm using it in a ProcessBuilder, as
ProcessBuilder pb = new ProcessBuilder(url.getPath(), param2, param3)
I've also tried getting the absolute path directly, like
absPathofBash = new File("assets/forbackingup.sh").getAbsolutePath();
Using the latter way, I am able to process it, but if I create a jar then the file cannot be found. (although the Jar contains the file within the respective folder assets)
I would be thankful if anyone can help me on that.
Once you have packaged your code as a jar, you can not load files that are inside the jar using file path, instead they are class resources and you have to use this to load:
this.getClass().getClassLoader().getResource("assets/forbackingup.sh");
This way you load assets/forbackingup.sh as an absolute path inside your jar. you also can use this.getClass().getResource() but this way the path must be relative to this class path inside jar.
getResource method gives you an URL, if you want to get directly an InputStream you can use getResourceAsStream
Hope it helps!
Since the file itself is in the jar file, you could try using:
InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileNameFromJar);
In case of jar file , classloader will return URL different than that of when the target file is not embedded inside jar. Refer to answer on link which should help u :
How to use ClassLoader.getResources() in jar file
I got it done by creating a temp file. Though it's not difficult, yet I'm posting the code patch here:
InputStream stream = MyClass.class.getClassLoader().
getResourceAsStream("assets/forbackingup.sh");
File temp = File.createTempFile("forbackingup", ".sh");
OutputStream outputStream =
new FileOutputStream(temp);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
outputStream.close();
}
Now, we have this temp file here which we can pipe to the ProcessBuilder like,
String _filePath=temp.getPath();
ProcessBuilder pb = new ProcessBuilder(url.getPath(), param2, param3)
Thank you everyone for your considerations.
You can use Path class like :
Path path = Paths.get("data/test-write.txt");
if(!Files.exists(path)){
// can handle null pointer exception
}

FileInputStream and FileNotFound Exception

I am trying to retrieve a jrxml file in a relative path using the following java code:
String jasperFileName = "/web/WEB-INF/reports/MemberOrderListReport.jrxml";
File report = new File(jasperFileName);
FileInputStream fis = new FileInputStream(report);
However, most probably I didn't succeed in defining the relative path and get an java.io.FileNotFoundException: error during the execution.
Since I am not so experienced in Java I/O operations, I didn't solve my problem. Any helps or ideas are welcomed.
You're trying to treat the jrxml file as an object on the file-system, but that's not applicable inside a web application.
You don't know how or where your application will be deployed, so you can't point a File at it.
Instead you want to use getResourceAsStream from the ServletContext. Something like:
String resourceName = "/WEB-INF/reports/MemberOrderListReport.jrxml"
InputStream is = getServletContext().getResourceAsStream(resourceName);
is what you're after.
You should place 'MemberOrderListReport.jrxml' in classpath, such as it being included in a jar placed in web-inf\lib or as a file in web-inf\classes.
The you can read the file using the following code:
InputStream is=YourClass.class.getClassLoader().getResourceAsStream("MemberOrderListReport.jrxml");
String jasperFileName = "/web/WEB-INF/reports/MemberOrderListReport.jrxml";
Simple. You don't have a /web/WEB-INF/reports/MemoberOrderListReport.jrxml file on your computer.
You are clearly executing in a web-app environment and expecting the system to automatically resolve that in the context of the web-app container. It doesn't. That's what getRealPath() and friends are for.
check that your relative base path is that one you think is:
File f = new File("test.txt");
System.out.println(f.getAbsoluteFile());
I've seen this kind of problem many times, and the answer is always the same...
The problem is the file path isn't what you think it is. To figure it out, simply add this line after creating the File:
System.out.println(report.getAbsolutePath());
Look at the output and you immediately see what the problem is.

How to read file from relative path in Java project? java.io.File cannot find the path specified

I have a project with 2 packages:
tkorg.idrs.core.searchengines
tkorg.idrs.core.searchengines
In package (2) I have a text file ListStopWords.txt, in package (1) I have a class FileLoadder. Here is code in FileLoader:
File file = new File("properties\\files\\ListStopWords.txt");
But I have this error:
The system cannot find the path specified
Can you give a solution to fix it?
If it's already in the classpath, then just obtain it from the classpath instead of from the disk file system. Don't fiddle with relative paths in java.io.File. They are dependent on the current working directory over which you have totally no control from inside the Java code.
Assuming that ListStopWords.txt is in the same package as your FileLoader class, then do:
URL url = getClass().getResource("ListStopWords.txt");
File file = new File(url.getPath());
Or if all you're ultimately after is actually an InputStream of it:
InputStream input = getClass().getResourceAsStream("ListStopWords.txt");
This is certainly preferred over creating a new File() because the url may not necessarily represent a disk file system path, but it could also represent virtual file system path (which may happen when the JAR is expanded into memory instead of into a temp folder on disk file system) or even a network path which are both not per definition digestable by File constructor.
If the file is -as the package name hints- is actually a fullworthy properties file (containing key=value lines) with just the "wrong" extension, then you could feed the InputStream immediately to the load() method.
Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("ListStopWords.txt"));
Note: when you're trying to access it from inside static context, then use FileLoader.class (or whatever YourClass.class) instead of getClass() in above examples.
The relative path works in Java using the . specifier.
. means same folder as the currently running context.
.. means the parent folder of the currently running context.
So the question is how do you know the path where the Java is currently looking?
Do a small experiment
File directory = new File("./");
System.out.println(directory.getAbsolutePath());
Observe the output, you will come to know the current directory where Java is looking. From there, simply use the ./ specifier to locate your file.
For example if the output is
G:\JAVA8Ws\MyProject\content.
and your file is present in the folder "MyProject" simply use
File resourceFile = new File("../myFile.txt");
Hope this helps.
The following line can be used if we want to specify the relative path of the file.
File file = new File("./properties/files/ListStopWords.txt");
InputStream in = FileLoader.class.getResourceAsStream("<relative path from this class to the file to be read>");
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
try .\properties\files\ListStopWords.txt
I could have commented but I have less rep for that.
Samrat's answer did the job for me. It's better to see the current directory path through the following code.
File directory = new File("./");
System.out.println(directory.getAbsolutePath());
I simply used it to rectify an issue I was facing in my project. Be sure to use ./ to back to the parent directory of the current directory.
./test/conf/appProperties/keystore
While the answer provided by BalusC works for this case, it will break when the file path contains spaces because in a URL, these are being converted to %20 which is not a valid file name. If you construct the File object using a URI rather than a String, whitespaces will be handled correctly:
URL url = getClass().getResource("ListStopWords.txt");
File file = new File(url.toURI());
Assuming you want to read from resources directory in FileSystem class.
String file = "dummy.txt";
var path = Paths.get("src/com/company/fs/resources/", file);
System.out.println(path);
System.out.println(Files.readString(path));
Note: Leading . is not needed.
I wanted to parse 'command.json' inside src/main//js/Simulator.java. For that I copied json file in src folder and gave the absolute path like this :
Object obj = parser.parse(new FileReader("./src/command.json"));
For me actually the problem is the File object's class path is from <project folder path> or ./src, so use File file = new File("./src/xxx.txt"); solved my problem
For me it worked with -
String token = "";
File fileName = new File("filename.txt").getAbsoluteFile();
Scanner inFile = null;
try {
inFile = new Scanner(fileName);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while( inFile.hasNext() )
{
String temp = inFile.next( );
token = token + temp;
}
inFile.close();
System.out.println("file contents" +token);
If text file is not being read, try using a more closer absolute path (if you wish
you could use complete absolute path,) like this:
FileInputStream fin=new FileInputStream("\\Dash\\src\\RS\\Test.txt");
assume that the absolute path is:
C:\\Folder1\\Folder2\\Dash\\src\\RS\\Test.txt
String basePath = new File("myFile.txt").getAbsolutePath();
this basepath you can use as the correct path of your file
if you want to load property file from resources folder which is available inside src folder, use this
String resourceFile = "resources/db.properties";
InputStream resourceStream = ClassLoader.getSystemClassLoader().getResourceAsStream(resourceFile);
Properties p=new Properties();
p.load(resourceStream);
System.out.println(p.getProperty("db"));
db.properties files contains key and value db=sybase
If you are trying to call getClass() from Static method or static block, the you can do the following way.
You can call getClass() on the Properties object you are loading into.
public static Properties pathProperties = null;
static {
pathProperties = new Properties();
String pathPropertiesFile = "/file.xml";
// Now go for getClass() method
InputStream paths = pathProperties.getClass().getResourceAsStream(pathPropertiesFile);
}

Categories

Resources