Checking to see where a function was called in Java - java

I'm working on some software that reads from a file system using a specific inputstream reader. This class has a function called read() which is used in some driver program to read files. I want to find out the location/source file for the driver program. If I only know where read() is implemented how can I find where it is used?

You can run this command on the top-level directory of the project to find where read() is used:
grep -n --recursive " read(" *
This will recursively search all the files for the string " read(" and print out which file it is in, as well as the line number.
Unfortunately, knowing where read() is implemented won't directly tell you where it is used. The implementation of a method is not dependent on where it is used, that's the other way around. If it were dependent, every single library in the Javadocs would have information about all the obscure programs that used such a library.

Assuming you can modify read() you might get a stack trace. Either throw an unchecked exception or do something like
StackTraceElement[] st = Thread.currentThread().getStackTrace();
System.out.println(Arrays.toString(st));

Related

What is System.out exactly?

I noticed that any call to System.out.println() from a JAR file that hasn't been started by the command line (i.e. a Runnable JAR file started by user with double-click) won't open the console.
After doing some research, I found multiple answers on the site:
System.out.println in jar
There is no problem doing like that. But where do you expect to see the output?
What happens to “System.out.println()” in executable jar?
If you run the code in some way that doesn't attach a console - such as javaw on Windows, which is the default program associated with executable jar files - then the output won't go anywhere. It won't cause any errors - the text will just be lost.
From what I understand, System.out does not represent the console. It does represent data which can be handled by anything that needs to display it.
Am I right?
What is System.out exactly?
How do I open the console from a Runnable JAR file started by user with double-click?
Processes in modern operating systems (and for that matter, several older operating systems) get three standard "streams" associated with them:
Standard in: Stream-based input (stdin)
Standard out: Stream-based output (stdout)
Standard error: Stream-based error output (stderr)
Collectively (and creatively) they're called the standard streams.
System.in, System.out, and System.err are, by default, Java's standard mechanism for writing to those streams.
Programs invoked from the command line are run in an environment where keystrokes in the command line go to stdin, and the output of both stdout and stderr shows as text in the console. They can be redirected to files, etc.
Programs launched via GUIs frequently don't have those streams hooked to anything you can see.
I say "by default" above because you can use calls on System to change where those streams point (they have creative names like setIn, setOut, and setErr.)
How do I open the console from a Runnable JAR file started by user with double-click?
There's a false correlation there: The fact that the jar is runnable is not why you don't see the streams. If you run a runnable jar at the command line, you'll see its standard output.
Whether you can see that output if you run it without it being associated with a console of some kind will depend on how you're running it and, potentially, how it's written. Many GUI frameworks will redirect standard out and err to a log file. Or the app may offer debugging options that do so. There's no one standard answer there (no pun).
Here, System.out represents the output stream - where your output will go. By default it is set to console. But you can change it to other like - text file. Most often, in large application it is used for logging (usually by new programmer, bad idea). In this case you can see the output in appropriate log file.
System is final class from java.lang package(default package in java) and cannot be instantiated.
out is a static member field of System class and is of type PrintStream and its access specifiers are public final.
println – is an overloaded method of PrintStream class. println prints the argument passed to the standard console and a newline. There are multiple println overloaded methods with different arguments. Every println makes a call to print method and adds a newline. Internally, print calls write() and write() takes care of displaying data to the standard output window.
Here it is how it should look in the inside:
//the System class belongs to java.lang package
class System {
public static final PrintStream out;
//...
}
//the Prinstream class belongs to java.io package
class PrintStream{
public void println();
//...
}
We therefore don't need to ever instantiate a System object to print messages to the screen; we simply call the println method on the System class's public static PrintStream member, out.
But you cannot create an object of PrintStream and call the println function. When you want to print to the standard output, then you will use System.out. That's the only way. Instantiating a PrintStream will allow you to write to a File or OutputStream you specify, but don't have anything to do with the console.
However, you can pass System.out to PrintStream and then invoke println on PrintStream object to print to the standard output. Here is a small example:
import java.io.*;
public class SystemOutPrintlnDemo
{
public static void main(String[] args)
{
//creating PrintStream object
PrintStream ps = new PrintStream(System.out);
ps.println("Hello World!");
ps.print("Hello World Again!");
//Flushes the stream
ps.flush();
}
}

Is there any way that Java could get current file name and current line number?

In C++, the file of the source code and current line number is decided by FILE and INLINE, which is decided at compiling time, is there any method in Java that could do the similar thing? The file and line number is decided at compiling time instead of runtime? this will be convenient for log. I kind of doubt that use runtime method to detect these information will decrease the performance.
You could use Thread.getStackTrace() and something like
System.out.println(Thread.currentThread().getStackTrace()[1]);
Output includes the current method and line number (if debugging was compiled in).
For example,
com.stackoverflow.Main.main(Main.java:23)

Write to non existing file with Files using Java 7

Hi I try to write to non existing file
public static void main(String[] args) throws IOException {
Path newFile = Paths.get("output.txt");
Files.write(newFile, "Sample text".getBytes());
}
And everything is OK but if I put option
Files.write(newFile, "Sample text".getBytes(),StandardOpenOption.DELETE_ON_CLOSE);
An error appears
Exception in thread "main" java.nio.file.NoSuchFileException: problem.txt
at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
So to work I have to add option
StandardOpenOption.CREATE_NEW
Why in the second attempt with StandardOpenOption.DELETE_ON_CLOSE doesn't work but the first without any option works and creates file?
I am using java version(build 1.7.0_45-b18)
From the documentation for Files.write:
If no options are present then this method works as if the CREATE, TRUNCATE_EXISTING, and WRITE options are present
So, once you start specifying OpenOptions, you have to specify the options you need from those three as well (or as you already noted, CREATE_NEW instead of CREATE).
According to Documentation
public static final StandardOpenOption DELETE_ON_CLOSE
Delete on close. When this option is present then the implementation makes a best effort attempt to delete the file when closed by the appropriate close method. If the close method is not invoked then a best effort attempt is made to delete the file when the Java virtual machine terminates (either normally, as defined by the Java Language Specification, or where possible, abnormally). This option is primarily intended for use with work files that are used solely by a single instance of the Java virtual machine. This option is not recommended for use when opening files that are open concurrently by other entities. Many of the details as to when and how the file is deleted are implementation specific and therefore not specified. In particular, an implementation may be unable to guarantee that it deletes the expected file when replaced by an attacker while the file is open. Consequently, security sensitive applications should take care when using this option.
So how are supposed to delete a file that does not exist ?

reading a file while it's being written

I've read some posts on stackoverflow about this topic but I'm still confused. When reading a file that is currently being written in Java, how do you keep track of how many lines have actually been written so that you don't get weird read results?
EDIT: sorry, I should have mentioned that the file writing it is in C++ and the one reading it is in Java so variables can't really be shared easily
When reading a file that is currently being written in Java, how do you keep track of how many lines have actually been written so that you don't get weird read results?
The problem is that you can never be sure that the current last character of the file is the end of a line. If it is a line terminator, you are OK. If BufferedReader.readLine() will interpret it as a complete line without a line terminator ... and weird results will ensue.
What you need to do is to implement your own line buffering. When you get an EOF you wait until the file grows some more and then resume reading the line.
Alternatively, if you are using Java 7 or later, the file watcher APIs allow you to watch for file writes without polling the file's size.
By the way, there is an Apache commons class that is designed for doing this kind of thing:
http://commons.apache.org/io/api-2.0/org/apache/commons/io/input/Tailer.html
If I understand, the file is being written in C# in some process and another Java process wants to read it while it is being written.
Look at File Monitoring section on the tail command here. But I want to warn you that when I used the cygwin tail on Windows recently to follow log files that were rolling over, it sometimes failed under heavy load. Other implementations may be more robust.
To have a count of the number of lines, just keep a counter on the side that's doing the writing.
So, every time you write a line, increment a counter, and make that counter readable via a method, something like, public int getNumLinesWritten()
The obvious answer to me... Why not use a buffer? Use a string or whatever you need. (You could use a list/array of strings if you want, one for each line maybe?) Append to the string just as you would write to the file, then instead of reading from the file, read from that string. Would that work for you?

Windows 7 /Eclipse watchpoint on file access

Is there a way in Eclipse [Helios] on Win 7 to watch for a file to be opened? Do I have to know where the app is going to do so, or is there a way to watch for a java.io object being created/something or other?
tia Rene
You could try setting breakpoints on the constructors of FileInputStream and/or FileOutputStream with conditions to check whether the filename provided matches your target filename (e.g. check the parameter on the constructors that take a filename, check the File.getName() on the constructors that take a File). Alternatively or in addition, you could set breakpoints on File constructors with a condition to check whether the specified filename is your target filename.
If your breakpoint trap trips, you can follow the stacktrace to see what methods are directly or indirectly access the file.

Categories

Resources