I have a timer which runs every 20 minutes. The code opens a connection with URLConnection, gets JSON information, and attempts to parse and add the results to a table. This code was working great in my dev (using CodeRunner.sh). Now it has come time to deploy, so I run “deploy.sh”, with no arguments. The timer shows up under the production tab of the interface under timers.
I click the run button, and it says completed successfully. I look at the log date.txt file which is generated. I see my info message print out, but nothing else. I went through and added debug messages at various points in my code. It gets to a certain point and stops. The entire bit of code is in a try-catch block that is logging if an exception is hit. That is never printed. I see no indication of what has happened, but it only gets to until before I call this:
final JSONObject json = new JSONObject(response.toString());
I can’t tell if that is the culprit, or if something else is going on. Since this works in debug mode, and I am definitely getting data from my query (put a debug in, yes it’s added as an approved external host), I am skeptical it’s the code. Thoughts?
Hi Evan,
One of the reasons why the timer may be interrupted is if it takes more than 5 seconds to run. The 5 second limit comes with the free tier of Backendless. It can be extended to 20 seconds by purchasing a function pack from the Marketplace.
Regards,
Mark
I have purchased that add-on from the marketplace. It was taking longer than 5 seconds. But it still doesn’t work. It stops running at the same point. Nothing shows in the log, but it clearly isn’t behaving as it does when running through CodeRunner.
Hi Evan,
Any chance you could benchmark in the local debug mode to see how long (in seconds) the execution takes?
Regards,
Mark
I save the time at the start and end, then print a log at the end with the difference.
Usually about 15 seconds for the whole thing to run, but it stops only after a second or two.
Here is a successful log (running in local debug, not sure if timing is quite the same).
2016-03-18 18:15:26,643 | com.backendless.app.timers.NewsQueryTimerTimer | INFO | QUERY: (Query address)
2016-03-18 18:15:28,136 | com.backendless.app.timers.NewsQueryTimerTimer | INFO | Response from BING okay.
(This is where it stops)
2016-03-18 18:15:28,284 | com.backendless.app.timers.NewsQueryTimerTimer | INFO | Beginning to add stories.
2016-03-18 18:15:28,411 | com.backendless.app.timers.NewsQueryTimerTimer | INFO | Adding article:d76798a9-40c1-4b71-91b2-eb1e73a440e5
.. More stuff
2016-03-18 18:15:33,935 | com.backendless.app.timers.NewsQueryTimerTimer | INFO | Done with query, took 8 seconds.
FYI, here is the code it’s choking on:
@BackendlessTimer("{'startDate':1458324000000,'frequency':{'schedule':'custom','repeat':{'every':1200}},'timername':'NewsQueryTimer'}")
public class NewsQueryTimerTimer extends com.backendless.servercode.extension.TimerExtender
{
@Override
public void execute( String appVersionId ) throws Exception
{
//////// (Query is here)
log.info("Response from BING okay.");
// This message is printed, the next one is not. I believe it's the very next line, but not sure.
// Got stuff, extract the JSON.
final JSONObject json = new JSONObject(response.toString());
final JSONObject d = json.getJSONObject("d");
results = d.getJSONArray("results");
resultsLength = results.length();
int success_count = 0;
// The following line is not called in production:
log.info("Beginning to add stories.");
// Iterate for stories
for (int i = 0; i < resultsLength; i++)
{
...
Any chance you could put the entire body of the method (the code in it) into a “try/catch(Throwable t)” block to see if there are any exceptions which might be occurring?
Yes, I’ve tried that. I did it again to test and it still does the same:
Code:
Added try block immediately after setting up the logger.
Catch block:
catch (Exception e) {
log.warn("Unhandled Exception");
log.warn(e.toString());
}
Log:
2016-03-18 22:10:53,352 | com.backendless.app.timers.NewsQueryTimerTimer | INFO | QUERY: (Query URL here)
2016-03-18 22:10:53,812 | com.backendless.app.timers.NewsQueryTimerTimer | INFO | Response from BING okay.
Could you change the catch block to catch Throwable instead of Exception?
I caught something! Thank you for the tip, I’m new to Java and didn’t realize Exception wasn’t the highest “catch all” type. I did that, and found that org.json wasn’t being built into my project, but my local context must have had the library and allowed it.
If it helps anybody else, this was the error:
java.lang.NoClassDefFoundError org/json/JSONObject
Not directly related, but how long does it take to approve an external host? I did one a while back that only took 12 hours or so, this time it’s been a good 36 and is still pending. I can wait, but I’m just curious for future reference what your typical time is.
As of right now all external URL requests have been approved. If yours has not been approved (or rejected), please contact support@backendless.com and inquire about it.
So this has been working just fine for a few weeks now. And on the 31st of March it stopped working. I removed my timer and re-deployed it. Now all I get is this:
2016-04-02 17:55:38,168 | com.backendless.app.timers.NewsQueryTimerTimer | INFO | Starting Query
2016-04-02 17:55:38,687 | com.backendless.app.timers.NewsQueryTimerTimer | WARN | Unhandled Exception
2016-04-02 17:55:38,695 | com.backendless.app.timers.NewsQueryTimerTimer | WARN | java.lang.NoClassDefFoundError: org/json/JSONObject
2016-04-02 17:55:45,459 | com.backendless.app.timers.NewsQueryTimerTimer | WARN | java.lang.NoClassDefFoundError: org/json/JSONObject
Has something changed on the backend side? Or am I missing something on the upload. I have the java-json.jar in my /libs folder and am using IntelliJ Idea.
Imported with this:
import org.json.JSONArray;
import org.json.JSONObject;
There was a bug (which we have fixed) preventing other jars/libs from being loaded into the service. Could you try again and let us know if it works for you now?