Why do I get NullPointerException when trying to access resource file? - java

I want to make so a file in the program is packaged in the jar file because it is needed in my program. It is the firebase credentials file. I read that I need to add it to the resource folder but now I cannot access it because I get NullPointerException. I think the path is valid and everything seems okay but I get null every time. Here is the code:
ClassLoader classLoader = EmailSender.class.getClassLoader();
File file = new File(Objects.requireNonNull(classLoader.getResource("/parkingsystem-cf164-firebase-adminsdk-5jjuk-2be72bfcce.json")).getFile());
And here is the code structure:
code structure
If there is another method to add file to jar I am open to hear it, it is just what I found on the Internet but it does not work for me. Any help is appreciated!
Edit: So apparently it works when the / is removed but then I need to convert it to FileInputStream and there I get FileNotFoundExcpetion. The rest of the code:
FileInputStream serviceAccount = null;
try {
serviceAccount = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
FirebaseOptions options = null;
try {
options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.build();
} catch (IOException e) {
e.printStackTrace();
}

Related

Java Properties Class

using java 8, tomcat 8
Hi, i am loading a file using properties, but i have a check before loading which returns the same properties object if its already been loaded (not null). which is a normal case scenario but i want to know if there is any way that if any change occur in target file, and some trigger should be called and refreshes all the properties objects. here is my code.
public static String loadConnectionFile(String keyname) {
String message = "";
getMessageFromConnectionFile();
if (propertiesForConnection.containsKey(keyname))
message = propertiesForConnection.getProperty(keyname);
return message;
}
public static synchronized void getMessageFromConnectionFile() {
if (propertiesForConnection == null) {
FileInputStream fileInput = null;
try {
File file = new File(Constants.GET_CONNECTION_FILE_PATH);
fileInput = new FileInputStream(file);
Reader reader = new InputStreamReader(fileInput, "UTF-8");
propertiesForConnection = new Properties();
propertiesForConnection.load(reader);
} catch (Exception e) {
Utilities.printErrorLog(Utilities.convertStackTraceToString(e), logger);
} finally {
try {
fileInput.close();
} catch (Exception e) {
Utilities.printErrorLog(Utilities.convertStackTraceToString(e), logger);
}
}
}
}
the loadConnectionFile method executes first and calls getMessageFromConnectionFile which has check implemented for "null", now if we remove that check it will definitely load updated file every time but it will slower the performance. i want an alternate way.
hope i explained my question.
thanks in advance.
Java has a file watcher service. It is an API. You can "listen" for changes in files and directories. So you can listen for changes to your properties file, or the directory in which your properties file is located. The Java Tutorials on Oracle's OTN Web site has a section on the watcher service.
Good Luck,
Avi.

Reading Properties file inside conf folder

I have a properties file which is located under conf folder. conf folder is under the project root directory. I am using the following code.
public class PropertiesTest {
public static void main(String[] args) {
InputStream inputStream = PropertiesTest.class
.getResourceAsStream("/conf/sampleprop.conf");
Properties prop = new Properties();
try {
prop.load(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(prop.getProperty("TEST"));
}
}
But I get nullpointer exception.
I have tried using
InputStream inputStream = PropertiesTest.class
.getResourceAsStream("./conf/sampleprop.conf");
and
InputStream inputStream = PropertiesTest.class
.getResourceAsStream("conf/sampleprop.conf");
But all result in nullpointer exception.
Can anyone please help.
Thanks in advance
Try to recover your working directory first:
String workingDir = System.getProperty("user.dir");
System.out.println("Current working dir: " + workingDir);
and then is simple:
Properties propertiesFile = new Properties();
propertiesFile.load(new FileInputStream(workingDir+ "/yourFilePath"));
String first= propertiesFile.getProperty("myprop.first");
Regards, fabio
The getResourceAsStream() method tries to locate and load the resource using the ClassLoader of the class it is called on. Ideally it can locate the files only the class folders .. Rather you could use FileInputStream with relative path.
EDIT
if the conf folder is under src, then you still be able to access with getResourceAsStream()
InputStream inputStream = Test.class
.getResourceAsStream("../conf/sampleprop.conf");
the path would be relative to the class from you invoke getRes.. method.
If not
try {
FileInputStream fis = new FileInputStream("conf/sampleprop.conf");
Properties prop = new Properties();
prop.load(fis);
System.out.println(prop.getProperty("TEST"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
NOTE: this will only work if it is Stand alone application/in eclipse. This will not work if its web based (as the root will be Tomcat/bin, for eg)
I would suggest to copy the configuration file at designated place, then you can acess at ease. At certain extent 'System.getProperty("user.dir")' can be used if you are always copying the file 'tomcat` root or application root. But if the files to be used by external party, ideal to copy in a configurable folder (C:\appconf)
Your code works like a charm! But you might have to add the project root dir to your classpath.
If you work with Maven, place your configuration in src/main/resources/conf/sampleprop.conf
When invoking java directly add the project root dir with the java -classpath parameter. Something like:
java -classpath /my/classes/dir:/my/project/root/dir my.Main

Getting error when I attach an image to Classpath Resource in scheduler jobclass

protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
System.out.println("Sending Birthday Wishes... ");
try
{
for(int i=0;i<maillist.length;i++)
{
Email email = new Email();
email.setFrom("spv_it#yahoo.com");
email.setSubject("Happy IndependenceDay");
email.setTo(maillist[i]);
email.setText("<font color=blue><h4>Dear Users,<br><br><br>Wish you a Happy Independence Day!<br><br><br>Regards,<br>Penna Cement Industries Limited</h4></font>");
byte[] data = null;
ClassPathResource img = new ClassPathResource("newLogo.gif");
InputStream inputStream = img.getInputStream();
data = new byte[inputStream.available()];
while((inputStream.read(data)!=-1));
Attachment attachment = new Attachment(data, "HappyBirthDay","image/gif", true);
email.addAttachment(attachment);
emailService.sendEmail(email);
}
}
catch (MessagingException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
This is the error I'm getting:
java.io.FileNotFoundException: class path resource [newLogo.gif] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:135)
at com.mail.schedular.BirthdayWisherJob.executeInternal(BirthdayWisherJob.java:55)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:66)
at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
The best practise is to read/write or to provide reference of any file is by mentioning the ABSOLUTE PATH of that file.
To your question, It shows the FileNotFoundException because, JVM failed to locate the file in your current directory which is by default your source path. So provide the absolute path in ClassPathResource or copy that image file to your current directory. It will solve your problem.
I think you need to put your file inside inside the src folder , if it's there then check whether it's under some directory which is inside the src directory.
Then give the correct location like given details below
src[dir]----->newLogo.gif
ClassPathResource img = new ClassPathResource("newLogo.gif");
or,
src[dir]----->images[dir]---->newLogo.gif
ClassPathResource img = new ClassPathResource("/images/newLogo.gif");
You got this error since the job is running in a separate quartz thread, I suggest that you locate your file newLogo.gif outside the jar and use the following to load it.
Thread.currentThread().getContextClassLoader().getResource("classpath:image/newLogo.gif");

Writing to a file inside of a jar

I am having a problem writing to a .xml file inside of my jar. When I use the following code inside of my Netbeans IDE, no error occurs and it writes to the file just fine.
public void saveSettings(){
Properties prop = new Properties();
FileOutputStream out;
try {
File file = new File(Duct.class.getResource("/Settings.xml").toURI());
out = new FileOutputStream(file);
prop.setProperty("LAST_FILE", getLastFile());
try {
prop.storeToXML(out,null);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
try {
out.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
}
However, when I execute the jar I get an error saying:
IllegalArguementException: uri is not hierachal
Does anyone have an idea of why it's working when i run it in Netbeans, but not working when i execute the jar. Also does anyone have a solution to the problem?
The default class loader expects the classpath to be static (so it can cache heavily), so this approach will not work.
You can put Settings.xml in the file system if you can get a suitable location to put it. This is most likely vendor and platform specific, but can be done.
Add the location of the Settings.xml to the classpath.
I was also struggling with this exception. But finally found out the solution.
When you use .toURI() it returns some thing like
D:/folderName/folderName/Settings.xml
and hence you get the exception "URI is not hierarchical"
To avoid this call the method getPath() on the URI returned, which returns something like
/D:/folderName/folderName/Settings.xml
which is now hierarchical.
In your case, the 5th line in your code should be
File file = new File(Duct.class.getResource("/Settings.xml").toURI().getPath());

I'm having trouble reading a properties file using FileInputStream

I'm working on a web application, and I have created a properties file in package com.xx.yy. I need to read this file from a class in author package com.aa.bb.
I have the folowing code:
try {
FileInputStream fileInputStream = new FileInputStream("com/xx/yy/myfile.properties");
internationalizationFile = new Properties();
internationalizationFile.load(fileInputStream);
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
but it doesn't work!!
Have you tried to load the resource through the class loader? like:
InputStream in = this.getClass().getClassLoader.getResourceAsStream("com/xx/yy/myfile.properties");
1) I would print out the absolute path to make sure the file / resource is in the correct location.
getResourceAsStream() vs FileInputStream
2) I would use getResourceAsStream, same reference.

Categories