Load property file with command line arguments - Java - java

What is the best way to load a property file when path to the property file is not fixed and provided via command line arguments?
I am using the following code to load it but it is giving me null pointer exception when run using command line arguments:
Properties p = new Properties();
p.load(testClass.class.getResourceAsStream("path to the property file"));

If you get the (full) path via command line, you jsut need to provide a reader or input stream with that path. In the end, your code could look like this:
public static void main(String[] args) {
System.out.println("reading property file " + args[0]);
// create new initial properties
Properties properties = new Properties();
// open reader to read the properties file
try (FileReader in = new FileReader(args[0])){
// load the properties from that reader
properties.load(in);
} catch (IOException e) {
// handle the exception
e.printStackTrace();
}
// print out what you just read
Enumeration<?> propertyNames = properties.propertyNames();
while(propertyNames.hasMoreElements()) {
String name = propertyNames.nextElement().toString();
System.out.println(name + ": " + properties.getProperty(name));
}
}

Related

Swing Laf Change Issues While Restarting App

I have the following restart method, which is working:
public static void restart(String[] args) {
ArrayList<String> commands = new ArrayList<String>();
List<String> jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments();
// Java
commands.add(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
// Jvm arguments
for (String jvmArg : jvmArgs) {
commands.add(jvmArg);
}
// Classpath
commands.add("-cp");
commands.add(ManagementFactory.getRuntimeMXBean().getClassPath());
// Class to be executed
commands.add(BaseUI.class.getName());
// Command line arguments
File workingDir = null; // Null working dir means that the child uses the same working directory
String[] env = null; // Null env means that the child uses the same environment
String[] commandArray = new String[commands.size()];
commandArray = commands.toArray(commandArray);
try {
Runtime.getRuntime().exec(commandArray, env, workingDir);
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
I want to put the Look And Feel configuration on the main method of my main application but, while restarting, the execution does not enter in that part of the code. So, obviously, the Look and Feel is not changed at all.
Is there any workaround to solve this?

Java Program That Deletes Itself - Not Working

I'm trying to create a program that creates a copy of itself and deletes the original project folder.
(FYI: Project has its own JRE inside it)
(FYI: This program runs on Windows)
So:
To be able to do that, other than my primary main method, there is a second main method in the class called SelfUpdater.
Inside my main thread I copy the project to a second folder.
And then run the SelfUpdater's main method inside this second project folder:
This should mean that I'm running a whole new instance, totally unrelated to the first java.exe (which already gets closed with system.exit(0) as soon as new instance starts).
But when I try to delete the first folder, I get the error "Error deleting old client.java.io.IOException: Unable to delete file". Actually It deletes some of the files, but I can't delete Application.exe and its lib folder.
Its folder is not open in windows. It is not being used by anything else. I can't delete the file manually either (Windows says it is in use). And as soon as the second java.exe is terminated, I can delete it.
I can't give a total working example, But my in my main thread I call this following method:
public static void selfUpdate() {
try {
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String rootPath = System.getProperty("user.dir");
String path = null;
File parentFolder = null;
File originalClientFolder = new File(rootPath);
parentFolder = originalClientFolder.getParentFile();
File secondClientFolder = new File(parentFolder.getAbsolutePath() + separator + "runLAST");
FileUtils.copyDirectory(originalClientFolder, secondClientFolder);
path = secondClientFolder.getAbsolutePath() + separator + "jre8" + separator + "bin" + separator + "java";
ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp", classpath, SelfUpdater.class.getName(), downloadURL, rootPath);
processBuilder.directory(secondClientFolder);
processBuilder.start();
System.exit(0);
} catch (Exception ex) {
}
}
And my SelfUpdater class' main is:
public static void main(String[] args) {
try {
String originalClientFolderPath = args[1];
//
File oldClientFolder = new File(originalClientFolderPath);
System.out.println("Deleting old client recursively. Folder: " + oldClientFolder.getAbsolutePath());
try {
FileUtils.deleteDirectory(oldClientFolder);
} catch (Exception ex) {
}
}
}
Appearently, I forgot to change the classpath.
I'm thinking about leaving the question, since people may need such code part.
But at the end, method that's being called is changed to this:
public static void selfUpdate() {
try {
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String rootPath = System.getProperty("user.dir");
String path = null;
File parentFolder = null;
File originalClientFolder = new File(rootPath);
parentFolder = originalClientFolder.getParentFile();
File secondClientFolder = new File(parentFolder.getAbsolutePath() + separator + "runLAST");
FileUtils.copyDirectory(originalClientFolder, secondClientFolder);
// ADDED: --------------------------------------------------------
String origialClientFolderName = originalClientFolder.getName();
classpath = classpath.replace(origialClientFolderName, "runLAST");
// ---------------------------------------------------------------
path = secondClientFolder.getAbsolutePath() + separator + "jre8" + separator + "bin" + separator + "java";
ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp", classpath, SelfUpdater.class.getName(), downloadURL, rootPath);
processBuilder.directory(secondClientFolder);
processBuilder.start();
System.exit(0);
} catch (Exception ex) {
}
}

Parsing error after '#' line in ini file

I have a locally stored ini file which I am trying to parse as follows:
Ini ini = new Ini(new File("path/to/file"));
System.out.println(ini.get("header", "key"));
But I keep getting a parse error exception message pointing to the line after the comment line of the ini file (#). This is what my ini file looks like:
File.ini
#Tue Oct 11 18:45:03 CST 2016
PVIDNO=PALMUS-00001
PVIDNo=SSI-1
Authentication=VALID
ModelNo=KD03816-B001
PALMUS-ID=73364
PV-ID=PALMUS-01
You can do the same with Properties:
Properties p = new Properties();
p.load(new FileInputStream("user.props"));
System.out.println("user = " + p.getProperty("DBuser"));
System.out.println("password = " + p.getProperty("DBpassword"));
System.out.println("location = " + p.getProperty("DBlocation"));
where the .ini file is:
# this a comment
! this a comment too
DBuser=anonymous
DBpassword=&8djsx
DBlocation=bigone
You are using some class Ini that comes from who-knows-where; and that Ini-File parser simply doesn't like .ini files that contain "# comment" entries.
So, your options are basically:
I forgot about that first, but maybe the "best" option: don't use "ini" files; but change to "property" files; which are a much more "natural" choice for Java applications. "Built-in" support for them; and hey, "# comments" work out of the box.
If Ini is "your own code"; then you make your own code accept such comments
If Ini is coming from some library, then you check if that library allows to influence the parsing process to allow for such comments.
If the library doesn't allow for such special handling, you have another two options:
Look out for some other 3rd party library to parse your files
"Talk" to the people providing the library you are currently using and convince them to somehow make their library work for you.
Have you tried using Properties?
Creating Config:
Properties prop = new Properties();
OutputStream output = null;
try {
SaveSucessful = true;
output = new FileOutputStream("config.jar");
// set the properties value
prop.setProperty("PVIDNO", "PALMUS-00001");
// save properties to project root folder
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Reading Config:
Properties prop = new Properties();
InputStream input = null;
try {
LoadSucessful = true;
input = new FileInputStream("config.jar");
// load a properties file
prop.load(input);
// get the property value and print it out
PlayerName = prop.getProperty("PVIDNO");
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This should work perfectly.

Java Properties - can't find existing properties file

I'm using the following references, since this is the first time I've used Java Properties.
http://docs.oracle.com/javase/tutorial/essential/environment/properties.html
http://www.mkyong.com/java/java-properties-file-examples/
I'm attempting to run the following at the beginning of my program start, so the user only has to select the database file path once. After selecting it once, every subsequent program run should automatically use the config.properties file and get the database path.
Unfortunately, input == null is continually firing on every program run, even after selecting the correct database path in the previous program run and confirming the properties file contains the database path information.
Am I doing something wrong below?
Properties prop = new Properties();
InputStream input = null;
String filename = "config.properties";
input = this.getClass().getClassLoader().getResourceAsStream(filename);
if (input == null)
{
fileChooser.setDialogTitle("Choose the database file");
fileChooser.setAcceptAllFileFilterUsed(false);
FileFilter filter = new FileNameExtensionFilter("S3DB Files", "S3DB");
fileChooser.addChoosableFileFilter(filter);
int ret = fileChooser.showDialog(null, "Select File");
File file = null;
if (ret == JFileChooser.APPROVE_OPTION) {
file = fileChooser.getSelectedFile();
dbc = new DBConnect(file.getAbsolutePath());
}
OutputStream output = null;
try
{
output = new FileOutputStream("config.properties");
// set the properties value
prop.setProperty("database", file.getAbsolutePath());
// save properties to project root folder
prop.store(output, null);
}
catch (IOException io)
{
io.printStackTrace();
}
finally
{
if (output != null)
{
try
{
output.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
else
{
try
{
prop.load(input);
dbc = new DBConnect(prop.getProperty("database"));
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, e.toString(), "Properties Read/Write Exception Occured (PRGRYADDView())", JOptionPane.ERROR_MESSAGE);
}
}
Check your the properties file path.
Create a 'config.properties' file, and put it in your project classpath.
Replace this line:
input = this.getClass().getClassLoader().getResourceAsStream(filename);
with this:
try
{
input = new FileInputStream(filename);
}
catch(Exception e){}
I was attempting to load from the classpath rather than from the properties file itself relative to the executable JAR. The above solved my problem.
Be sure to add in your own exception handling as well.

FileNotFoundException when using java properties file

am asking this question after doing a lot of research and also implementing it in my code after the research but I ended up with FileNotFoundException.What exactly am doing here is I want to avoid hardcoding in my java code so am creating a properties file with name as Constants.properties and am calling it in my java code. but it says that it is not finding the file. My properties file is in the src folder of the project. Below is the code snippet. Any suggestions?
Properties file:
executable.run = C:\\server\\lrd.exe
incoming.file = C:\\file\\test.ic
executable.params1 = -z
executable.params2 = -a[+]
log.file = C:\\TESTFile\\test.txt
Java Code: This is the class file which has the properties file details.
public class PropInfo {
static private PropInfo _instance = null;
public String executable = null;
public String filein = null;
public String params1 = null;
public String params2 = null;
public String log = null;
protected PropInfo(){
try{
InputStream file = new FileInputStream(new File("Constants.properties"));
Properties props = new Properties();
props.load(file);
executable = props.getProperty("executable.run");
filein = props.getProperty("incomin.file");
params1 = props.getProperty("executable.params1");
params2 = props.getProperty("executable.params2");
log = props.getProperty("log.file");
}
catch(Exception e){
System.out.println("error" + e);
}
}
static public PropInfo instance(){
if(_instance == null){
_instance = new PropInfo();
}
return _instance;
}
}
Main Class:
try{
PropInfo propinfo = PropInfo.instance();
String connString = propinfo.executable + " " + propinfo.params1 + " " +
propinfo.filein + " " + propinfo.params2 + " " + " " + propinfo.log ;
Runtime rt = Runtime.getRuntime();
// Process pr = rt.exec
// (PropInfo.executable+" "+PropInfo.params1+" "+PropInfo.filein+" "
//+PropInfo.params2+" "+PropInfo.log);
Process pr = rt.exec(connString);
BufferedReader input = new BufferedReader(new InputStreamReader (pr.getInputStream()));
String line=null;
StringBuffer start= new StringBuffer();
while((line=input.readLine()) != null) {
start.append("Started" + line + "\n");
System.out.println(line);
}
// System.out.println("browse");
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
}
Gives this Exception:
errorjava.io.FileNotFoundException: Constants.properties (The system cannot find the
file specified)
java.io.IOException: Cannot run program "null": CreateProcess error=2, The system
cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1042)
at java.lang.Runtime.exec(Runtime.java:615)
at java.lang.Runtime.exec(Runtime.java:448)
at java.lang.Runtime.exec(Runtime.java:345)
at com.emc.clp.license.StartTest.main(StartTest.java:44)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the
file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(ProcessImpl.java:288)
at java.lang.ProcessImpl.start(ProcessImpl.java:133)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1023)
... 4 more
Yes, don't put your properties file into the src folder. Put it where you start the jvm from (or provide an absolute path). Also I really suggest getting rid of forward slashes in path names.
UPDATE: Add this to find out where to put your file:
System.out.println(new File(".").getAbsolutePath());
The way you load Constants.properties it should be right under your src package package at the level where your packaging starts.
for example,
if you hava src/java/propinfopackage/PropInfo
put it inside java folder and call it as follows
InputStream propertiesInputStream = null;
Properties properties = new Properties();
propertiesInputStream = PropInfo.class.getClassLoader().getResourceAsStream("/Constants.properties");
properties.load(propertiesInputStream);
String value = properties.getProperty("executable.run");
.......
I had the same problem and it was solved like this:
Properties prop = new Properties();
try {
prop.load(getClass().getResourceAsStream("/com/my/package/Constants.properties"));//here your src folder
System.out.println(prop.getProperty("executable.run"));
} catch(IOException e) {}
Make sure your properties file is in root path of the project. Right click on project and paste the properties file. Your error will go.
Also refer #Axel Answer above. It will resolve your issue.

Categories