Can't find resource outside the jar - java

I am trying to read properties which is located external to the jar file of my code.using ResourceBundle but its unable to read the property file locations.properties. The property file is located under resource folder and both jar and resource folder are under same directory.
myDir
--> myJar.jar
--> resource
-->locations.properties
I don't know whats wrong with my code below:
public static ResourceBundle getResourceBundle(String fileName) throws MalformedURLException{
if (resourceBundle == null) {
File file = new File("resource/"+fileName);
URL[] urls = { file.toURI().toURL() };
ClassLoader loader = new URLClassLoader(urls);
resourceBundle = ResourceBundle.getBundle(fileName, Locale.getDefault(), loader);
}
return resourceBundle;
}
And this is how am invoking ResourceBundle object:
ResourceBundle locationBundle = null;
try {
locationBundle = ReadPropertyUtil.getResourceBundle(propFileName);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Please guide whats wrong with this code and whats the correct way of reading an external properties file.

Get Jar file path.
Get Parent folder of that file.
Use that path in InputStreamPath with your properties file name.
Properties prop = new Properties();
try {
File jarPath=new File(YourClassNameInJar.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String propertiesPath=jarPath.getParentFile().getAbsolutePath();
System.out.println(" propertiesPath-"+propertiesPath);
prop.load(new FileInputStream(propertiesPath+"/resource/locations.properties"));
} catch (IOException e1) {
e1.printStackTrace();
}

Well, I figured out the error myself. I was appending the fileName to the directory location File file = new File("resource/"+fileName); which was wrong.
All I had to do was to first get the present working directory name using
System.getProperties("user.dir") //this gives me the path of my current directory
and passing only the directory name to file object.
File file = new File("resource/");
And then load the bundle using the specified file name.
resourceBundle = ResourceBundle.getBundle(fileName, Locale.getDefault(), loader);
ResourceBundle automatically looks into the directory and loads the file specified by the fileName

Related

Apache Configuration cannot load file Properties - returns null

I gave Apache Configuration2 a try.
I try to load a path from properties file:
String configFileName = getConfigFileName();
Configurations configs = new Configurations();
try {
File configFile = new File(configFileName);
String configFileStr = FileUtils.readFileToString(configFile, StandardCharsets.UTF_8); // content is loaded correctly
config = configs.properties(configFile);
config = configs.properties("src/main/resources/config.properties");
baseStoreDir = config.getString("baseStoreDir", baseStoreDir);
} catch (ConfigurationException cex) {
log.fatal(...);
} catch (IOException ex) {
log.fatal(...);
}
With this code I cannot get property value. Just as file or property is not found.
config.getString("baseStoreDir");
This returns null.
Why I cannot get the property?
The issue was in properties file. Directory path there was in format:
baseStoreDir = .\src\main\resources\
When I converted it to:
baseStoreDir = ./src/main/resources/
it worked.
Apache Configuration2 has very strange "logic" of reading resource files as Java files :P

Unable to load external files in java while running in terminal

I have created a executable jar package (called myjar.jar) which has a class for reading config file(called config_reader) .There is another class file outside myjar.jar which uses the config_reader. But the config file for config_reader is placed outside the myjar.jar ( in local filesystem) .Now when i try to execute the executable jar along with another file that uses it i get an error saying config file not found :
I tried to :
java -classpath config myclass.class
can Anyone help out on this ?
The code of config_reader is :
public class config_reader()
{
public static ArrayList<String> get_prop()
{
Properties prop = new Properties();
ArrayList<String> s= new ArrayList<String>();
try {
//load a properties file
prop.load(new FileInputStream("config"));
//get the property value and print it out
s.add(prop.getProperty("source_folder_dir"));
s.add(prop.getProperty("dest_folder_dir"));
s.add(prop.getProperty("file_type"));
s.add(prop.getProperty("username"));
s.add(prop.getProperty("userpwd"));
s.add(prop.getProperty("exclusion_list"));
} catch (IOException ex) {
ex.printStackTrace();
}
return s;
}
}
prop.load(new FileInputStream("config"));
Instead of just saying config use absolute path to the file. Infact it is better to do
File configFile = new File("absolute path to config file");
if(configFile.exists()){
//continue with your logic
}

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

How to get full file path present in eclipse project explorer?

I am working on eclipse plugin. In this i have a file name present in a project hierarchy. i need the full path of file abc.java present in project Test.
The file presented in path F:/Test/src/main/java/com/sung/Pre/abc.java
IWorkspaceRoot rootWorkspace = ResourcesPlugin.getWorkspace().getRoot();
IProject project = rootWorkspace.getProject("/Test");
file1 = project.getFile("/abc.java");
FileEditorInput fileEditorInput = new FileEditorInput(file1);
IWorkbench workbench = PlatformUI.getWorkbench();
IEditorDescriptor desc = workbench.getEditorRegistry().getDefaultEditor(file1.getName());
IWorkbenchPage page11 = workbench.getActiveWorkbenchWindow().getActivePage();
try {
page11.openEditor(fileEditorInput, desc.getId(),true);
} catch (PartInitException e1) {
e1.printStackTrace();
}
This is searching file in /Test folder. If the file presented in the root Test folder it's able to open this file but if it's inside some folder like F:/Test/src/main/java/com/sung/Pre/abc.java than it's can not find the file.
I also tried below code but facing the same issue
try {
//IDE.openEditor(page11, uri, "org.eclipse.ui.ide.IDE", true);
IDE.openEditor(page11, file1, true);
} catch (PartInitException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
so my question is if we have a file name presented in project hierarchy so how can we get the absolute or full path of that.
Please remember that i am doing this task in eclipse plugin project
You can specify a path on project.getFile:
project.getFile(new Path("src/main/java/com/sung/Pre/abc.java"));
or get the IFolder for the folder containing the file and use
folder.getFile(new Path("abc.java"));

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");

Categories