so i have problem where i am trying to open a file through my own written virtual machine object in java but the problem is that the virtual machine is not running and causing an error.
Error: Could not find or load main class C:\Users\dell\Trace\Main.java
we also tried modifying the CLASSPATH & PATH with no success
below is the code of the main
import com.sun.jdi.Bootstrap;
import com.sun.jdi.connect.*;
import java.util.Map;
import java.util.List;
import java.util.Iterator;
import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Trace {
// Running remote VM
private final VirtualMachine vm;
// Thread transferring remote error stream to our error stream
private Thread errThread = null;
// Thread transferring remote output stream to our output stream
private Thread outThread = null;
// Mode for tracing the Trace program (default= 0 off)
private int debugTraceMode = 0;
// Do we want to watch assignments to fields
private boolean watchFields = false;
// Class patterns for which we don't want events
private String[] excludes = {"java.*", "javax.*", "sun.*",
"com.sun.*"};
/**
* main
*/
public static void main(String[] args) {
new Trace(args);
}
/**
* Parse the command line arguments.
* Launch target VM.
* Generate the trace.
*/
Trace(String[] args) {
PrintWriter writer = new PrintWriter(System.out);
int inx;
for (inx = 0; inx < args.length; ++inx) {
String arg = args[inx];
if (arg.charAt(0) != '-') {
break;
}
if (arg.equals("-output")) {
try {
writer = new PrintWriter(new FileWriter(args[++inx]));
} catch (IOException exc) {
System.err.println("Cannot open output file: " + args[inx]
+ " - " + exc);
System.exit(1);
}
} else if (arg.equals("-all")) {
excludes = new String[0];
} else if (arg.equals("-fields")) {
watchFields = true;
} else if (arg.equals("-dbgtrace")) {
debugTraceMode = Integer.parseInt(args[++inx]);
} else if (arg.equals("-help")) {
usage();
System.exit(0);
} else {
System.err.println("No option: " + arg);
usage();
System.exit(1);
}
}
if (inx >= args.length) {
System.err.println("<class> missing");
usage();
System.exit(1);
}
StringBuffer sb = new StringBuffer();
sb.append(args[inx]);
for (++inx; inx < args.length; ++inx) {
sb.append(' ');
sb.append(args[inx]);
}
vm = launchTarget(sb.toString());
generateTrace(writer);
}
/**
* Generate the trace.
* Enable events, start thread to display events,
* start threads to forward remote error and output streams,
* resume the remote VM, wait for the final event, and shutdown.
*/
void generateTrace(PrintWriter writer) {
vm.setDebugTraceMode(debugTraceMode);
EventThread eventThread = new EventThread(vm, excludes, writer);
eventThread.setEventRequests(watchFields);
eventThread.start();
redirectOutput();
vm.resume();
// Shutdown begins when event thread terminates
try {
eventThread.join();
errThread.join(); // Make sure output is forwarded
outThread.join(); // before we exit
} catch (InterruptedException exc) {
// we don't interrupt
}
writer.close();
}
/**
* Launch target VM.
* Forward target's output and error.
*/
VirtualMachine launchTarget(String mainArgs) {
LaunchingConnector connector = findLaunchingConnector();
Map arguments = connectorArguments(connector, mainArgs);
try {
return connector.launch(arguments);
} catch (IOException exc) {
throw new Error("Unable to launch target VM: " + exc);
} catch (IllegalConnectorArgumentsException exc) {
throw new Error("Internal error: " + exc);
} catch (VMStartException exc) {
throw new Error("Target VM failed to initialize: " +
exc.getMessage());
}
}
void redirectOutput() {
Process process = vm.process();
// Copy target's output and error to our output and error.
errThread = new StreamRedirectThread("error reader",
process.getErrorStream(),
System.err);
outThread = new StreamRedirectThread("output reader",
process.getInputStream(),
System.out);
errThread.start();
outThread.start();
}
/**
* Find a com.sun.jdi.CommandLineLaunch connector
*/
LaunchingConnector findLaunchingConnector() {
List connectors = Bootstrap.virtualMachineManager().allConnectors();
Iterator iter = connectors.iterator();
while (iter.hasNext()) {
Connector connector = (Connector)iter.next();
if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {
return (LaunchingConnector)connector;
}
}
throw new Error("No launching connector");
}
/**
* Return the launching connector's arguments.
*/
Map connectorArguments(LaunchingConnector connector, String mainArgs) {
Map arguments = connector.defaultArguments();
Connector.Argument mainArg =
(Connector.Argument)arguments.get("main");
if (mainArg == null) {
throw new Error("Bad launching connector");
}
mainArg.setValue(mainArgs);
if (watchFields) {
// We need a VM that supports watchpoints
Connector.Argument optionArg =
(Connector.Argument)arguments.get("options");
if (optionArg == null) {
throw new Error("Bad launching connector");
}
optionArg.setValue("-classic");
}
return arguments;
}
/**
* Print command line usage help
*/
void usage() {
System.err.println("Usage: java Trace <options> <class> <args>");
System.err.println("<options> are:");
System.err.println(
" -output <filename> Output trace to <filename>");
System.err.println(
" -all Include system classes in output");
System.err.println(
" -help Print this help message");
System.err.println("<class> is the program to trace");
System.err.println("<args> are the arguments to <class>");
}
}
Related
Currently I am trying to extract some execution data via the JDI.
Therefore I first start a java vm manually with the command
java -agentlib:jdwp=transport=dt_socket,server=y,address=8000 DebugDummy
My DebugDummy.java:
public class DebugDummy {
public class MyInnerClass {
private int a;
public MyInnerClass(int a) {
this.a = a;
this.doSomething();
}
public void doSomething() {
System.out.println(this.a);
}
}
public DebugDummy() {
MyInnerClass myInnerClass = new MyInnerClass(5);
myInnerClass.doSomething();
}
public static void main(String[] args) {
DebugDummy dd = new DebugDummy();
}
}
And then connect with the JDI, waiting for the main-method entry and step line per line through the code execution.
public class VMStart {
public static void main(String[] args) {
//Check for argument count
if(args.length != 3){
System.err.println("Not enough parameter!");
System.exit(0);
}
String cwd = "", mainClass = "", vmPort = "";
cwd = args[0];
mainClass = args[1];
vmPort = args[2];
System.out.println("CWD: " + cwd);
System.out.println("MainClass: " + mainClass);
System.out.println("VM Port: " + vmPort);
//Init vm arguments and settings
VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
AttachingConnector ac = vmm.attachingConnectors().get(0);
//Setting port
Map<String, Connector.Argument> env = ac.defaultArguments();
Connector.Argument port = env.get("port");
port.setValue(vmPort);
//Setting hostname
Connector.Argument hostname = env.get("hostname");
hostname.setValue("localhost");
//Attach vm to remote vm
VirtualMachine vm = null;
try {
vm = ac.attach(env);
} catch (IOException | IllegalConnectorArgumentsException e) {
//Doesn't work, stop here...
System.err.println("Can't connect to vm!");
e.printStackTrace();
System.exit(0);
}
//Create EventQueue and EventRequestManager for further event handling
EventQueue eventQueue = vm.eventQueue();
EventRequestManager mgr = vm.eventRequestManager();
//Set the vm to sleep for further operations
vm.suspend();
//Searching for our main thread reference
ThreadReference mainThread = null;
List<ThreadReference> threads = vm.allThreads();
for (ThreadReference thread : threads) {
if ("main".equals(thread.name())) {
mainThread = thread;
}
}
//Create and register MethodEntryRequest, so we can pause execution at first line of main later on
MethodEntryRequest methodEntryRequest = mgr.createMethodEntryRequest();
methodEntryRequest.addClassFilter(mainClass);
methodEntryRequest.addThreadFilter(mainThread);
methodEntryRequest.enable();
//Resume the execution of the remote vm
vm.resume();
//Resume the execution of the main thread in remote vm
mainThread.resume();
//Waiting for our needed MethodEntryEvent so execution started at first line of main method
Event event = null;
while (true) {
EventSet eventSet = null;
try {
eventSet = eventQueue.remove();
} catch (InterruptedException e) {
System.err.println("Something went wrong while waiting for MethodEntryEvent");
e.printStackTrace();
System.exit(0);
}
event = eventSet.eventIterator().next();
if (event instanceof MethodEntryEvent) {
break;
}
}
//Indicates whether there is still code execution in our remote vm
boolean codeIsExecuting = true;
//Step loop until there is no code execution
while(codeIsExecuting){
//Filter for steeping not into java api methods
final String[] noBreakpointRequests = {"java.*", "javax.*", "sun.*", "com.sun.*"};
//Creating our StepRequest for each line of code
StepRequest stepRequest = mgr.createStepRequest(mainThread, StepRequest.STEP_LINE, StepRequest.STEP_INTO);
for(String classInFilter : noBreakpointRequests){ //Apply filter
stepRequest.addClassExclusionFilter(classInFilter);
}
stepRequest.addCountFilter(1);
try{
stepRequest.enable();
}catch(IllegalThreadStateException e){
//program reached end of code, so there is no code execution anymore
codeIsExecuting = false;
System.out.println("Code execution ended...");
break;
}
//Extract data from current vm execution state
//TODO
System.out.println("TODO - extract data from current vm execution state");
//Test
StackFrame stackFrame = null;
try {
stackFrame = mainThread.frame(0);
System.out.println(stackFrame.location());
} catch (IncompatibleThreadStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Resume vm for code execution
vm.resume();
try {
Thread.sleep(10L);
} catch (InterruptedException e) {
e.printStackTrace();
}
//StepRequest is done, remove it from event queue to prevent lock
mgr.deleteEventRequest(stepRequest);
}
//Debugging has ended, we free our remote vm
try{
vm.dispose();
}catch(VMDisconnectedException e){
}
//Print results
//TODO
System.out.println("TODO - print results...");
}
}
Unfortunally, if I delete the Thread.sleep(), I'm getting a IncompatibleThreadStateException at line
stackFrame = mainThread.frame(0);
Exception:
com.sun.jdi.IncompatibleThreadStateException at com.sun.tools.jdi.ThreadReferenceImpl.privateFrames(ThreadReferenceImpl.java:436)
at com.sun.tools.jdi.ThreadReferenceImpl.frame(ThreadReferenceImpl.java:355)
at VMStart.main(VMStart.java:143)
What's wrong? Do I have to wait for a certain event before stepping one line further?
Finally, I found a solution to myself...
This code has to be inserted AFTER the vm.resume() instruction:
boolean go = false;
while (!go) {
EventSet eventSet = null;
try {
eventSet = eventQueue.remove();
} catch (InterruptedException e) {
System.err.println("Something went wrong while waiting for StepEvent");
e.printStackTrace();
System.exit(0);
}
for (Event e : eventSet) {
if (e instanceof StepEvent) {
System.out.println("Step Event!");
go = true;
}
}
}
This code works fine in Linux but not in Windows 7: to get file contents update I have to click on the output file. Where is the trick?
I am using Windows 7 prof, NetBeans IDE 8.0 RC1 (Build 201402242200) updated to version NetBeans 8.0 Patch 1.1, JDK 1.8
package watchfilethreadmod;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardWatchEventKinds.*;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class WatchFileThreadMod {
static class WatchFile {
String fileName;
long lastFilePos;
RandomAccessFile file;
public WatchFile(String _fileName, RandomAccessFile _file) {
fileName = _fileName;
lastFilePos = 0;
file = _file;
}
}
public static void shutDownListener(Thread thread) {
Thread thr = thread;
if (thr != null) {
thr.interrupt();
}
}
private static class MyWatchQueueReader implements Runnable {
/**
* the watchService that is passed in from above
*/
private WatchService myWatcher;
public ArrayList<WatchFile> threadFileToWatch;
public String dirPath;
public MyWatchQueueReader(String _dirPath, WatchService myWatcher, ArrayList<WatchFile> _threadFileToWatch) {
this.myWatcher = myWatcher;
this.threadFileToWatch = _threadFileToWatch;
this.dirPath = _dirPath;
}
private void openFile(WatchFile obj) {
try {
System.out.println("Open file "+obj.fileName);
obj.file = new RandomAccessFile(dirPath + "/" + obj.fileName, "r");
} catch (FileNotFoundException e) {
obj.file = null;
System.out.println("filename " + obj.fileName + " non trovato");
}
obj.lastFilePos = 0;
}
private void process(WatchEvent evt) {
String thisLine;
ArrayList<WatchFile> auxList = threadFileToWatch;
for (WatchFile obj : auxList) {
if (obj.fileName.equals(evt.context().toString())) {
if (obj.file == null) {
openFile(obj);
}
try {
obj.file.seek(obj.lastFilePos);
} catch (IOException e) {
System.err.println("Seek error: " + e);
}
try {
thisLine = obj.file.readLine();
if ((thisLine == null)&&(evt.kind() == ENTRY_MODIFY)) {
System.out.printf("---> thisLine == null received %s event for file: %s\n",
evt.kind(), evt.context());
obj.file.close();
System.out.println("Close file "+obj.fileName);
openFile(obj);
thisLine = obj.file.readLine();
}
while (thisLine != null) { // while loop begins here
if (thisLine.length() > 0) {
if (thisLine.substring(thisLine.length() - 1).equals("*")) {
obj.lastFilePos = obj.file.getFilePointer();
System.out.println(obj.fileName + ": " + thisLine);
}
}
thisLine = obj.file.readLine();
} // end while
} // end try
catch (IOException e) {
System.err.println("Error: " + e);
}
}
}
}
/**
* In order to implement a file watcher, we loop forever ensuring
* requesting to take the next item from the file watchers queue.
*/
#Override
public void run() {
try {
// get the first event before looping
WatchKey key = myWatcher.take();
while (key != null) {
// we have a polled event, now we traverse it and
// receive all the states from it
for (WatchEvent event : key.pollEvents()) {
WatchEvent.Kind eventType = event.kind();
if (eventType == OVERFLOW) {
continue;
}
process(event);
}
key.reset();
key = myWatcher.take();
}
} catch (InterruptedException e) {
ArrayList<WatchFile> auxList = threadFileToWatch;
for (WatchFile obj : auxList) {
if (obj.file != null) {
try {
obj.file.close();
System.out.println("chiusura file " + obj.fileName);
} catch (IOException ex) {
System.out.println("errore in chiusura file");
Logger.getLogger(WatchFileThreadMod.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
//e.printStackTrace();
}
System.out.println("Stopping thread");
}
}
public static void main(String[] args) throws Exception {
// get the directory we want to watch, using the Paths singleton class
//Path toWatch = Paths.get(DIRECTORY_TO_WATCH);
ArrayList<WatchFile> fileToWatch = new ArrayList<>();
String filename;
RandomAccessFile file;
fileToWatch.add(new WatchFile("EURUSD.rlt", new RandomAccessFile(args[0] + "/EURUSD.rlt", "r")));
filename = "EURCHF2.rlt";
try {
file = new RandomAccessFile(args[0] + "/" + filename, "r");
} catch (FileNotFoundException e) {
file = null;
System.out.println("filename " + filename + " non trovato");
}
fileToWatch.add(new WatchFile(filename, file));
fileToWatch = fileToWatch;
Path toWatch = Paths.get(args[0]);
if (toWatch == null) {
throw new UnsupportedOperationException("Directory not found");
}
// Sanity check - Check if path is a folder
try {
Boolean isFolder = (Boolean) Files.getAttribute(toWatch,
"basic:isDirectory", NOFOLLOW_LINKS);
if (!isFolder) {
throw new IllegalArgumentException("Path: " + toWatch + " is not a folder");
}
} catch (IOException ioe) {
// Folder does not exists
ioe.printStackTrace();
}
// make a new watch service that we can register interest in
// directories and files with.
WatchService myWatcher = toWatch.getFileSystem().newWatchService();
// start the file watcher thread below
MyWatchQueueReader fileWatcher = new MyWatchQueueReader(args[0], myWatcher, fileToWatch);
Thread processingThread = new Thread(fileWatcher, "FileWatcher");
processingThread.start();
toWatch.register(myWatcher, ENTRY_CREATE, ENTRY_MODIFY);
}
}
Edit: reduced code as requested.
Edit 2: file path
Edit 3: Metatrader code I am using to write data
#property strict
int file_handle;
string InpFileName = _Symbol + ".rlt"; // File name
input string InpDirectoryName = "Data"; // Folder name
int OnInit()
{
ResetLastError();
file_handle = FileOpen(InpDirectoryName + "//" + InpFileName, FILE_SHARE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
if(file_handle == INVALID_HANDLE) {
PrintFormat("Failed to open %s file, Error code = %d", InpFileName, GetLastError());
ExpertRemove();
}
return INIT_SUCCEEDED;
}
void OnTick()
{
// file_handle = FileOpen(InpDirectoryName + "//" + InpFileName, FILE_SHARE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
// Datetime), Bid, Volume
// string s = FileRead()
string s = TimeToStr(TimeGMT()) + "|" + Bid + "|" + Volume[0];
FileWriteString(file_handle, s + "|*\r\n");
FileFlush(file_handle);
//FileClose(file_handle);
}
void OnDeinit(const int reason)
{
FileClose(file_handle);
}
Edit 4: Screencast to better show my issue: data updates only when I click on the output file
Watch Service does not update
First of all, a premise : I'm answering this question primarily for future users of WatchService, which (like me) could experience this problem (i.e. on some systems events are signaled way after they occur).
The problem is that the implementation of this feature in Java is native, so it is platform-dependant (take a look at https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html, under the section 'platform dependencies').
In particular, on Windows 7 (and MacOSX afaict) the implementation uses polling to retrieve the changes from the filesystem, so you can't rely on the 'liveliness' of notifications from a WatchService. The notifications will eventually be signaled, but there are no guarantees on when it will happen.
I don't have a rigorous solution to this problem, but after a lot of trial and error I can describe what works for me :
First, when writing to a file that is registered (i.e. 'watched'), I try to flush the content every time I can and update the 'last modified' attribute on the file, e.g. :
try (FileWriter writer = new FileWriter(outputFile)) {
writer.write("The string to write");
outputFile.setLastModified(System.currentTimeMillis());
writer.flush();
}
Second, I try to 'trigger' the refresh from code (I know it's not good code, but in this case, I'm just happy it works 99% of the time)
Thread.sleep(2000);
// in case I've just created a file and I'm watching the ENTRY_CREATE event on outputDir
outputDir.list();
or (if watching ENTRY_MODIFY on a particular file in outputDir)
Thread.sleep(2000);
outputFile.length();
In both cases, a sleep call simply 'gives the time' to the mechanism underlying the WatchService to trigger, even though 2 seconds are probably a lot more than it is needed.
Probably missing quotes on file path.
This code works fine in Linux but not in Windows 7: to get file contents update I have to click on the output file. Where is the trick?
I am using Windows 7 prof, NetBeans IDE 8.0 RC1 (Build 201402242200) updated to version NetBeans 8.0 Patch 1.1, JDK 1.8
package watchfilethreadmod;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardWatchEventKinds.*;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class WatchFileThreadMod {
static class WatchFile {
String fileName;
long lastFilePos;
RandomAccessFile file;
public WatchFile(String _fileName, RandomAccessFile _file) {
fileName = _fileName;
lastFilePos = 0;
file = _file;
}
}
public static void shutDownListener(Thread thread) {
Thread thr = thread;
if (thr != null) {
thr.interrupt();
}
}
private static class MyWatchQueueReader implements Runnable {
/**
* the watchService that is passed in from above
*/
private WatchService myWatcher;
public ArrayList<WatchFile> threadFileToWatch;
public String dirPath;
public MyWatchQueueReader(String _dirPath, WatchService myWatcher, ArrayList<WatchFile> _threadFileToWatch) {
this.myWatcher = myWatcher;
this.threadFileToWatch = _threadFileToWatch;
this.dirPath = _dirPath;
}
private void openFile(WatchFile obj) {
try {
System.out.println("Open file "+obj.fileName);
obj.file = new RandomAccessFile(dirPath + "/" + obj.fileName, "r");
} catch (FileNotFoundException e) {
obj.file = null;
System.out.println("filename " + obj.fileName + " non trovato");
}
obj.lastFilePos = 0;
}
private void process(WatchEvent evt) {
String thisLine;
ArrayList<WatchFile> auxList = threadFileToWatch;
for (WatchFile obj : auxList) {
if (obj.fileName.equals(evt.context().toString())) {
if (obj.file == null) {
openFile(obj);
}
try {
obj.file.seek(obj.lastFilePos);
} catch (IOException e) {
System.err.println("Seek error: " + e);
}
try {
thisLine = obj.file.readLine();
if ((thisLine == null)&&(evt.kind() == ENTRY_MODIFY)) {
System.out.printf("---> thisLine == null received %s event for file: %s\n",
evt.kind(), evt.context());
obj.file.close();
System.out.println("Close file "+obj.fileName);
openFile(obj);
thisLine = obj.file.readLine();
}
while (thisLine != null) { // while loop begins here
if (thisLine.length() > 0) {
if (thisLine.substring(thisLine.length() - 1).equals("*")) {
obj.lastFilePos = obj.file.getFilePointer();
System.out.println(obj.fileName + ": " + thisLine);
}
}
thisLine = obj.file.readLine();
} // end while
} // end try
catch (IOException e) {
System.err.println("Error: " + e);
}
}
}
}
/**
* In order to implement a file watcher, we loop forever ensuring
* requesting to take the next item from the file watchers queue.
*/
#Override
public void run() {
try {
// get the first event before looping
WatchKey key = myWatcher.take();
while (key != null) {
// we have a polled event, now we traverse it and
// receive all the states from it
for (WatchEvent event : key.pollEvents()) {
WatchEvent.Kind eventType = event.kind();
if (eventType == OVERFLOW) {
continue;
}
process(event);
}
key.reset();
key = myWatcher.take();
}
} catch (InterruptedException e) {
ArrayList<WatchFile> auxList = threadFileToWatch;
for (WatchFile obj : auxList) {
if (obj.file != null) {
try {
obj.file.close();
System.out.println("chiusura file " + obj.fileName);
} catch (IOException ex) {
System.out.println("errore in chiusura file");
Logger.getLogger(WatchFileThreadMod.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
//e.printStackTrace();
}
System.out.println("Stopping thread");
}
}
public static void main(String[] args) throws Exception {
// get the directory we want to watch, using the Paths singleton class
//Path toWatch = Paths.get(DIRECTORY_TO_WATCH);
ArrayList<WatchFile> fileToWatch = new ArrayList<>();
String filename;
RandomAccessFile file;
fileToWatch.add(new WatchFile("EURUSD.rlt", new RandomAccessFile(args[0] + "/EURUSD.rlt", "r")));
filename = "EURCHF2.rlt";
try {
file = new RandomAccessFile(args[0] + "/" + filename, "r");
} catch (FileNotFoundException e) {
file = null;
System.out.println("filename " + filename + " non trovato");
}
fileToWatch.add(new WatchFile(filename, file));
fileToWatch = fileToWatch;
Path toWatch = Paths.get(args[0]);
if (toWatch == null) {
throw new UnsupportedOperationException("Directory not found");
}
// Sanity check - Check if path is a folder
try {
Boolean isFolder = (Boolean) Files.getAttribute(toWatch,
"basic:isDirectory", NOFOLLOW_LINKS);
if (!isFolder) {
throw new IllegalArgumentException("Path: " + toWatch + " is not a folder");
}
} catch (IOException ioe) {
// Folder does not exists
ioe.printStackTrace();
}
// make a new watch service that we can register interest in
// directories and files with.
WatchService myWatcher = toWatch.getFileSystem().newWatchService();
// start the file watcher thread below
MyWatchQueueReader fileWatcher = new MyWatchQueueReader(args[0], myWatcher, fileToWatch);
Thread processingThread = new Thread(fileWatcher, "FileWatcher");
processingThread.start();
toWatch.register(myWatcher, ENTRY_CREATE, ENTRY_MODIFY);
}
}
Edit: reduced code as requested.
Edit 2: file path
Edit 3: Metatrader code I am using to write data
#property strict
int file_handle;
string InpFileName = _Symbol + ".rlt"; // File name
input string InpDirectoryName = "Data"; // Folder name
int OnInit()
{
ResetLastError();
file_handle = FileOpen(InpDirectoryName + "//" + InpFileName, FILE_SHARE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
if(file_handle == INVALID_HANDLE) {
PrintFormat("Failed to open %s file, Error code = %d", InpFileName, GetLastError());
ExpertRemove();
}
return INIT_SUCCEEDED;
}
void OnTick()
{
// file_handle = FileOpen(InpDirectoryName + "//" + InpFileName, FILE_SHARE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
// Datetime), Bid, Volume
// string s = FileRead()
string s = TimeToStr(TimeGMT()) + "|" + Bid + "|" + Volume[0];
FileWriteString(file_handle, s + "|*\r\n");
FileFlush(file_handle);
//FileClose(file_handle);
}
void OnDeinit(const int reason)
{
FileClose(file_handle);
}
Edit 4: Screencast to better show my issue: data updates only when I click on the output file
Watch Service does not update
First of all, a premise : I'm answering this question primarily for future users of WatchService, which (like me) could experience this problem (i.e. on some systems events are signaled way after they occur).
The problem is that the implementation of this feature in Java is native, so it is platform-dependant (take a look at https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html, under the section 'platform dependencies').
In particular, on Windows 7 (and MacOSX afaict) the implementation uses polling to retrieve the changes from the filesystem, so you can't rely on the 'liveliness' of notifications from a WatchService. The notifications will eventually be signaled, but there are no guarantees on when it will happen.
I don't have a rigorous solution to this problem, but after a lot of trial and error I can describe what works for me :
First, when writing to a file that is registered (i.e. 'watched'), I try to flush the content every time I can and update the 'last modified' attribute on the file, e.g. :
try (FileWriter writer = new FileWriter(outputFile)) {
writer.write("The string to write");
outputFile.setLastModified(System.currentTimeMillis());
writer.flush();
}
Second, I try to 'trigger' the refresh from code (I know it's not good code, but in this case, I'm just happy it works 99% of the time)
Thread.sleep(2000);
// in case I've just created a file and I'm watching the ENTRY_CREATE event on outputDir
outputDir.list();
or (if watching ENTRY_MODIFY on a particular file in outputDir)
Thread.sleep(2000);
outputFile.length();
In both cases, a sleep call simply 'gives the time' to the mechanism underlying the WatchService to trigger, even though 2 seconds are probably a lot more than it is needed.
Probably missing quotes on file path.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm trying to make a programme which does times tables and it outputs a to a file called log.txt as a log file, but when I run it all it does is runs though and does the times tables and makes the file, but writes nothing to the file. Can someone please tell me, what's wrong with my code? If you do, thanks.
Key:
[.jar = runnable file]
[.zip = source code]
Download links:- http://wardogsk93-ftp.bugs3.com/Downloads/Java/Counter/
Java Doc:- http://wardogsk93-ftp.bugs3.com/Downloads/Java/Counter/Java%20Doc/
Main.java:-
public class Main {
/************************************************/
/*************STUFF YOU CAN CHANGE***************/
/************************************************/
/** change this to start at a different number must be a number {#link Integer}**/
public static int minCount = 1;
/** change to change the number of where the programme will end must be a number {#link Integer}**/
public static int maxCount = 10;
/** change this to how many times you want to sleep for in seconds (1 = 1 second, 2 = 2 second, 10 = 10 second) before moving to next sum must be a number {#link Integer} **/
public static int sleepAmountMultiplyer = 1;
/** true = outputs to the command prompt / false = outputs to eclipse console {#link boolean}**/
public static boolean outputTOCMD = true;
/************************************************/
/******DONT CHANGE ANYTHING BELOW THIS LINE******/
/************************************************/
/** allows to output to a command prompt **/
private static Console cmd;
private static Output file;
private static int endNumber = maxCount + 1;
private static int sleepAmount = 1000 * sleepAmountMultiplyer;
/**
* main method
* call this to start
**/
public static void start() {
file = new Output();
if (outputTOCMD) {
cmd = new Console();
count();
cmd.exit();
} else {
count();
System.exit(1);
}
}
public static Main getInstance() {
return Main.getInstance();
}
/**code to start running**/
private static void count() {
try {
for (int i = minCount; i < maxCount + 1; i++) {
int j = i * i;
Thread.sleep(sleepAmount);
if (i == endNumber) {
return;
}
if (outputTOCMD) {
cmd.out(i + " X " + i + " = " + j);
file.write(String.valueOf(i) + " X " + String.valueOf(i) + " = " + String.valueOf(j));
} else {
System.out.println(i + " X " + i + " = " + j);
file.write(String.valueOf(i) + " X " + String.valueOf(i) + " = " + String.valueOf(j));
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Output.class:-
import java.io.*;
public class Output {
public Output() {}
private Console cmd;
private File logFile;
private String input;
private BufferedReader reader;
private BufferedWriter writer;
public Output(Console cmd, File logFile, BufferedReader reader, BufferedWriter writer) {
this.cmd = cmd;
this.logFile = logFile;
this.reader = reader;
this.writer = writer;
}
/** writes to a log file using {#link FileWriter} **/
public void write(String message) {
try {
logFile = new File("log.txt");
writer = new BufferedWriter(new FileWriter(logFile));
if (!logFile.exists()) {
writer.write(message);
writer.close();
} else {
read();
if (logFile.isFile()) {
logFile.delete();
writer.write(message);
}
}
} catch (IOException e) {
if (Main.outputTOCMD) {
cmd.out(e.getMessage());
} else {
e.printStackTrace();
}
}
}
/** writes to a log file using {#link FileReader} **/
public void read() {
try {
logFile = new File("log.txt");
reader = new BufferedReader(new FileReader(logFile));
if (logFile.exists()) {
setInput(reader.readLine());
}
} catch (IOException e) {
if (Main.outputTOCMD) {
cmd.out(e.getMessage());
} else {
e.printStackTrace();
}
}
}
/**
* #return the input
*/
private String getInput() {
return input;
}
/**
* #param input the input to set
*/
private String setInput(String input) {
this.input = input;
return input;
}
}
Console.class:-
import java.awt.Color;
import java.awt.Image;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JTextArea;
/**
* Creates the command prompt window in class {#link Console}
*/
public class Console {
private JFrame frame;
private JTextArea console;
private Image icon;
public Console() {
try {
frame = new JFrame();
frame.setBackground(Color.BLACK);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setName("Commad Prompt");
frame.setSize(678, 340);
frame.setTitle(frame.getName());
frame.setVisible(true);
icon = new ImageIcon(new URL("http://upload.wikimedia.org/wikipedia/en/e/ef/Command_prompt_icon_(windows).png")).getImage();
frame.setIconImage(icon);
console = new JTextArea();
console.setAutoscrolls(true);
console.setBackground(Color.BLACK);
console.setEditable(false);
console.setForeground(Color.WHITE);
console.setSelectionColor(Color.WHITE);
console.setSelectedTextColor(Color.BLACK);
console.setVisible(true);
frame.add(console);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
/**
* #param {#link String} text does the same as {#link System}.out.println();
*/
public void out(String text) {
console.append(text + "\n");
}
/**
* #exception {#link Exception} to catch any errors and prints them to the window
* does the same has {#link System}.exit(1);
*/
public void exit() {
try {
Thread.sleep(1000 * Main.sleepAmountMultiplyer);
console.disable();
frame.dispose();
System.exit(1);
} catch (Exception e) {
this.out(e.getMessage());
}
}
/**
* #return Allows you to acces all the stuff in <br>{#link Console}</br>
**/
public Console getInstance() {
return this;
}
}
Launch File:-
public class Test {
public static void main(String[] args) {
Main.minCount = 1;
Main.maxCount = 10;
Main.sleepAmountMultiplyer = 1;
Main.outputTOCMD = true;
Main.start();
}
}
You must always use the close() method when finished writing to a file. Else wise it won't save it (you also want to close to avoid resource leak errors...read here). So in this method:
public void write(String message) {
try {
logFile = new File("log.txt");
writer = new BufferedWriter(new FileWriter(logFile));
if (!logFile.exists()) {
writer.write(message);
writer.close();
} else {
read();
if (logFile.isFile()) {
logFile.delete();
writer.write(message);
}
}
//close the buffer writer in order to save
writer.close();
} catch (IOException e) {
if (Main.outputTOCMD) {
cmd.out(e.getMessage());
} else {
e.printStackTrace();
}
}
}
Alternatively, you can close in a finally block. You must also close the BufferReader after you're done reading. You need to be very careful when using Thread if you plan to have multiple Thread reading/writing to same file.
NOTE: This will overwrite the file each time. However, if you want to append the data, change this line:
writer = new BufferedWriter(new FileWriter(logFile));
To:
writer = new BufferedWriter(new FileWriter(logFile, true));
The second parameter in FileWriter is confirming whether you want to overwrite the file or append to the file. Check out this example.
try {
String comd ="E:/ior1.txt";
Runtime rt = Runtime.getRuntime();
rt.exec("C:/tes1.bat"+comd+"");
System.out.println("Process exitValue: ");
}
catch (Exception e)
{
System.out.println("Unexpected exception Trying to Execute Job: " +e);
}
But when I run I get an exception like this
Unexpected exception Trying to Execute Job: java.io.IOException: CreateProcess:
C:/tes1.batE:/ior1.txt error=2
Press any key to continue . . .
This is the batch file content
echo "testing"
echo %1
There's a blank missing after .bat (in the rt.exec line)
Edit:
You could also try executing:
rt.exec("cmd /c c:/tes1.bat "+comd);
Try prefixing the exec call with cmd /c or call, e.g.
rt.exec("cmd /c c:/tes1.bat "+comd);
(I don't have a Windows box available right now so I can't test this but as far as I remember, launching batch files required launching the command interpreter first.)
When i see this correct, you have to put a space between the bat command and the argument
EDIT:
try {
String comd ="E:/ior1.txt";
Runtime rt = Runtime.getRuntime();
rt.exec("C:/tes1.bat "+comd+"");
System.out.println("Process exitValue: ");
}
catch (Exception e)
{
System.out.println("Unexpected exception Trying to Execute Job: " +e);
}
EDIT 2:
After taking a look again and testing on my PC the other answers seems correct. The cmd is missing.
rt.exec("cmd /c c:/tes1.bat "+comd);
Be aware, that there is a number of issues related to executing an external process from within your Java program if you have to use this in a production environment.
You have e.g. to be aware of the fact, that if the output from the process is larger than the buffer used by the JVM<->OS the exec will block forever.
I normally use a wrapper with Threads to read from the buffers.
Its not perfect, but something like (see main() for details on usage):
/**
* Executes a given OS dependent command in a given directory with a given environment.
* The parameters are given at construction time and the initialized object is immutable.
* After the object initialization and execution of the blocking exec() method the state
* can't be changed. The result of the execution can be accessed through the get methods
* for the exitValue, stdOut, and stdErr properties. Before the exec() method is completed
* the excuted property is false and the result of other getters is undefined (null).
*/
public class CommandExecutor {
/**
* Specifies the number of times the termination of the process is
* waited for if the OS gives interruptions
*/
public static final int NUMBER_OF_RUNS = 2;
/**
* Used for testing and as example of usage.
*/
public static void main(String[] args) {
System.out.println("CommandExecutor.main Testing Begin");
String command_01 = "cmd.exe /C dir";
File dir_01 = new File("C:\\");
System.out.println("CommandExecutor.main Testing. Input: ");
System.out.println("CommandExecutor.main Testing. command: " + command_01);
System.out.println("CommandExecutor.main Testing. dir: " + dir_01);
CommandExecutor ce_01 = new CommandExecutor(command_01, null, dir_01);
ce_01.exec();
System.out.println("CommandExecutor.main Testing. Output:");
System.out.println(" exitValue: " + ce_01.getExitValue());
System.out.println(" stdout: " + ce_01.getStdout());
System.out.println(" stderr: " + ce_01.getStderr());
String command_02 = "cmd.exe /C dirs";
File dir_02 = new File("C:\\");
System.out.println("CommandExecutor.main Testing. Input: ");
System.out.println("CommandExecutor.main Testing. command: " + command_02);
System.out.println("CommandExecutor.main Testing. dir: " + dir_02);
CommandExecutor ce_02 = new CommandExecutor(command_02, null, dir_02);
ce_02.exec();
System.out.println("CommandExecutor.main Testing. Output:");
System.out.println(" exitValue: " + ce_02.getExitValue());
System.out.println(" stdout: " + ce_02.getStdout());
System.out.println(" stderr: " + ce_02.getStderr());
System.out.println("CommandExecutor.main Testing End");
}
/*
* The command to execute
*/
protected String command;
/*
* The environment to execute the command with
*/
protected String[] env;
/*
* The directory to execute the command in
*/
protected File dir;
/*
* Flag set when the command has been executed
*/
protected boolean executed = false;
/*
* Exit value from the OS
*/
protected int exitValue;
/*
* Handle to the spawned OS process
*/
protected Process process;
/*
* Std error
*/
protected List<String> stderr;
/*
* Worker Thread to empty the stderr buffer
*/
protected Thread stderrReader;
/*
* Std output
*/
protected List<String> stdout;
/*
* Worker Thread to empty the stdout buffer
*/
protected Thread stdoutReader;
/**
* Creates a new instance of the CommandExecutor initialized to execute the
* specified command in a separate process with the specified environment
* and working directory.
*
* #param env
*/
public CommandExecutor(String command, String[] env, File dir) {
this.command = command;
this.env = env;
this.dir = dir;
}
/**
* Creates a reader thread for the stderr
*/
protected void connectStderrReader() {
stderr = new ArrayList<String>();
final InputStream stream = process.getErrorStream();
final BufferedReader reader =
new BufferedReader(new InputStreamReader(stream));
stderrReader = new Thread(new Runnable() {
public void run() {
String nextLine = null;
try {
while ((nextLine = reader.readLine()) != null) {
stderr.add(nextLine);
}
} catch (IOException e) {
System.out.println(
"CommandExecutor.connectStderrReader() error in reader thread");
e.printStackTrace(System.out);
}
}
});
stderrReader.start();
}
/**
* Creates a reader thread for the stdout
*/
protected void connectStdoutReader() {
stdout = new ArrayList<String>();
final InputStream stream = process.getInputStream();
final BufferedReader reader =
new BufferedReader(new InputStreamReader(stream));
stdoutReader = new Thread(new Runnable() {
public void run() {
String nextLine = null;
try {
while ((nextLine = reader.readLine()) != null) {
stdout.add(nextLine);
}
} catch (IOException e) {
System.out.println(
"CommandExecutor.connectStdoutReader() error in reader thread");
e.printStackTrace(System.out);
}
}
});
stdoutReader.start();
}
/**
* Creates the process for the command
*/
protected void createProcess() {
try {
process = Runtime.getRuntime().exec(command, env, dir);
} catch (IOException e) {
System.out.println("CommandExecutor.exec() error in process creation. Exception: " + e);
e.printStackTrace(System.out);
}
}
/**
* Executes command in a separate process in the specified directory. Method will block until
* the process has terminated. Command will only be executed once.
*/
public synchronized void exec() {
// Future enhancement: check for interrupts to make the blocking nature interruptible.
if (!executed) {
createProcess();
connectStdoutReader();
connectStderrReader();
waitForProcess();
joinThreads();
exitValue = process.exitValue();
executed = true;
}
}
/**
* #return the command
*/
public String getCommand() {
return command;
}
/**
* #return the dir
*/
public File getDir() {
return dir;
}
/**
* #return the env
*/
public String[] getEnv() {
return env;
}
/**
* #return the exitValue
*/
public int getExitValue() {
return exitValue;
}
/**
* #return the stderr
*/
public List<String> getStderr() {
return stderr;
}
/**
* #return the stdout
*/
public List<String> getStdout() {
return stdout;
}
/**
* #return the executed
*/
public boolean isExecuted() {
return executed;
}
/**
* Joins on the 2 Reader Thread to empty the buffers
*/
protected void joinThreads() {
try {
stderrReader.join();
stdoutReader.join();
} catch (InterruptedException e) {
System.out.println("CommandExecutor.joinThreads() error. Exception: ");
e.printStackTrace(System.out);
}
}
/**
* Creates a String representing the state of the object
*/
#Override
public synchronized String toString() {
StringBuilder result = new StringBuilder();
result.append("CommandExecutor:");
result.append(" command: " + command);
result.append(" env: " + Arrays.deepToString(env));
result.append(" dir: " + dir);
result.append(" executed: " + executed);
result.append(" exitValue: " + exitValue);
result.append(" stdout: " + stdout);
result.append(" stderr: " + stderr);
return result.toString();
}
/**
* Waits for the process to terminate
*/
protected void waitForProcess() {
int numberOfRuns = 0;
boolean terminated = false;
while ((!terminated) && (numberOfRuns < NUMBER_OF_RUNS)) {
try {
process.waitFor();
terminated = true;
} catch (InterruptedException e) {
System.out.println("CommandExecutor.waitForProcess() error");
e.printStackTrace(System.out);
numberOfRuns++;
}
}
}
}
Additonal to laalto's comment:
Runntime provides several signatures of exec().
rt.exec("cmd /c c:/tes1.bat "+comd);
rt.exec(new String[] {"cmd","/c","c:/tes1.bat",comd});