I have a small part of the program that has a timer to take a picture using a usb webcamera through the command line (fswebcam) every 15 minutes.
The code is like this:
public static final String HOME_DIR = System.getProperty("user.home") + "/";
public static final String PGP_DIR = HOME_DIR + "PGP/";
public static final String COLLECTION_DATA_DIR = PGP_DIR + "collectionData/";
public static final String SENSOR_CALIBRATION_DATA = PGP_DIR + "sensorCalibration/";
public static final String PICTURE_DIR = PGP_DIR + "pictures/";
public static final String ALARM_DIR = PGP_DIR + "alarms/";
private class PictureTakerTask extends TimerTask{
Timer t;
public void start(){
if(t != null){
t.cancel();
t.purge();
t = null;
this.cancel();
}
t = new Timer(true);
t.scheduleAtFixedRate(this, 0, 1000 * 60 * 15); //takes a picture every 15 minutes
}
public void stop(){
if(running) return;
if(t != null){
t.cancel();
t.purge();
t = null;
}
this.cancel();
}
#Override
public void run() {
String filename = getPictureFilename();
if(filename == null) return;
Process p;
try {
CommIO.printLog("Taking a picture");
String file;
light.setGreenPWM(80);
p = Runtime.getRuntime().exec("fswebcam -r 1920x1080 --no-banner -S 1 " + filename);
p.waitFor();
System.out.println ("picture taken with exit value: " + p.exitValue());
p.destroy();
light.setGreenPWM(0);
} catch (Exception e) {
e.printStackTrace();
light.setGreenPWM(0);
}
}
private String getPictureFilename(){
//make folder if it doesn't exist already
SimpleDateFormat justDate = new SimpleDateFormat("MM-dd-yy");
String date = justDate.format(new Date());
String s = PICTURE_DIR + date + "/";
File picDir = new File(s);
if(!picDir.exists()){
if(picDir.mkdir()){
Alert alert = new Alert(AlertType.ERROR, "Couldn't make picture directory: " + s, ButtonType.OK);
}
}
//find an unused filename
String picFileName = s + "plant_01.jpg";
File tempFile = new File(picFileName);
int i = 1;
while (tempFile.exists()) { //finds the next nonexistent name for data spreadsheet
String num = i < 10 ? "0" + i : "" + i;
picFileName = s + "plant_" + num + ".jpg";
i++;
tempFile = new File(picFileName);
if(i > 10000) break;
}
return picFileName;
}
}
The thread starts and works fine, until midnight exactly. It will fail to take pictures the next day. I can't figure out for the life of me why it stops. If I stop and restart the task it will work fine again. If I even take a picture through the terminal outside the program it will work fine again. It just will quit taking pictures by the next day. It even creates the next day's folder, just no pictures. No error messages (that I can find).
Does anybody have any ideas or experience with this? Before you say it, no I can't use motion or Cron because I need to be synchronized with the "light" object in the run() function.
Answering my own question. Simple mistake, actually:
if(picDir.mkdir()){
Alert alert = new Alert(AlertType.ERROR, "Couldn't make picture directory: " + s, ButtonType.OK);
}
Forgot the negation of condition. I usually run the program more than once in a day to check other changes, so it makes the folder on the first time, crashes the thread, and runs fine the next couple times I start the program. But when the next day comes around, it makes an Alert and throws a tantrum because it's not on the FX thread. It was difficult to notice because I forgot to actually even show the Alert.
I love java-fx, but it can be so finicky sometimes. Fixed by adding negation, and putting the alert into a Platform.runLater Runnable.
You could try and set the time to 12:00:01am at 11:59:59pm. I'm not sure if that would fix it. A while loop could work.
Related
I have a login page and a sign up page in my program.
I want to run it only if the user says begin.
These pages are called in the main method of my class, and I have a speech recognizer class.
I want the program to continue only when String output.contains("begin") == true
I tried putting the Class.main(args) in my if(output.contains("begin") == true)) case, there was an unhandled exception, and when i surrounded that section with try and catch, it didn't work.
I was told that Inheriting and implementing the classes from my API will work, but I'm not quite sure how to do it.
final Microphone mic = new Microphone(FLACFileWriter.FLAC);
GSpeechDuplex duplex = new GSpeechDuplex("AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw");
duplex.setLanguage("en");
duplex.addResponseListener(new GSpeechResponseListener() {
String old_text = "";
public void onResponse(GoogleResponse gr) {
String output = gr.getResponse();
if (gr.getResponse() == null) {
this.old_text = response.getText();
if (this.old_text.contains("(")) {
this.old_text = this.old_text.substring(0,
this.old_text.indexOf('('));
}
System.out.println("Paragraph Line Added");
this.old_text = ( response.getText() + "\n" );
this.old_text = this.old_text.replace(")", "").replace("( ", "");
response.setText(this.old_text);
}
if (output.contains("(")) {
output = output.substring(0, output.indexOf('('));
}
if (!gr.getOtherPossibleResponses().isEmpty()) {
output = output + " (" + (String)
gr.getOtherPossibleResponses().get(0) + ")";
}
response.setText("");
response.append(this.old_text);
response.append(output);
System.out.println(output);
if(output.contains("begin") == true){
duplex.stopSpeechRecognition();
mic.close();
Trying_Different_Languages t = new Trying_Different_Languages();
frame.dispose();
}
}
});
Expect The program to begin when i say begin but
It it doesn't begin when I say begin.
The try and catch statements just help in error free compilation.
In a program there should exist only 1 public static void main(String[] args) method. That is the indicator which tells you there starts the program.
Instead of calling the main method you should add a different method which do the stuff you want at a specific point.
So in detail it can look like that:
public class SomeClass {
public static void someMethodName() {
//some stuff you want to execute
}
}
So and where you want to execute the code:
...
SomeClass.someMethodName(); //executes the stuff you want.
In this case it would work if you create different methods which do exactly that you need to do at a specific point.
I'm writing a Java program that prints information to a text file as it runs. When testing my program on my Mac in Eclipse, it works properly--both creating the text file and writing to it. I exported my program to a .jar file to test on different computers, and when I run the .jar file on other Mac computers, everything works as it should. However, when I run the program on a Windows computer, a file is created but nothing is written to it. I have searched for Filewriter issues on different operating systems, but haven't come up with anything so far--thoughts?
Below is the code I use to write to the file. It's within a timer task and writes an angle value and a time stamp to the file on each execution. Everything else within the timer task works properly on all operating systems, so that isn't the issue. If it helps, here is an example of a file might look like:
1 270
2 30
3 26
4 29
etc. with the first column containing the time count and the second column containing an angle value.
The code:
public AnAngleTimerTask(Model newModel, int newCounter, int newEndAnalysis,
int newSampleEvery) {
model = newModel;
counter = newCounter;
endAnalysis = newEndAnalysis;
sampleEvery = newSampleEvery;
angles = new int[(int) Math
.floor((endAnalysis - counter) / sampleEvery)];
times = new int[(int) Math.floor((endAnalysis - counter) / sampleEvery)];
file = newFile();
}
#Override
public void run() {
PrintWriter out;
System.out.println(counter);
// get angle and write to file
if (!model.getTimer().getPaused()) {
int usbAngle = retrieveAngle();
times[i] = counter;
angles[i] = usbAngle;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter(file, true)));
out.printf("%-10d %-10d\n", counter, usbAngle);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
model.setAngle(usbAngle);
i++;
counter = counter + sampleEvery;
}
if (counter == endAnalysis) {
model.setMeanAngle(angles);
model.setR(angles);
System.out.println("End Analysis");
cancel();
}
}
public File newFile() {
String nameString;
Date myDate = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd:HH-mm-ss");
String myDateString = sdf.format(myDate);
if (model.getArenaName() == null) {
nameString = "Arena" + model.getName() + "Tracker";
} else {
nameString = model.getArenaName();
}
File file = new File(model.getPath() + "/" + nameString + "_"
+ model.getName() + "_" + myDateString + ".txt");
model.setLastDataRecordedToFile(file.getAbsolutePath());
return file;
}
Please let me know if you need any other information or code for context.
Is the file empty? Or is the output not as expected. Depending on that, changing from
out.printf("%-10d %-10d\n", counter, usbAngle);
to
out.printf("%-10d %-10d%n", counter, usbAngle);
might help. With the first one it sends a raw line feed. Second one does the platform specific conversion and generate a \r\n on windows
PrintWriter swallows exceptions, and you aren't calling checkError() to see if one happened. Try it with a BufferedWriter. You'll have to use something other than printf() of course.
After some trial and tribulation, I discovered that the issue was actually that I was using a file name with a colon in it (generated by the SimpleDateFormat), which is permitted on Macs but not on Windows. Got rid of the colon and everything works as it should!
I am a newbie in Java but I need to make a scanner (that has a built in ocr) output some content to a browser. I haven't gotten to the browser yet, but the code works when I run it as an application.
With the scanner, I received Java code that makes the scanner take a picture, then read from it and output it back to the console. I added a few lines to make it an applet:
import gx.*;
import pr.*;
import java.applet.*;
public class DocScan extends Applet
{
/**
*
*/
private static final long serialVersionUID = 1L;
static
{
try
{
System.loadLibrary("jgx");
System.loadLibrary("jpr");
}
catch (UnsatisfiedLinkError e)
{
System.err.println("Native code library failed to load." + e);
System.exit(1);
}
}
public static void main(String argv[])
{
Lib lib = new Lib();
String text;
String[] ec ={ "Ok", "Warning", "Error" };
try
{
/* Opening the PR system */
lib.FunctionStart("Opening system files");
PassportReader pr = new PassportReader(); /* Object for the PR system */
lib.FunctionEnd();
/* Validity check */
if (!pr.IsValid())
{
lib.Error("Failed to initialize!");
lib.PrintStat();
}
/* Connecting to the first device */
lib.FunctionStart("Connecting to the first device");
pr.UseDevice(0, jpr.PR_UMODE_FULL_CONTROL);
lib.FunctionEnd();
/* Using the device */
while (!lib.KbHit())
{
lib.ProcessStart("Processing document");
try
{
/* Capturing images */
lib.FunctionStart("Capturing images");
pr.Capture();
lib.FunctionEnd();
/* Getting document data */
lib.FunctionStart("Recognizing.");
prDoc doc = pr.Recognize(0);
lib.FunctionEnd();
if (!doc.IsValid()) lib.WriteLine("No data found.");
else
{
/* Displaying document type */
lib.WriteLine("Document type: " + doc.Code() + ", status: " + ec[doc.Status() / 100]);
/* Get some fixed fields and displaying them */
text = doc.Field(jpr.PR_DF_NAME);
if (!text.equals("")) lib.WriteLine("NAME \"" + text + "\" [" + ec[doc.FieldStatus(jpr.PR_DF_NAME) / 100] + "]");
text = doc.Field(jpr.PR_DF_DOCUMENT_NUMBER);
if (!text.equals("")) lib.WriteLine("DOCUMENT NUMBER \"" + text + "\" [" + ec[doc.FieldStatus(jpr.PR_DF_DOCUMENT_NUMBER) / 100] + "]");
text = doc.Field(jpr.PR_DF_EXPIRY_DATE);
if (!text.equals("")) lib.WriteLine("EXPIRY DATE \"" + text + "\" [" + ec[doc.FieldStatus(jpr.PR_DF_EXPIRY_DATE) / 100] + "]");
/* Searching for fields and displaying them */
gxVariant pdoc = doc.ToVariant();
gxVariant fieldlist = new gxVariant();
pdoc.GetChild(fieldlist, jgx.GX_VARIANT_BY_ID, jpr.PRV_FIELDLIST, 0);
int nitems = fieldlist.GetNItems();
for (int i = 0; i < nitems; i++)
{
gxVariant field = new gxVariant();
fieldlist.GetItem(field, jgx.GX_VARIANT_BY_INDEX, 0, i);
int field_code = field.GetInt();
text = doc.Field(field_code);
if (!text.equals("")) lib.WriteLine("[" + field_code + "] \"" + text + "\" [" + ec[doc.FieldStatus(field_code) / 100] + "]");
if (field_code >= jpr.PR_DF_FORMATTED) continue;
try
{
gxImage img = doc.FieldImage(field_code);
if (img.IsValid()) img.Save(field_code + ".jpg", jgx.GX_JPEG);
}
catch (RuntimeException e)
{
lib.DisplExcp(e);
}
}
}
}
catch (RuntimeException e)
{
lib.DisplExcp(e);
}
lib.ProcessEnd();
lib.WaitForSec(3);
}
/* Closing the device */
lib.FunctionStart("Closing the device");
pr.CloseDevice();
lib.FunctionEnd();
}
catch (RuntimeException e)
{
lib.DisplExcp(e);
}
lib.PrintStat();
}
}
I am using Eclipse as an IDE. Right now my goal is to simply make the scanner "flash". I know that the output is to the console and I will not see anything from it in an applet, but it should still flash.
When I run this code as an application, it works. The scanner takes a picture and then it outputs what it has read to the console.
When I run this code as an Applet, the applet starts and does nothing. It just stays there with no errors of any kind (at least that's what Eclipse is showing me).
I read that I should allow the applet accesss, so I edited:
c:\program files\java\jre8\lib\security\java.policy
and added this at the end:
grant {
permission java.security.AllPermission;
};
Which should allow applets full access. However, there is no change - the applet still launches and does nothing.
Can anyone point me in the right direction? Why is the code not working when I run it as an applet?
I have an app that created multiple endless threads. Each thread reads some info and I created some tasks using thread pool (which is fine).
I have added additional functions that handle arrays, when it finishes, its send those ArrayLists to new thread that save those lists as files. I have implemented the saving in 3 ways and only one of which succeeds. I would like to know why the other 2 ways did not.
I created a thread (via new Thread(Runnable)) and gave it the array and name of the file. In the thread constructor I create the PrintWriter and saved the files. It ran without any problems. ( I have 1-10 file save threads runing in parallel).
If I place the save code outputStream.println(aLog); in the Run method, it never reaches it and after the constructor finishes the thread exit.
I place the created runnables (file save) in a thread pool (and code for saving is in the run() method). When I send just 1 task (1 file to save), all is fine. More than 1 task is being added to the pool (very quickly), exceptions is created (in debug time I can see that all needed info is available) and some of the files are not saved.
Can one explain the difference behavior?
Thanks
Please see code below. (starting with function that is being part of an endless thread class that also place some tasks in the pool), the pool created in the endless thread:
ExecutorService iPool = Executors.newCachedThreadPool();
private void logRate(double r1,int ind){
historicalData.clear();
for (int i = 499; i>0; i--){
// some Code
Data.add(0,array1[ind][i][0] + "," + array1[ind][i][1] + "," +
array1[ind][i][2] + "," + array1[ind][i][3] + "," +
array2[ind][i] + "\n" );
}
// first item
array1[ind][0][0] = r1;
array1[ind][0][1] = array1[ind][0][0] ;
array1[ind][0][2] = array1[ind][0][0] ;
array2[ind][0] = new SimpleDateFormat("HH:mm:ss yyyy_MM_dd").format(today);
Data.add(0,r1+","+r1+","+r1+","+r1+ "," + array2[ind][0] + '\n') ;
// save the log send it to the pool (this is case 3)
//iPool.submit(new FeedLogger(fName,Integer.toString(ind),Data));
// Case 1 and 2
Thread fl = new Thread(new FeedLogger(fName,Integer.toString(ind),Data)) ;
}
here is the FeedLogger class:
public class FeedLogger implements Runnable{
private List<String> fLog = new ArrayList<>() ;
PrintWriter outputStream = null;
String asName,asPathName;
public FeedLogger(String aName,String ind, List<String> fLog) {
this.fLog = fLog;
this.asName = aName;
try {
asPathName = System.getProperty("user.dir") + "\\AsLogs\\" + asName + "\\Feed" + ind
+ ".log" ;
outputStream = new PrintWriter(new FileWriter(asPathName));
outputStream.println(fLog); Case 1 all is fine
outputStream.flush(); // Case 1 all is fine
outputStream.close(); Case 1 all is fine
}
catch (Exception ex) {
JavaFXApplication2.logger.log(Level.SEVERE, null,asName + ex.getMessage());
}
}
#Override
public void run()
{
try{
outputStream.println(fLog); // Cas2 --> not reaching this code, Case3 (as task) create
exception when we have multiple tasks
outputStream.flush();
}
catch (Exception e) {
System.out.println("err in file save e=" + e.getMessage() + asPathName + " feed size=" +
fLog.size());
JavaFXApplication2.logger.log(Level.ALL, null,asName + e.getMessage());
}
finally {if (outputStream != null) {outputStream.close();}}
}
}
You need to call start() on a Thread instance to make it actually do something.
I have written a program to monitor the status of some hard drives attached to a RAID on Linux. Through this program I execute several command line commands. An interesting error occurs though....the program runs for a good three minutes before it seems that it can no longer correctly execute the command it had been previously executing (for many iterations).
It spits out an array index error (my variable driveLetters[d]) because it appears to miss the drive somehow (even though it found it hundreds of times before).
Other things to note...if I tell it to reset int "d" to "0" if it exceeds the number of drives...the program won't crash and instead will just become stuck in an infinite loop.
Also, the time at which the program crashes varies. It doesn't appear to crash after a set number of intervals. Finally, I don't get any kind of memory leak errors.
Here is some of code that should reveal the error:
public static void scsi_generic() throws IOException, InterruptedException
{
int i =0;
int d =0;
int numberOfDrives = 8;
char driveLetters[] = {'b','c','d','e','f','g','h','i','j','k','l','m'};
String drive = "";
while (i <= numberOfDrives)
{
System.out.println("position 1");
List<String> commands = new ArrayList<String>();
commands.add("cat");
commands.add("/sys/class/scsi_generic/sg"+i+"/device/sas_address");
SystemCommandExecutor commandExecutor = new SystemCommandExecutor(commands);
int driveFound = commandExecutor.executeCommand();
if (driveFound == 0)
{
System.out.println("Folder: sg" + i + " was found." );
StringBuilder stdout = commandExecutor.getStandardOutputFromCommand();
String data = stdout.toString();
String sas = data.substring(11,12);
int sasA = Integer.parseInt(sas,16);
boolean matchedSG = false;
while (matchedSG == false)
{
System.out.println("position2");
List<String> lookSD = new ArrayList<String>();
lookSD.add("test");
lookSD.add("-d");
lookSD.add("/sys/class/scsi_generic/sg"+i+"/device/block:sd" + driveLetters[d]);
SystemCommandExecutor commandSearch = new SystemCommandExecutor(lookSD);
int sdFound = commandSearch.executeCommand();
StringBuilder stdout3 = commandSearch.getStandardOutputFromCommand();
StringBuilder stderr = commandSearch.getStandardErrorFromCommand();
String sdFound2 = stdout3.toString();
if (sdFound == 0)
{
matchedSG = true;
System.out.println("Found the SD drive.");
drive = "sd"+driveLetters[d];
System.out.println(sasA);
hdsas.set(sasA , sas);
d = 0;
i++;
loadDrives(drive , sasA);
}
/* else if (sdFound != )
{
System.out.println("Error:" + sdFound);
System.out.println(d+ " "+ i);
}
*/
else if ( d >= 8)
{
System.out.println("Drive letter: " + driveLetters[d]);
System.out.println("Int: " + i);
// System.out.println(sdFound2);
System.out.println("sd error: "+ sdFound);
// System.out.println(stderr);
//System.out.println(sdFound2 + " m");
}
else
{
d++;
}
}
}
else
{
System.out.println("Folder: sg" + i + " could not be found.");
i++;
}
d =0;
}
}
Any help or suggestions would be awesome! Thanks.
EDIT:
The solution I found was to use the java library for testing if a directory exists rather than doing it through the linux command line.
Ex:
File location = new File("directory");
if (location.exists())
{
}
No idea why it works and doesn't crash, where as the linux command line did after a short period of time, but it does.
This is no direct answer to your question, but it still might help you:
I often have to find bugs in code like yours (very long methods with "global" variables, that is, variables declared at the beginning of a method and used all over then). Just by refactoring the code properly (short methods with a single purpose each), the cause of the bug becomes immediately visible to me and is fixed within a second (while the refactoring itself takes much longer).
I guess that's what everyone trying to offer you help is doing anyway: Refactor your code (probably only in one's head) so that is (much) more easy to understand what's going on.
The solution I found was to use the java library for testing if a directory exists rather than doing it through the linux command line.
Ex:
File location = new File("directory");
if (location.exists())
{
}
No idea why it works and doesn't crash, where as the linux command line did after a short period of time, but it does.