I've a very annoying problem and I'm not able to fix this by myself.
I have a simple JavaFX Scene with just 2 buttons for start and killing the thread. The stop-action is not relevant in this case because I'm not able to get the thread working well. The actionListener looks like:
EDIT1: Figured out the problem, it's not thread specific, it's the request against the TimeServer, take a look here: answer
Thanks to everyone of you who answered this or read the question! :)
private FarmAction action = null;
@FXML
void btnStartListener(ActionEvent event) {
Firefox ff = new Firefox();
ff.startBrowser();
BrowserAction browserAction = new BrowserAction(ff.getDriver(), ff.getJse());
browserAction.loginToGame(user, pass);
ObservableList<AttackCommand> list = (ObservableList<AttackCommand>) Serializer.deserialize(Constants.FILE_NAME_TESTPURPOSE);
if(action == null)
action = new FarmAction(ff.getDriver(), ff.getJse(), list);
Thread run = new Thread(action);
try {
run.start();
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
}
Note: I'm working with the Selenium Framework to automate some clicks on a Website.
My FarmAction class looks like this:
public class FarmAction implements Runnable{
private WebDriver driver;
private JavascriptExecutor jse;
private ObservableList<AttackCommand> attackList;
private boolean stop = false;
public FarmAction(WebDriver driver, JavascriptExecutor jse, ObservableList<AttackCommand> attackList) {
this.driver = driver;
this.jse = jse;
for(AttackCommand ac : attackList)
{
ac.transferFromPropToAttributes();
}
this.attackList = attackList;
}
@Override
public void run() {
ArrayList<Integer> unitIds = Constants.UNIT_ID_LIST_ALL;
if(!driver.getCurrentUrl().equals(Constants.URL_TESTPURPOSE))
driver.navigate().to(Constants.URL_TESTPURPOSE);
int count = 0;
while(true) { // Just let the Thread run for duration = lifetime of application
System.out.println(count++); //count how often the thread runs into this while loop before terminating for no reason
for(AttackCommand ac : attackList) {
for(int i = 0; i < unitIds.size(); i ++) {
int unitKey = unitIds.get(i); // Momentane UnitID der Iteration
if(ac.getUnits().containsKey(unitKey) && ( ac.getTurnBackTime() == 0 ||ac.getTurnBackTime() <= DateUtil.getActualServerTime())) // getActualServerTime is request against the timeserver de.pool.ntp.org
{
String textfieldName = Constants.HASHMAP_TEXTFIELD_NAME_ALL_HTML_PLACE.get(unitKey);
WebElement textfield = driver.findElement(By.name(textfieldName));
textfield.sendKeys(String.valueOf(ac.getUnits().get(unitKey)));
WebElement textfieldCoordinates = driver.findElement(By.name(Constants.TEXTFIELD_NAME_HTML_PLACE_COODRINATESFORTARGET));
textfieldCoordinates.sendKeys(StringHelper.getPointAsString(new Point(ac.getXCoordinates(), ac.getYCoordinates())));
WebElement submitButton = driver.findElement(By.id(Constants.TA));
submitButton.click();
WebElement sndAttackSubmitButton = driver.findElement(By.name(Constants.SBM));
WebElement span = driver.findElement(By.className(Constants.CLASSNAME_TIME));
long duration = Long.parseLong(span.getAttribute(Constants.ATTRIBUTE_DURATION));
sndAttackSubmitButton.click();
ac.setStartTime(DateUtil.getActualServerTime());
ac.setDurationInSeconds(duration*1000);
ac.setTurnBackTime(ac.getStartTime()+ac.getDurationInSeconds());
}
}
}
}
}}
As you see I've wrapped the Thread.start() method into a try-catch for Throwables AND Exceptions but I don't get any Stacktrace if the thread stops for no reason. I expected an StackOverFlow Error but I don't catch anything.
The amount of loops my thread is working is very different. Sometimes it stops after 12, then other times after 370 or 59. All values are examples - it's different each time.
Do you have any Ideas what I'm doing wrong?
Thanks in advance!
OK guys, I've figuered the problem out. It's not thread specific, sorry for that, but I've learned almost a bit more about threads because of your answers :) Thanks to everyone of you!
I've put SystemOuts behind every single codeline and figured out after 25 runs and freezes there are two possible codelines where thread stops working:
Both statements use my DateUtil.getActualServerTime()
Method which looks as follows:
public static long getActualServerTime() {
String TIME_SERVER = "de.pool.ntp.org";
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress;
long returnTime = 0;
try {
inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
return returnTime;
}
I'm using the apache.commons.net lib for that.
If I'm just return a
Date d = new Date(); return d.getTime();
my thread works fine for about 60.000 loops until I've stopped it manually.
I don't get an Exception or Throwable here as well. I'd say theres a maximum amount of request against the time server in a specific time or something like that. I can't figure it out on the Website right now.