I am using a Java Project that gives an user interface for doing some user events. It is not being executed as Runnable thread in main() as in most Swing/Gui applications. Rather it has several class and form files in the source code and is run from command line using another Java program.
But when I am trying to read a certain file by clicking on some input button, the system fails to read the file. The system writes the custom error message into a file named log.txt saved within the project folder.
I have tried
1. Setting breakpoints (the application does not stop at breakpoint)
2. Doing console prints i.e. System.out.println (there is no print on console)
So both the ways of debugging has failed. I am using Eclipse 3.5.2 SDK (Galileo). How can I debug the user events on my applicattion?
The outline of the source class DataImportPanel in project DDMT is listed below. It is giving an exception in the method DataImportPanel.openHeteroFile(File).
DDMT.core.DataImportPanel
...
DDMT.core.DataImportPanel.heteroDistributionModel
...
DDMT.core.DataImportPanel.initComponents()
DDMT.core.DataImportPanel.initComponents().new ActionListener() {...}
...
DDMT.core.DataImportPanel.initComponents().new MouseAdapter() {...}
DDMT.core.DataImportPanel.initComponents().new ActionListener() {...}
DDMT.core.DataImportPanel.jButton2ActionPerformed(ActionEvent)
...
DDMT.core.DataImportPanel.jButton3ActionPerformed(ActionEvent)
DDMT.core.DataImportPanel.openHeteroFile(File)
DDMT.core.DataImportPanel.jButton8ActionPerformed(ActionEvent)
DDMT.core.DataImportPanel.openFile(File)
DDMT.core.DataImportPanel.jButton15ActionPerformed(ActionEvent)
DDMT.core.DataImportPanel.jRadioButton1ActionPerformed(ActionEvent)
DDMT.core.DataImportPanel.buttonGroup1
...
DDMT.core.DataImportPanel.jButton8
DDMT.core.DataImportPanel.jButton9
DDMT.core.DataImportPanel.jLabel1
...
DDMT.core.DataImportPanel.jList1
...
DDMT.core.DataImportPanel.jPanel1
...
DDMT.core.DataImportPanel.jRadioButton1
...
DDMT.core.DataImportPanel.jScrollPane1
...
DDMT.core.DataImportPanel.jTabbedPane1
DDMT.core.DataImportPanel.DistributionTypes
DDMT.core.DataImportPanel.DoubleCellRenderer
Here is the openHeteroFile which is throwing the Data Import exception
private void openHeteroFile(File f)
{
File file = null;
try{
file = f;
file.createNewFile();
FileReader reader = new FileReader(file);
BufferedReader bReader = new BufferedReader(reader);
//The vector that holds the number of columns
attributeNames = new ArrayList<String>();
//Read in the number of pairs
String line = bReader.readLine();
//load the file
heteroDistributionModel = new DefaultListModel();
line = bReader.readLine();
while( line != null )
{
//Set up the RegEx matches
heteroDistM = heteroDistP.matcher(line);
firstM = firstP.matcher(line);
firstM.find();
String output1 = firstM.group()+" (";
for( int j = 0; j< nodeTypes[0].length; j++)
{
if( controlClass.nodes[Integer.parseInt(firstM.group())].getNodeType().equals( nodeTypes[1][j]) )
{
output1 = output1+nodeTypes[0][j]+")";
}
}
String output2 = new String();
while( heteroDistM.find() )
{
attributeNames.add(heteroDistM.group(1));
output2 = output2 + " "+heteroDistM.group(1);
}
heteroDistributionModel.addElement(new String[]{output1, output2});
line = bReader.readLine();
}
for (String attr : attributeNames)
System.out.println(attr); //debug
jList3.setModel(heteroDistributionModel);
jList3.setCellRenderer(new DoubleCellRenderer());
bReader.close();
reader.close();
}catch(IOException ex)
{
controlClass.showError("Data Import: Error: File "+file.getPath()+" is not a valid Heterogeneous data file!");
}catch(Exception ex)
{
ex.printStackTrace(); //debug
controlClass.showError("Data Import: Error: Unknown problem reading file "+file.getPath()+"!");
}
}
There is a little green ladybug right next to the run button that starts the debugger.
I would make sure the proper calls are being made. Also check your brackets, breaks, and returns to make sure the code is actually being read. Please post a SSCCE (Short, Self Contained, Correct Example) so we can view your code to help you out better.
Edit (after OP added some code)
I'm pretty sure your issue is where you file.createNewFile();
Related
I am trying to create an authentication system of sorts that uses a file called Users.dat to store user data. Currently, I am developing a method to remove users by rewriting the Users.dat file, omitting the user specified. The code below works in a basic environment with an all-encompassing directory containing the .java files and the Users.dat file in the same spot. The old Users.dat file is deleted and Users.dat.tmp is renamed to User.dat. (No problems here, everything works as intended).
public static boolean RemoveUser(String userName) {
// TODO remove username from Users.dat
try {
File originalFile = new File("Users.dat");
System.out.println(originalFile.getAbsolutePath());
BufferedReader read = new BufferedReader(new FileReader("Users.dat"));
String line = null;
while ((line = read.readLine()) != null) {
if (line.indexOf(userName) != -1) {
break;
}
}
String[] userInfo = line.split(", ");
if (!userName.equals(userInfo[2])) {
System.out.println("Username not found. No users removed.");
read.close();
return false;
}
File tempFile = new File(originalFile.getAbsolutePath() + ".tmp");
PrintWriter print = new PrintWriter(new FileWriter(tempFile));
String lineToRemove = line;
BufferedReader read2 = new BufferedReader(new FileReader("Users.dat"));
while ((line = read2.readLine()) != null) {
if (!line.trim().equals(lineToRemove)) {
print.println(line);
print.flush();
}
}
print.close();
read.close();
read2.close();
System.out.println(originalFile.getAbsolutePath());
originalFile.delete(); //This line is not executing correctly
tempFile.renameTo(originalFile); //Nor is this line
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return true;
}
Users.dat file format:
Joe, Last, jlast, 58c536ed8facc2c2a293a18a48e3e120, true
Sam, sone, samsone, 2c2a293a18a48e3e12058c536ed8facc, false
Jane, Best, jbest, 293a18a48e3e12052058c536ed8facc2c, false
Andrew, Estes, Aestes, 63a490d69aa544fd1272a976014ad570, true
Test, User, tuser, 63a490d69aa544fd1272a976014ad570, true
I have two System.out.println(originalFile.getAbsolutePath()) statements, one at the beginning, one at the end to make sure the path isn't getting screwed up in the process of everything somehow.
Like I said, the code works, however, when I try to implement it in my project, it creates the Users.dat.tmp and it writes the correct data to it, but it does not delete the old Users.dat file, nor does it rename the Users.dat.tmp file to replace Users.dat. I'm certain the directory is correct, as I am literally displaying it as the code executes. I can't figure out any other reason why originalFile.delete() and tempFile.renameTo(originalFile) aren't functioning properly.
EDIT:
Using java.nio.file, I was able to produce an error message. it reads:
java.nio.file.FileSystemException: C:\Path\Users.dat: The process cannot access the file because it is being used by another process.
I don't have the file open when this error message is shown, and I don't get this error using java.nio in my testing environment mentioned at the beginning. I'm not sure what other process the message is referring to.
EDIT 2:
I tried running the code on other machines, one a Mac, the other a Windows laptop, and the code functioned on the Mac just fine, but I was still seeing the same issue on the Windows laptop.
I had the similar issue. My problem was not closing all the streams I read and written to the file. Thanks for your Edit #1, that was helpful
When you wrap
BufferedReader read = new BufferedReader(new FileReader("Users.dat"));
don't you need to close the inner readers too?
If not for the author, but for those who stambled upon this question (like me), hope this suggestion will be useful
I had an earlier function that I was calling in main that was accessing Users.dat, but I never closed the BufferredReader in that function.
Currently working on a project which requires me to read in file input of over 50k lines. I am currently using the BufferedReader class to read in the input and present the data in a text area. Currently, the application just reproduces the file in my own HMI similar to a text editor, however where I would like to differ is that there are certain starting words for each line that I would like to not be presented in the text area... I believe my lack of experience with buffers is responsible for my problems. I have tried implementing code along the following lines:
private void insertSyrFile(BufferedReader buffer, JFileChooser chooser) throws IOException{
String line;
//reader = "\n";
try{
reader = new FileReader(chooser.getSelectedFile().toString());
buffer = new BufferedReader(reader);
while ((line = buffer.readLine()) != null){
if (!line.startsWith("Elaborating"))
origSyrTextFeild.read(buffer, null);
}
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
This code was implemented with the following button event handler:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);
syrFile.openFile(chooser.getSelectedFile().toString());
try {
insertSyrFile(buffer, chooser); //origSyrTextFeild.setText(syrFile.readFileLine());
} catch (IOException ex) {
Logger.getLogger(ParsingAppMainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
... using this code, even though I have if statement to check for a string, the original file is still reproduced with no processing on the file. I am still a beginner in java, however if someone understands what my goal is and has any insight I'd appreciate any ideas!!
I guess you may use " origSyrTextFeild.append(line);" instead of " origSyrTextFeild.read(buffer, null);". Because the if statement checks the "line" but "read" method get contents from the original buffer.
I am trying to make a method that reads words from a file and saves them in a string named common.
After this, it should compare the words in common to the words in a list of strings (not an ArrayList) and remove any of the nodes in the list that appear in the file (or the string common).
When I compile this program, it works fine. It also runs. However, for some reason, it just skips over the while loop.
private void removeCommonEnglishWords() {
Scanner infile = null;
try {
infile = new Scanner( new FileInputStream( "filename" ) );
} catch(Exception e) {
System.out.println("Nope");
}
String common = "";
while (infile.hasNext()) {
common = common + infile.next() + " ";
}
for (int k = 0; k < terms.size(); k++) {
if (common.contains(terms.get(k))) {
terms.remove(k);
}
}
}
If it's skipping over the while loop, then that means your only possible problem is "infile" is not getting defined, and it is either null from your initialization, or it is simply empty.
Actually, from looking at this code snibbit, that would make sense. Above in your code this is the only thing that is running in your try block:
try {
infile = new Scanner( new FileInputStream( "filename" ) );
}
// By the way you should use this instead
try( /*initialized resources here */ ) {
//Do work here
}
All your work needs to be inside this try block. This is because if something were to happen with the input stream, or your code fires an exception, it needs to be properly handled. The try (with resources) block I mentioned above automatically tries closing your declared resources directly after the try block, before the code execution continues. This is mainly a security reason, so other users can't get a hold of your resource and manipulate it.
For instance your code block might look something like the bellow (I'm putting dummy example code here):
try ( FileOutputStream fos = new FileOutputStream("server/file.txt")) {
// Do work.
byte[] byteArray = new byte[9]();
fos.write(byteArray);
// Try with resources block will automatically try closing the resources,
//but if there are any errors, they are suppressed. You can still print the
//supressed errors, but you will have to write extra code for this.
} catch(Exception e) {
// Always print out logs, so you know what went wrong!
e.printStackTrace();
System.out.println("Whoops! There was an error, please fix.");
}
Here is the docs on try with resources, if you want to read more :)
Also, you didn't specify anything about the file name, but are you sure you have the right path to your file?
I have a project where program has to open notepad file and after entering text and saving that notepad file program should display number of words in that file and it should delete the entered content in the file.
iam getting this error Error not derjava.lang.NullPointerException after running the program.
though after entering some text in Mytext.txt and saving it?
my question is why BufferedReader is reading empty file even though iam saving the file with some content.
Appreciate the help..
public class Notepad_Example {
public static void main(String[] jfb) {
try {
ProcessBuilder proc = new ProcessBuilder("notepad.exe", "C:\\Java Projects\\Reverse String\\src\\Mytext.txt");
proc.start();
BufferedReader br;
String s;
br = new BufferedReader(new FileReader("C:\\Java Projects\\Reverse String\\src\\Mytext.txt"));
s = br.readLine();
char c[] = new char[s.length()];
int j = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != ' ') {
c[i] = s.charAt(i);
} else {
j++;
}
}
System.out.println("number of words are " + (j + 1));
br.close();
} catch (Exception hj) {
System.out.println("Error not der" + hj);
}
try {
FileWriter fw = new FileWriter("C:\\Java Projects\\Reverse String\\src\\Mytext.txt");
fw.close();
} catch (Exception hj) {
System.out.println("Error not der" + hj);
}
}
}
The issue you are having is here:
ProcessBuilder proc=new ProcessBuilder("notepad.exe","C:\\Java Projects\\Reverse String\\src\\Mytext.txt");
proc.start();
proc.start() is returning the freshly started process. You'll have to give the user the chance to edit and save the file and close the editor before you can read from that file. That is you have to wait for that process to finish before you can start using the results (the saved file) of that process.
So do instead something like this:
Process process = proc.start();
int result = process.waitFor();
if (result == 0) {
// Do your rest here
} else {
// give error message as the process did not finish without error.
}
Some further remarks:
The rest of your code also appears to have some issues.
You are only reading one line of that file. What if the user is using new lines?
The exception handling is not very good, at the very least print the stack trace of the exception which will give you further hints of where an exception was occuring
If you are using Java 7, read on try with resources; if you are using Java 6, add finally blocks to make sure your resources (the streams) are getting closed.
When you run proc.start(); it is not going to block and waitfor the process to end, it will continue running.
You will need to call the proc.waitFor() method, to block until it has finished.
NOTE
we have had some weird behaviour when using the process builder...
we used to start the process with a
new ProcessBuilder("notepad.exe", "C:\\Java Projects\\Reverse String\\src\\Mytext.txt");
but that started to fail wen we upgraded to Win7 and Java7 - we we not sure where this problem really originated, but we changed out Code like this:
String[] cmd = new String[]{"notepad.exe", "C:\\Java Projects\\Reverse String\\src\\Mytext.txt"};
new ProcessBuilder(cmd);
and since then it worked correct!
I would like to call an R script from Java. I have done google searches on the topic, but almost all of the results I have seen would require me to add a dependency to some third party library. Can anyone show me a good way to accomplish the same thing without adding any dependencies to my code?
I am using a windows machine, so perhaps I might use the command line to start R (if it is not already open) and to run a specific R script. But I have never written command line code (or called it from Java) so I would need code examples.
I am including working sample code that I wrote for one possible approach below, using my command line idea. In my in-line-comments below, you can see that Step Three in AssembleDataFile.java is intentionally left blank by me. If you think that you can make the command line idea work, then please show me what code to write in Step Three.
Also, feel free to suggest another approach that, hopefully, does not involve adding any more dependencies to my code.
And, as always, I very much appreciate any links you might post to articles/tutorials/etc related to this question.
Here is what I have so far:
AssembleDataFile.java
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
public class AssembleDataFile {
static String delimiter;
static String localPath = "C:\\test\\cr\\";
static String[][] myDataArray;
public static void main(String[] args) {
String inputPath = localPath+"pd\\";
String fileName = "MSData.txt";
delimiter = "\\t";
// Step One: Import data in two parts
try {
// 1A: get length of data file
BufferedReader br1 = new BufferedReader(new FileReader(inputPath+fileName));
int numRows = 0;
int numCols = 0;
String currentRow;
while ((currentRow = br1.readLine()) != null) {
numRows += 1;
numCols = currentRow.split(delimiter).length;}
br1.close();
//1B: populate data into array
myDataArray = new String[numRows][numCols+1];
BufferedReader br2 = new BufferedReader(new FileReader(inputPath+fileName));
String eachRow;
int rowIdx = 0;
while ((eachRow = br2.readLine()) != null) {
String[] splitRow = eachRow.split(delimiter);
for(int z = 0;z < splitRow.length;z++){myDataArray[rowIdx][z] = splitRow[z];}
rowIdx += 1;}
br2.close();
// Step Two: Write data to csv
String rPath = localPath+"r\\";
String sFileName = rPath+"2colData.csv";
PrintWriter outputWriter = new PrintWriter(sFileName);
for(int q = 0;q < myDataArray.length; q++){
outputWriter.println(myDataArray[q][8]+", "+myDataArray[q][9]);
}
outputWriter.close();
//Step Three: Call R script named My_R_Script.R that uses 2ColData.csv as input
// not sure how to write this code. Can anyone help me write this part?
// For what it is worth, one of the R scripts that I intend to call is included below
//
//added the following lines here, per Vincent's suggestion:
String rScriptFileName = rPath+"My_R_Script.R";
Runtime.getRuntime().exec("mypathto\\R\\bin\\Rscript "+rScriptFileName);
//
//
//Step Four: Import data from R and put it into myDataArray's empty last column
try {Thread.sleep(30000);}//make this thread sleep for 30 seconds while R creates the needed file
catch (InterruptedException e) {e.printStackTrace();}
String matchFileName = rPath+"Matches.csv";
BufferedReader br3 = new BufferedReader(new FileReader(matchFileName));
String thisRow;
int rowIndex = 0;
while ((thisRow = br3.readLine()) != null) {
String[] splitRow = thisRow.split(delimiter);
myDataArray[rowIndex][numCols] = splitRow[0];
rowIndex += 1;}
br3.close();
//Step Five: Check work by printing out one row from myDataArray
//Note that the printout has one more column than the input file had.
for(int u = 0;u<=numCols;u++){System.out.println(String.valueOf(myDataArray[1][u]));}
}
catch (FileNotFoundException e) {e.printStackTrace();}
catch (IOException ie){ie.printStackTrace();}
}
}
My_R_Script.R
myCSV <- read.csv(file="2colData.csv",head=TRUE,sep=",")
pts = SpatialPoints(myCSV)
Codes = readShapeSpatial("mypath/myshapefile.shp")
write.csv(ZipCodes$F[overlay(pts,Codes)], "Matches.csv", quote=FALSE, row.names=FALSE)
EDIT:
Here is the error message that is being thrown when I add Runtime.getRuntime().exec("Rscript "+rScriptFileName); to the code above:
java.io.IOException: Cannot run program "Rscript": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at AssembleDataFile.main(AssembleDataFile.java:52)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
... 5 more
SECOND EDIT:
The code above now works because I followed Vincent's suggestions. However, I had to put in a sleep command in order to give the R script enough time to run. Without the sleep command, the java code above throws an error saying that the Matches.csv file does not exist. I am concerned that a 30 second sleep period is too rough of an instrument. Can anyone show me code that gets the java program to wait until the R program has a chance to create Matches.csv? I hesitate to use thread tools because I have read that poorly designed threads can cause bugs that are nearly impossible to localize and fix.
You just want to call an external application: wouldn't the following work?
Runtime.getRuntime().exec("Rscript myScript.R");
You can easily adapt this code: http://svn.rforge.net/org/trunk/rosuda/REngine/Rserve/test/StartRserve.java
Among other things it finds R and runs a fixed script in R - you can replace that script with with your script and ignore the last two methods.
Do not wait for the process to finish with Thread.sleep()...
Use the waitFor() method instead.
Process child = Runtime.getRuntime().exec(command, environments, dataDir);
int code = child.waitFor();
switch (code) {
case 0:
//normal termination, everything is fine
break;
case 1:
//Read the error stream then
String message = IOUtils.toString(child.getErrorStream());
throw new RExecutionException(message);
}
BufferedReader reader = null;
Process shell = null;
try {
shell = Runtime.getRuntime().exec(new String[] { "/usr/bin/Rscript", "/media/subin/works/subzworks/RLanguage/config/predict.R" });
reader = new BufferedReader(new InputStreamReader(shell.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
...would require me to add a dependency to some third party library...
Why is that so bad? You make it sound like "...would require me to assault a honeybadger with a baseball bat..." I don't see the harm, especially if it works.
Maybe RCaller can help you. No JNI required.