why there is PointerException while running code [duplicate] - java

I have just started learning Java with IntelliJ IDE. I know a bit C# so the logic makes some sense, however there is one thing so far I couldn't get over it.
How do I read from the console? In C#, you could easily read what the human typed into it, using Console.ReadLine(). In Java, System.console().readLine(); does not work for me and throws a NullPointerException.
What am I missing here?

NOTE: problem doesn't appear when we run your code from console/terminal via java [options] [MainClass] so if this is valid solution for you you can stop reading here. Rest of this answer is for people who are using some IDEs to run their code.
Problem
Most IDEs are using javaw.exe instead of java.exe to run Java code (see image below).
Difference between these two programs is that javaw runs Java code without association with current terminal/console (which is useful for GUI applications), and since there is no associated console window System.console() returns null. Because of that System.console().readLine() ends up as null.readLine() which throws NullPointerException since null doesn't have readLine() method (nor any method/field).
But just because there is no associated console, it doesn't mean that we can't communicate with javaw process. This process still supports standard input/output/error streams, so IDEs process (and via it also we) can use them via System.in, System.out and System.err.
This way IDEs can have some tab/window and let it simulate console.
For instance when we run code like in Eclipse:
package com.stackoverflow;
public class Demo {
public static void main(String[] args) throws Exception {
System.out.println("hello world");
System.out.println(System.console());
}
}
we will see as result
which shows that despite javaw.exe not having associated console (null at the end) IDE was able to handle data from standard output of the javaw process System.out.println("hello world"); and show hello world.
General solution
To let user pass information to process use standard input stream (System.in). But since in is simple InputStream and Streams are meant to handle binary data it doesn't have methods which would let it easily and properly read data as text (especially if encoding can be involved). That is why Readers and Writers ware added to Java.
So to make life easier and let application read data from user as text you can wrap this stream in one of the Readers like BufferedReader which will let you read entire line with readLine() method. Unfortunately this class doesn't accept Streams but Readers, so we need some kind of adapter which will simulate Reader and be able to translate bytes to text. But that is why InputStreamReader exists.
So code which would let application read data from input stream could look like
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Hello. Please write your name: ");
String name = br.readLine();
System.out.println("Your name is: "+name);
Preferred/simplest solution - Scanner
To avoid this magic involving converting Stream to Reader you can use Scanner class, which is meant to read data as text from Streams and Readers.
This means you can simply use
Scanner scanner = new Scanner(System.in);
//...
String name = scanner.nextLine();
to read data from user (which will be send by console simulated by IDE using standard input stream).

If you realy need to Console object you can compile your class from command line. Firstly in my java file first statement is package com.inputOutput;
Go in your project "src" folder and compile it like : "javac com/inputOutput/Password.java" 'com' and 'inputOutput' are folder(package). Run your class file in src folder
java com.inputOutput.Password". It had worked work for me.

You could use an Jframe.
JFrame frame = new JFrame("titile");
// prompt the user to enter their code
String code = JOptionPane.showInputDialog(frame, "promt here");

java.util.Scanner API is what you are looking for.

Related

Understanding java IO, opening/closing files using JFileChooser and opening/closing/saving binary files

I've been assigned a Java project by my professor and per usual, he didn't teach us how to use the tools we need to get the job done. So I'm trying to teach myself the basics of file manipulation as well as how to use JFileChooser, and I'm pretty confused.
In this project, he wanted us to create a JMenuBar with 3 JMenus(File, Batch Processing, Interactive Processing). Under the File JMenu, I have 5 JMenuItems(Open Binary File, Close Binary File, Save Binary File, Create Report, Exit). I listed these to hopefully give an idea of what the app is trying to accomplish.
Here are some snippets of instruction, which is what I've been interpreting and trying to mess around with:
1) Globally declare and create an object of the JFileChooser class:
JFileChooser jfc = new JFileChooser();
2) Complete the actionPerformed as follows:
for each JMenuItem selected, you will be calling a method or performing an action:
OpenMI: call the OpenFile method to open the binary access file for input
CloseMI: provide warning (JOptionPane) to Save first, if yes, then close the binary file and repaint
SaveMI: call method to open binary file for output then call method to output to it
ReportMI: call method to open text file and output to it
ExitMI: System.exeit(0);
PopulateBatchMI: call method to read from opened binary sequential file and put data into the array of tools objects(a class we created previously)
DisplayMI: display the contents of the toolsarray in a JTextArea on this screen
HideMI: hide the contents of the JTextArea displaying the toolsarray contents
*3) Write each method according to notes given in the text and in the lecture!
Part 4 Next, complete the following: (BSAF = Binary Sequentia Access File)*
1.Write a method called SaveBSAFile and within it
a. Create an object of the DataOutputStream
b. Create an object of the JFileChooser. Include all JFileChooser code, use the Save option
1. Open the binary sequential file for output
2. print a message to state that it is opened (use a JOptionPane)
c. call the SaveBSAFile method when the SaveFile menu item is clicked
I'm having trouble understanding how to use the FileInputStream/FileOutputStream DataInputStream/DataOutputStream classes in conjunction with JFileChooser. All I've learned so far has been off of this site or others, so my understanding of how these classes work, especially together, has me confused. If anyone wanted to give me an explanation, I would really appreciate it.
Here is the code I've been working with so far, although it doesn't seem to be working correctly. There is an actionPerformed() that is used when the user clicks one of the menu options, and calls the methods I'm trying to write here:
public void saveBSAFile()
{
filename = JOptionPane.showInputDialog("Please specify a file name for the "
+ " file you wish to save");
try
{
FileOutputStream FOStream = new FileOutputStream(filename);
DataOutputStream DOStream = new DataOutputStream(FOStream);
}
catch (FileNotFoundException e)
{
System.out.println("file name was not found");
}
jfc.setDialogTitle("Specify a file to save");
int userSelection = jfc.showSaveDialog(this);
if (userSelection == jfc.APPROVE_OPTION)
{
File filename = jfc.getSelectedFile();
JOptionPane.showMessageDialog(null, "File to save " + filename,
"Save Review", JOptionPane.INFORMATION_MESSAGE);
}
else if (userSelection == jfc.CANCEL_OPTION)
{
return;
}
}
public void openBSAFile()
{
int status = jfc.showOpenDialog(this);
if (status == JFileChooser.APPROVE_OPTION)
{
File selectedFile = jfc.getSelectedFile();
filename = selectedFile.getAbsolutePath();
JOptionPane.showMessageDialog(null, "You selected " + filename,
"File Review",
JOptionPane.INFORMATION_MESSAGE);
try
{
FileInputStream fstream = new FileInputStream(filename);
DataInputStream dstream = new DataInputStream(fstream);
}
catch (FileNotFoundException e)
{
JOptionPane.showMessageDialog(null, "File not found. Please select a " +
"valid file to open", "File Not found",
JOptionPane.ERROR_MESSAGE);
System.err.println(e);
e.printStackTrace();
}
}
}
There are no errors, but nothing seems to be happening. The saveBSAFile method is misleading because it seems its purpose is to create a file and save data from the array of tool objects (which has data members such as ID, price, numberInStock, ect).
No file is created, and when I try to open one I've created and specified, nothing happens, either.
In addition to reading tutorials, StackOverflow questions, Javadocs, and general trial-and error, most of what I know about Swing-based GUIs and I/O came from Introduction to Programming Using Java, a free textbook by David Eck. He provides very readable working code, and if anything that follows is unclear, I recommend reading along in the source to SimplePaintWithFiles.java.
Remember that a variable only exists within the section of code where it is declared, regardless of the variable's type. In this case, that means that fstream and dstream only exist in your try block, so you can only use them there. Do also brush up on when to use public, protected, and private access modifiers for methods.
What follows is a flowchart of the high-level steps to I/O, as I understand them. It contains simple code snippets that are deliberately out of context because they turn up in too many different contexts to include here.
1. Choose a path to interact with for I/O
via a String literal in your code
via System.in, a Scanner, or some other input stream
via a GUI object such as a JFileChooser
2. Construct a File object pointing to that pathname (and probably keep a pointer to it)
case 1.1: pass the String literal (or the variable you declared with it) to a File constructor
e.g. File someFile = new File("/a/hardcoded/absolute/path"); This isn't flexible, easy to maintain, or necessarily secure for distributable code, but comes in handy for unit tests, quick and dirty scripts, and tiny snippets in answers and forums where the poster assumes the reader knows better than to put a million literals all over their code.
case 1.2: assuming some Scanner is in scope called scnr, String thePath = scnr.next(); Put check code after this to determine is thePath is really an acceptable path for your use case, before passing thePath to other methods, including constructors.
case 1.3: this is why JFileChooser jfc = new // whatever constructor is best for your use case; is usually declared globally. It's always in scope; the menu items all have a single repository of information about the last-chosen file, so their actionPerformed methods can "talk" to each other; and the private utility methods such as openBSAFile() can query File targetFile = jfc.getSelectedFile(); for the File to operate on.
3. Now I have a File! What do I do with it?
That depends on whether there is already a file on disk at the chosen address and whether you expect a file to be there. This is one reason to keep a pointer to the currently-active File, so you can call it's exists() method, mkdir(), etc as needed.
If the file already exists on disk, perform interaction0. An output method should probably throw an error or ask for permission to overwrite. An input method will probably proceed normally.
If the file does not exist on disk, perform interaction1. An input method will probably throw an error (and maybe catch its own error, such as to display a dialog). An output method will probably proceed normally.
4. Remember to flush
Just because you have called dstream.writeChars("Content of some string-type variable you need to save"); doesn't mean that your variable has actually been sent to the disk. call dstream.flush() before closing, returning, or otherwise assuming that the data has safely arrived. See TextIO.java at the second link above for some great examples of when flushing is the solution to bugs.
5. Close your open streams! (This is what confused me the most)
When to close an open stream? The short answer is "when you're done with it," but that's as vague as saying "a piece of rope is as long as you need it to be." So how do you know when you're done? There are two broad categories of "done with a stream." I still don't fully understand when streams are implicitly closed, so when in doubt I tend to add close() statements that might be redundant. There is some debate about whether unclosed streams can fairly be called "memory leaks," but they do tie up scarce resources.
An IOException has occurred after which your code cannot function correctly. In addition to throwing an exception, catching an exception, displaying dialogs, etc, you are also done with your streams. In your code above, calling dstream.close() will also close fstream because dstream is its wrapper.
Your code has finished interacting with the stream normally. In this case, you have written or read all the data you need, no errors have occurred, and the method using the stream is about to return.
Deeper discussion of cases 3.1, 3.2, and 5.1
It's metaphor time.
Opening a stream with a File is like calling someone on the phone. If an exception is not thrown and the stream is opened, consider that "picking up the phone." You called, they picked up, now it's your turn to say something. Saying something might mean reading data from the stream, or it might mean writing data to it. Either way, complete the business you called about, then hang up.
Things could still be going wrong even if an input stream hasn't thrown an error. If you are supposed to be reading a list of integers from a file, and the file actually contains Moby Dick, something has gone wrong that Java's built-in I/O classes can't detect. It is our job as programmers to include code to check the semantic correctness of the data we read from a file, for the same reasons we must include code to check the semantic correctness of a pathname obtained in case 2.2. Only you know what "correctness" looks like for your data, and relying on a file extension is not enough.
Aside about binary save files:
The assignment specifications provided in the question don't call for Serialization. They do, however, call for a known set of fields and a known representation of those fields. Most of the searches I have done about binary save data recommend Serialization because you don't have to do so much hand coding. However, such an assignment isn't just making you work harder; arguments could be made that your save files will be more useful without Serialization. I don't have the space to get into details here, nor am I attempting to open an opinion-based can of worms. Instead, you might have a look at the unofficial specification of the .xcf file format for inspiration on how and in what order you might manually save the data needed to recreate any given object.
You are opening the streams, but you do not use them. Since the streams are declared in a (try-)block, they are only alive and visible in the try-block. Your manipulation of the stream should be happening inside the try-block. Furthermore, you should use the try-with-resources statement. Here you find a tutorial on how to use basic I/O-streams. You can use a JFileChooser to handle the open dialog.

Trying to read from the console in Java

I have just started learning Java with IntelliJ IDE. I know a bit C# so the logic makes some sense, however there is one thing so far I couldn't get over it.
How do I read from the console? In C#, you could easily read what the human typed into it, using Console.ReadLine(). In Java, System.console().readLine(); does not work for me and throws a NullPointerException.
What am I missing here?
NOTE: problem doesn't appear when we run your code from console/terminal via java [options] [MainClass] so if this is valid solution for you you can stop reading here. Rest of this answer is for people who are using some IDEs to run their code.
Problem
Most IDEs are using javaw.exe instead of java.exe to run Java code (see image below).
Difference between these two programs is that javaw runs Java code without association with current terminal/console (which is useful for GUI applications), and since there is no associated console window System.console() returns null. Because of that System.console().readLine() ends up as null.readLine() which throws NullPointerException since null doesn't have readLine() method (nor any method/field).
But just because there is no associated console, it doesn't mean that we can't communicate with javaw process. This process still supports standard input/output/error streams, so IDEs process (and via it also we) can use them via System.in, System.out and System.err.
This way IDEs can have some tab/window and let it simulate console.
For instance when we run code like in Eclipse:
package com.stackoverflow;
public class Demo {
public static void main(String[] args) throws Exception {
System.out.println("hello world");
System.out.println(System.console());
}
}
we will see as result
which shows that despite javaw.exe not having associated console (null at the end) IDE was able to handle data from standard output of the javaw process System.out.println("hello world"); and show hello world.
General solution
To let user pass information to process use standard input stream (System.in). But since in is simple InputStream and Streams are meant to handle binary data it doesn't have methods which would let it easily and properly read data as text (especially if encoding can be involved). That is why Readers and Writers ware added to Java.
So to make life easier and let application read data from user as text you can wrap this stream in one of the Readers like BufferedReader which will let you read entire line with readLine() method. Unfortunately this class doesn't accept Streams but Readers, so we need some kind of adapter which will simulate Reader and be able to translate bytes to text. But that is why InputStreamReader exists.
So code which would let application read data from input stream could look like
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Hello. Please write your name: ");
String name = br.readLine();
System.out.println("Your name is: "+name);
Preferred/simplest solution - Scanner
To avoid this magic involving converting Stream to Reader you can use Scanner class, which is meant to read data as text from Streams and Readers.
This means you can simply use
Scanner scanner = new Scanner(System.in);
//...
String name = scanner.nextLine();
to read data from user (which will be send by console simulated by IDE using standard input stream).
If you realy need to Console object you can compile your class from command line. Firstly in my java file first statement is package com.inputOutput;
Go in your project "src" folder and compile it like : "javac com/inputOutput/Password.java" 'com' and 'inputOutput' are folder(package). Run your class file in src folder
java com.inputOutput.Password". It had worked work for me.
You could use an Jframe.
JFrame frame = new JFrame("titile");
// prompt the user to enter their code
String code = JOptionPane.showInputDialog(frame, "promt here");
java.util.Scanner API is what you are looking for.

how to pass input during executin of java code in eclipse

I pass command line arguments to my java code in eclipse (and retrieve it using args[] in main method)-this is fine.
However, my scenario is different. My code periodically asks for input during execution. Where would I enter such input? when controls hits such input prompt, eclipse freezes
EDIT
Some of the answers I read below suggests using command line args or buffered reader or using console view: but my eclipse freezes right after asking me for sudo password (further, my situation is different from command line args as explained in the very first line).
I am using Kepler on centos 6.5
Eclipse has a console, its typically located at the bottom of your java perspective. If its not there just go to Window->Show View->Console.
Have you ever used an input stream reader or a buffered reader?
The following is a start on how
static InputStreamReader input = new InputStreamReader(System.in);
static BufferedReader in = new BufferedReader(input);
Then you can use the buffered reader for taking input during execution.
you can pass command line arguments from eclipse, run your program from eclipse as run on configuration it will open dialog box and click arguments tab and pass your arguments from there
Go to Window -> Show View -> Console. You will able to enter input.
For short cut , type : Alt + Shift + Q, C.
Use the Scanner class. You have to import it from java.util.Scanner;
String userInput;
Scanner input = new Scanner(System.in);
System.out.print("Enter something: ");
userInput = input.nextLine();
and remember to close the scanner when you're done using it
input.close();
Puzzled why my question is down voted and why few respondents suggested irrelevant answer.
You can pass input using scanner or input stream if your code is expecting it. But my question is asking for uncertain situations(in this case, if my eclipse is started as sudo it wont ask for root password; but if I start as regular user it would ask for root password based on the Linux shell command that my java code has to exec)
Yes, you can pass the input to java code (executed under eclipse). From the command line window where eclipse was started, we can enter the input and java code can read it as string.

acessing source code variables when executable is running in java

I am running a tool named "fio" from my java code using process builder.the tool has its source code in C.i need to get values of some variables from the source code of "fio",when i am running the tool in my java code.I tried to search for the solution but could not find any.
how can i do it?can "environment variables" for processbuilder help?
here is the code i am using
String line=null;
ProcessBuilder pb=new ProcessBuilder("fio","inp.fio");
File f=new File("/home/nikhil/Nikhil");
pb.directory(f);
Process p=pb.start();
InputStream i=p.getInputStream();
InputStreamReader ir=new InputStreamReader(i);
BufferedReader bf=new BufferedReader(ir);
InputStream err=p.getErrorStream();
InputStreamReader rerr=new InputStreamReader(err);
BufferedReader bferr=new BufferedReader(rerr);
I'm going to assume you have access to the code for fio and can rebuild it. One mechanism you could use would be to have fio output the local variable state you are interested in to one of the output streams (stdout or stderr) that you are handling, and parse the values out of it as messages whenever it changes and fio outputs an updated value. That keeps the communication fairly simple.
If you have a lot of complex data, you might want to consider creating a separate communication channel (shared memory, for example, or named pipes, or a socket based connection) for shared state. If you are just interested in some cheap debugging, I'd just go with the first approach by outputting something like
DBG{var1}=<value>
to stderr whenever a value of interest changes, and have your stderr stream handler in Java record the state for use wherever you need it.
I can use "shared memory" to share the variable value with another new C program i wrote,now i can call a function from this new C program that will return me the value of the variable which is "shared" in my java code using JNI.

Why Use java.io.Console?

Just a quick one here.
What are the benefits of using java.io.Console as opposed to using a BufferedReader wrapping an InputStreamReader for System.in?
Why would I use it?
Thanks for any advice!
Because it's code that is already written for you...no need to re-invent the wheel. Chances are, you're not going to get it any better than it already is.
You can use java.io.Console to present an interactive command-line to the user. You could do all that with System.in yourself, but you would have to implement things like noticing when the input was done, or readPassword, etc.
See java.io.Console is finally here!
One of the most popular feature
requests for J2SE in recent times has
been the request to improve console
support and provide a way to enter
passwords with echo disabled.
Developers know this feature 4050435
as it has been skulking in the Top 25
RFEs list for some time.
java.io.Console only works when you start a Java program from a command line without redirecting STDIN/STDOUT.
The main advantage I see with Console over System.in is that you have the readPassword() method, which won't echo the characters typed by the user (I couldn't find a way to do this with System.in).
You also have readLine() which will present a prompt and read a single line. You don't have to create your own LineNumberReader.
But, if you want your Java program to be able to read from STDIN when it's redirected from a file or pipe, you still have to use System.in.
Another trick I'm pretty sure you won't get with Console--I created my own input and output streams and replaced System.in/out with them. My implementation of the stream appended to a log file as well as echoing to the screen.
When I turned on my poor-man's "Debug Info", I could even have it tell me what program/line the sysout came from (It was slow though. It created an exception and examined the appropriate stack entry so it was off by default)
java.io.Console is used to take and read input from the user at runtime and output are displayed after processing the input from user.
For more and detailed information visit https://www.examsmyantra.com/article/58/java/java-io---console-input-and-output

Categories