I have this piece of code.
// On a thread
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
Path directory = Paths.get("properties");
WatchKey watchKey = directory.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
for (WatchEvent<?> event : watchKey.pollEvents()) {
Path changed = (Path) event.context();
if (changed.toString().equals("radar.properties")) {
System.out.println("read call:");
readProperties();
}
}
if (!watchKey.reset()) {
break;
}
}
} catch (IOException e) {
FCSLogger.LOGGER.log(Level.SEVERE, "Exception while setting up WatchService", e);
}
// Method called by the above code
private void readProperties() {
try {
InputStream input = new FileInputStream(Paths.get("properties", "radar.properties").toString());
Properties prop = new Properties();
prop.load(input);
updateRate = Integer.parseInt(prop.getProperty("updateRate"));
System.out.println(updateRate);
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
It returns the right result on the first call and then blocks the whole thread. I've isolated the bug to be in this method since everything else works flawlessly when there is no calling this method. I'm wondering what am I doing wrong here.
Snapshot of console output:
// First change of file:
read call:
10
read call:
10
// Second change of file:
read call:
// I keep changing but nothing happens:
It can be that readProperties throws NumberFormatException, and that causes your watcher thread to exit.
You could wrap calls to readProperties and catch exceptions; so that at least the watcher will keep watching in case of exceptions.
And you should use take, so that the watcher thread blocks. Your current solution causes 100% cpu usage.
See below the modified code. I added a writer thread to update the file, and (unsurprisingly?) readProperties can fail since we are accessing the file while it is being written. A possible output is:
....
property=5000
property=null
java.lang.NumberFormatException: null
at java.base/java.lang.Integer.parseInt(Integer.java:614)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at cl.ClientPoll.readProperties(ClientPoll.java:26)
at cl.ClientPoll.run(ClientPoll.java:46)
property=6000
property=7000
....
So when watching, you can either: skip on error and continue; or use other APIs so that the file being written is locked while writing.
Sample code
package cl;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Properties;
public class ClientPoll extends Thread {
private void readProperties() {
try {
Path path = Paths.get("radar.properties");
InputStream input =new FileInputStream(path.toString());
Properties prop = new Properties();
prop.load(input);
String property = prop.getProperty("updateRate");
System.out.println("property="+property);
int updateRate = Integer.parseInt(property);
// System.out.println(updateRate);
input.close();
} catch (IOException e) {
e.printStackTrace(System.out);
}
}
#Override
public void run() {
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
Path directory = Paths.get(".");
WatchKey watchKey = directory.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
WatchKey wk = watcher.take();
for (WatchEvent<?> event : wk.pollEvents()) {
Path changed = (Path) event.context();
if (changed.toString().equals("radar.properties")) {
try {
readProperties();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
if (!watchKey.reset()) {
break;
}
}
} catch (IOException e) {
e.printStackTrace(System.out);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ClientPoll().start();
new Writer().start();
}
}
class Writer extends Thread {
#Override
public void run() {
try {
for (int i=0;i<10;i++) {
File f = new File("radar.properties");
FileWriter fw = new FileWriter(f);
fw.write("updateRate="+i*1000);
fw.close();
sleep(1000L);
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
System.out.println("exit");
System.exit(0);
}
}
Related
Tried to put flush and close everywhere. Still, does not write to file. Changed file location, path of the file, still does not write to the file; however it creates it.
public void filePatient(HashMap<Integer,Patient> collection, String filename) {
// crating a file
File file = new File (filename+".txt");
try (PrintWriter out = new PrintWriter(new FileWriter(file),true)) {
for(Patient i: collection.values()) {
out.write(i.getName());
//out.write(i.getHealthNumber());
}
out.flush();
out.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Your code works as-is.
You can also remove the close, as you use try-with-resources.
Here's a full working example:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("a", "my name");
map.put("b", "your name");
filePatient(map, "c:\\temp\\test");
}
public static void filePatient(Map<String, String> collection, String filename) {
// crating a file
File file = new File(filename + ".txt");
try (PrintWriter out = new PrintWriter(new FileWriter(file), true)) {
for (String name : collection.values()) {
out.write(name);
}
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have a problem I can't resolve.
I need to read properties file, but can't set right path.
Documentation of java.io.File is saying that I have to set in from the src/...
It doesnt work, I did a path from current file and have the same problem.
EXCEPTION IS : FileNotFound
PropertyReader class:
public final class PropertyReader {
private Properties prop = new Properties();
private InputStream input = null;
public Properties getProperties(File file) {
try {
input = new FileInputStream(file);
// load a properties file
prop.load(input);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != input) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return prop;
}
}
And ApplicationController.class which uses PropertyReader:
#RequestMapping(value = "/result", method = RequestMethod.GET)
public String resultPage(ModelMap model) {
//Getting property with key "path"
model.addAttribute("path", new PropertyReader().getProperties(file).getProperty("path"));
return "result";
If I'm setting path from C://.. it works fine.
Thank you much and have a nice day!
Try to use Following example to read property file.
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class App {
public static void main(String[] args) {
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("config.properties");
// load a properties file
prop.load(input);
// get the property value and print it out
System.out.println(prop.getProperty("mysqldb"));
System.out.println(prop.getProperty("dbuser"));
System.out.println(prop.getProperty("dbpassword"));
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Its also depends on the framework that you are using like SpringMVC, JSF and Struts. All these framework have their own shortcut ways to access property files.
I resolved it by using annotations #PropertySource and #Value()
For example:
//There could be any folder
#PropertySource("classpath:file.properties")
public class AnyClass {
//There could be any property
#Value("${some.property}")
private String someValue;
}
How to release process resource??
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.StringTokenizer;
public class RuntimeSample{
public RuntimeSample() {
}
private void execCmd1() throws IOException {
InputStream in = null;
Process process = null;
String[] cmd = { "java", "-version" };
try {
process = Runtime.getRuntime().exec(cmd);
in = process.getInputStream();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
}
}
private void execCmd2() throws IOException {
Process process = null;
String[] cmd = { "java", "-version" };
try {
process = Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
why it is throwing process.getError stream is not closed,I tried to close process resource by using following
if (process != null) {
process.getInputStream().close();
process.getOutputStream().close();
process.getErrorStream().close();
even it is showing process.getError stream is not closed.may i know the reason y it is showing that stream is not closed and how to close the process resource.Thanks in advance
I know this answer is somewhat late, but maybe someone else runs into the same issue.
In my project the Server runs some utility (I call it winps.exe here) regularly and it was easy to see (using RAMMAP resp. Handles) that the Java process kept a handle to each of the (terminated) child processes. Restarting the Server removed all entries from the process table.
After some experimenting, I found that explicitly calling the Garbage Collector resolved the issue.
Below you find my Java test program which I used to investigate the matter.
Note that this test program has been copied from the Server source code and isn't 100% as cleanly written as possible.
import java.util.*;
import java.io.*;
import java.util.regex.*;
import java.text.*;
import java.lang.reflect.*;
import java.util.concurrent.TimeUnit;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
public class StartPS
{
static Long STARTTIME_JITTER = 5000L;
synchronized public static HashMap<String,Long> getStartTimes()
{
HashMap<String,Long> result = new HashMap<String, Long>();;
final File tmp_file = new File("/tmp/starttimes.out");
String tmpfilename = null;
try {
tmpfilename = tmp_file.getCanonicalPath();
} catch (Exception e) {}
try {
ProcessBuilder pb = new ProcessBuilder(".\\winps.exe");
pb.redirectOutput(new File(tmpfilename));
pb.redirectErrorStream(true);
Process p = pb.start();
p.getOutputStream().close();
p.getInputStream().close();
p.getErrorStream().close();
try {
p.waitFor();
} catch (InterruptedException ie) {
// maybe some cleanup here
}
try {
while (p.isAlive()) { // <- most likely unnecessary ;-)
Thread.sleep(100);
p.destroy();
System.gc();
}
p = null; // should help the garbage collector (eliminates a reference to the object p points to)
System.gc(); // <- most likely the key to success !
} catch (Exception e) {
System.out.println("Warning: " + e.toString());
}
} catch (Exception e) {
throw new RuntimeException("(02310251044) Process start times : " + e.toString());
}
return result;
}
public static void main(String[] argv)
{
String sMax;
int iMax = 500;
if (argv.length > 0) {
sMax = argv[0];
try {
iMax = Integer.parseInt(sMax);
} catch (Exception e) {
System.out.println("Oops : " + e.toString());
System.exit(1);
}
}
for (int i = 0; i < iMax; ++i) {
System.out.print("\r" + i);
getStartTimes();
try {
Thread.sleep(1000);
} catch (Exception e) {
// do nothing
}
}
}
}
I am new in OSGI and i have current aim. I have 10 threads, it's writing their names in a file. After recording thread sleep random 0..1 sec. This all must be a bundle. I create it, but i'm not sure Is this correct. Can any comments?
package helloworld;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import writer.StartThreads;
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
System.out.println("Start Thred!!");
new StartThreads().Execute();
}
public void stop(BundleContext context) throws Exception {
System.out.println("Goodbye World!!");
}
}
1
package writer;
import writer.WriterLogs;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class StartThreads {
public static void Execute() {
BufferedWriter writer = null;
File textFile = new File("threadLog.txt");
// if file doesnt exists, then create it
if (!textFile.exists()) {
try {
textFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
writer = new BufferedWriter(new FileWriter(textFile, true));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
WriterLogs wrt = new WriterLogs(writer);
Thread worker = new Thread(wrt);
worker.setName("Nisha-" + i);
worker.start();
try {
worker.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2
package writer;
import java.io.BufferedWriter;
import java.io.IOException;
public class WriterLogs implements Runnable {
private BufferedWriter writer;
public WriterLogs(BufferedWriter wr) {
this.writer = wr;
}
#Override
public void run() {
try
{
try {
synchronized(this.writer) {
this.writer.write(Thread.currentThread().getName() + "\n");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// set random 0...1 s.
Thread.sleep((long)(Math.random() * 1000));
System.out.println(Thread.currentThread().getName());
}
catch (InterruptedException interruptedException)
{
/*Interrupted exception will be thrown when a sleeping or waiting
* thread is interrupted.
*/
System.out.println( Thread.currentThread().getName() +interruptedException);
}
}
}
This is not correct. Like Boris the Spider states, when your bundle stops, you should free any resources and stop any processing the bundle was doing. So from the stop method you should somehow signal your threads to stop as soon as they can.
In practice you might get away with letting the code run, but this is definitely not how you should write your code in OSGi (which is what you're asking).
I was testing out writing to files with this code:
package files;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
public class FileTest1
{
public static void main(String[] args)
{
try
{
try
{
File f = new File("filetest1.txt");
FileWriter fWrite = new FileWriter(f);
BufferedWriter fileWrite = new BufferedWriter(fWrite);
fileWrite.write("This is a test!");
}
catch(FileNotFoundException e)
{
System.out.print("A FileNotFoundException occurred!");
e.printStackTrace();
}
}
catch(IOException e)
{
System.out.println("An IOException occurred!:");
e.printStackTrace();
}
}
}
Nothing happens when it is executed.
"This is a test!" is not written, nor the StackTrace or the "A/An [exception] occurred!"...
I don't know what's causing the problem. I have fileTest1.txt in the package right under the file...
A BufferedWriter does just that, it buffers the output before it is written to the destination. This can make the BufferedWriter faster to use as it doesn't have to write to a slow destination, like a disk or socket, straight away.
The contents will be written when the internal buffer is to full, you flush the Writer or close the writer
Remember, if you open it, you should close it...
For example...
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class TestFileWriter {
public static void main(String[] args) {
try {
BufferedWriter fileWrite = null;
try {
File f = new File("filetest1.txt");
System.out.println("Writing to " + f.getCanonicalPath());
FileWriter fWrite = new FileWriter(f);
fileWrite = new BufferedWriter(fWrite);
fileWrite.write("This is a test!");
fileWrite.flush();
} catch (FileNotFoundException e) {
System.out.print("A FileNotFoundException occurred!");
e.printStackTrace();
} finally {
try {
// Note, BufferedWriter#close will also close
// the parent Writer...
fileWrite.close();
} catch (Exception exp) {
}
}
} catch (IOException e) {
System.out.println("An IOException occurred!:");
e.printStackTrace();
}
try {
BufferedReader br = null;
try {
File f = new File("filetest1.txt");
System.out.println("Reading from " + f.getCanonicalPath());
FileReader fReader = new FileReader(f);
br = new BufferedReader(fReader);
String text = null;
while ((text = br.readLine()) != null) {
System.out.println(text);
}
} catch (FileNotFoundException e) {
System.out.print("A FileNotFoundException occurred!");
e.printStackTrace();
} finally {
try {
// Note, BufferedWriter#close will also close
// the parent Writer...
br.close();
} catch (Exception exp) {
}
}
} catch (IOException e) {
System.out.println("An IOException occurred!:");
e.printStackTrace();
}
}
}
If you are using Java 7, you may like to take a look at try-with-resources
After
fileWrite.write("This is a test!");
you have to flush() the writer. To avoid leaking of resources you should also close() the writer (which automatically flushes it).
So you need to add:
fileWrite.close();
Use BufferedWriter.flush() and BufferedWriter.close(). Additional info here http://docs.oracle.com/javase/7/docs/api/java/io/BufferedWriter.html
You must call close() or at least flush() on the writer in order for the buffer to be really written to the file.