I am using objectify as an interface to the GAE datastore and am wondering how I can detect when a transaction fails. That is, when you call
ofy().transact(new VoidWork() {
public void vrun() {
//save entity, this may throw - concurrent modification exception
}
});
If an exception is thrown, the vrun() method is called again. I would like to log when this happens. I have tried many things - surrounding the contents of vrun() with a try/catch, passing a reference to a boolean flag, etc. But this does not appear to work. Any ideas where I might be going wrong?
I need to be able to programmatically detect if the transaction failed , and have some code execute before it is reattempted.
Use the overload for transactNew() that limits the # of tries:
ofy().transactNew(1, new VoidWork() {
...
});
This will let you manage retries on your own. Note that prior to v5.1.6, the # was erroneously being used as a # of retries (not tries). In v5.1.6, behavior was corrected to match the documentation. It's the # of tries.
Related
For example I have something like this:
public void saveFoodatas(List<Foodata> foodataList) {
DatabaseHelper.database.beginTransaction();
try {
for (Foodata foodata : foodataList) {
saveFoodata(foodata);
}
DatabaseHelper.database.setTransactionSuccessful();
}
finally {
DatabaseHelper.database.endTransaction();
}
}
Where DatabaseHelper is a class extending SQLiteOpenHelper and database is a SQLiteDatabase.
In this function I am trying to make it so you save/commit a lot of objects to the database, but if there is a failure, then don't commit any of the changes.
I believe that what it's currently set up to do correctly (if there is an error, it leaves the try block I think and goes straight to finally since there is no catch), but my question is how to properly trigger the failure condition. Do I need saveFoodata to "throw an exception"? If the function encounters some kind of failure without me doing any try/catch/throwing, does that count too? How exactly do I handle saveFooData()?
I think you are on the right track. You need to abort the transaction if an error occurs. You also need to alert the user of the problem. This means that saveFoodata() and saveFoodatas() should throw an exception so that the UI code can display a message to the user,
Our app suddenly got a lot of traffic and there were some design flaws in the system (or rather we never thought it would get this much traffic so we just skipped it by choice).
As the topic states I'm looking for a way to prevent the error: org.datanucleus.exceptions.NucleusDataStoreException: Concurrent Modification
Currently I have an entity called Group that looks like this:
#PersistenceCapable
public class Group extends PersistableString {
private static final long serialVersionUID = 6215353466976945628L;
#Persistent
private int yesCount;
#Persistent
private int noCount;
public void increaseYesCount()
{
yesCount++;
}
public void increaseNoCount()
{
noCount++;
}
}
The following code is how the update of the entity is done:
int answer = Integer.parseInt(req.getParameter("answer"))
try {
PersistenceManager pm = PMF.getPersistenceManager();
for(String groupId : allGroupsToBeUpdated)
{
Group group = pm.getObjectById(Group.class, groupId);
if(answer == 0)
group.increaseNoCount();
else
group.increaseYesCount();
}
pm.close();
} catch (Exception e) {
e.printStackTrace();
}
allGroupsToBeUpdated is a list that contains around 30 string-ids. Is there some way I can avoid the Concurrent Modification-error? Can I check if the entity that I retrieve is being updated and then just discard(/ignore) the update? It's not SUPER important that the write actually succeeds, I just wanna make sure I don't get the error (or that it keeps trying to succeed with the write), because it's causing the request to take between 10-30seconds.
Should I maybe open (get new PM-instance) and close the connection (pm.close()) between each update instead of waiting for all of the 30ish updates to go through?
I know of sharded counters and should have (obviously) used them, but right now I'm looking for a "quick-fix" to this problem.
EDIT:
I'm using:
App Engine SDK 1.8.9
JDO 3.0
Stacktrace can be found at:
http://pastebin.com/TWnmkpPU
Posting as an answer due to length.
Transactions probably aren't good in your case since you are really just looking to hide the issue from the user which is manifesting itself in slow request times. Perhaps kicking off an async push task to do the writes in the background outside of the request would be your best bet.
I really would not recommend design based on hiding errors and swallowing exceptions though. Looking to "prevent" an exception that is doing what it is supposed to (signaling a failed write due to contention), means you should avoid the condition which caused it in the first place.
I totally understand needing to get things working fast early on, but it may be a good idea to start adopting best practices now once the bad design decisions just start making their mark. Continuing to rely on "quick-fixes" and hiding problems can land you in a real mess later on.
I need to write a JUnit test case for a never ending main() method. This main() method after processing some files sleeps for a minute and then resumes its execution. This process goes on and on and on.
I used the below code to write JUnit for it:
#Test (timeout = 10000)
public void testMainMethod()
{
ClassName.main(null);
assertEquals(true, true);
}
And with no surprise, my test case failed with java.lang.Exception: test timed out after 10000 milliseconds message. Even when the main() method works as expected, this test case is going to be failed with the timeout exception. How could i override the behavior of this failing test case so that in case of timeout exception it should show the result as "Succeeded" for this test case.
Edit
The actual requirement is:
I need to search the files from a particular location and, if found any, then move them to different folder. This search should be done every 30 minutes. For this i have used below code:
public class FaxProcessor {
public static void main(String[] args) {
LOGGER.info("*** Starting Fax Server Processor ***");
int poll_time = 1800000;
LOGGER.info("Poll Time set to " + poll_time + " millisec");
FaxProcessor faxProcessor = new FaxProcessor();
while (true) {
try {
if(LOGGER.debugEnabled()){
LOGGER.debug("Starting new pass of fax processor");
}
faxProcessor.startProcessing();
} catch (Exception e) {
LOGGER.error("Processing Error", e);
} finally {
try {
// Wait for next loop
Thread.sleep(poll_time);
} catch (InterruptedException e) {
LOGGER.error("Thread Exception", e);
}
}
}
}
// startProcessing and other private methods here
}
The biggest problem is, I have only one public method {main() method} and all others are private, so i cant write JUnit test case for them. Also, main() method is not returning anything, it only moves files from one folder to another, and in case it fails in moving files in one pass, it tries to do the same in next pass. So using JUnit test case, i only want to check whether an unexpected exception is coming during whole process or not.
If i will not specify timeout in JUnit, the test case is never gonna complete then. As soon as the timeout occurs, i want to check, whether the test case is completed due to Timeout exception or some other exception has come from inside main() method that haulted JUnit test case.
In case it's Timeout exception, this implies, everything inside my program, went in the right direction till the timeout occured, so the test case should SUCCEED. In all other case it should show FAILED as JUnit status.
You have artificially constrained your testing environment, with this statement: "I have only one public method {main() method} and all others are private" -- who says? If this is a requirement imposed by your teacher, then you should seriously consider getting out of the class.
1) Proper testing means testing a) that candidate files are recognized, b) that candidate files are moved, and c) the operation occurs periodically.
2) Factor your main routine into the infinite-loop control part and the worker part. Even better, make the wait interval be a computed value.
3) Use protected methods instead of private methods. Since they are protected, you can now use a sub-class to get access to methods as you need, without violating necessary encapsulation.
You should think of separating long running unit tests. How to achieve that is for example shown here or here.
I don't understand what you want to do.
If you got Timeout Exception, that means the test case ran too long.
If you want to test the main method, and it contains an infinite loop, how can you determine that the method works as expected?
For your problem, use
#Test (timeout = 10000, expected=Exception.class)
EDIT2
#paradigmatic made a good point in suggesting to redirect rather than throw the exception; that solves the logging issue. The problem in Play 2 is that redirects need to occur within so-called Action scope, which is not always the case with date parser calls.
As a workaround, I went with Play's global interceptor, presumably the equivalent of a Java servlet filter.
val ymdMatcher = "\\d{8}".r // matcher for yyyyMMdd URI param
val ymdFormat = org.joda.time.format.DateTimeFormat.forPattern("yyyyMMdd")
def ymd2Date(ymd: String) = ymdFormat.parseDateTime(ymd)
override def onRouteRequest(r: RequestHeader): Option[Handler] = {
import play.api.i18n.Messages
ymdMatcher.findFirstIn(r.uri) map{ ymd=>
try { ymd2Date( ymd); super.onRouteRequest(r) }
catch { case e:Exception => // kick to "bad" action handler on invalid date
Some(controllers.Application.bad(Messages("bad.date.format")))
}
} getOrElse(super.onRouteRequest(r))
}
EDIT
Here 's a little context to work with:
// String "pimp": transforms ymdString.to_date call into JodaTime instance
class String2Date(ymd: String) {
def to_date = {
import play.api.i18n.Messages
try{ ymdFormat.parseDateTime(ymd) }
catch { case e:Exception => throw new NoTrace(Messages("bad.date.format")) }
}
val ymdFormat = org.joda.time.format.DateTimeFormat.forPattern("yyyyMMdd")
}
#inline implicit final def string2Date(ymd: String) = new String2Date(ymd)
and a test custom exception handler:
public class NoTrace extends Exception {
static final long serialVersionUID = -3387516993124229948L;
#Override
public Throwable fillInStackTrace() {
return null;
}
public NoTrace(String message) {
super(message);
}
}
Calling the date parser on an invalid yyyyMMdd string logs 30 line stack trace to the log (this occurs upstream by Play framework/Netty container, better than default 100 line trace):
"20120099".to_date
ORIGINAL
Have an issue where my application.log is getting filled with errors related to a uri date parser operation that should succeed given a valid yyyyMMdd uri date.
However, some users try to circumvent this by entering invalid dates in hopes of gaining free access to paid subscriber-only content. It's pointless, as it simply won't work, but regardless, I have MBs of these error traces in my application log.
Is there a way to throw a truly trimmed down Exception to the log? I found this SO answer, but in my application it looks like the container (Play framework on Netty) gets into the mix and logs its own 30 line stack trace to the log (30 lines is better than 100, but still 29 too many)
Similarly, I found this thread in regard to Java 7 and the new option to suppress stack trace; however, for some reason, despite being on Java 1.7, with Eclipse configured for Java 1.7, only the old 2 param method of Throwable is available (and I do see the 4 param method when I click through to the Throwable class; maybe a Scala 2.9.2 library issue?)
At any rate, ideally I can simply log a 1-line exception message and not the kitchen sink.
Simply override this method in your custom exception class:
#Override
public Throwable fillInStackTrace() {
return this;
}
after adding this method your trace method will not print
Your trouble is that although you can suppress the stacktrace of the exception your own code threw, there is nothing you can do about the exception it will be wrapped into by the framework. The only avenue I can see is not allowing the framework to catch your exception at all (doing your own top-level handling) or tweaking the logging configuration.
I think you have two options:
Control the logging to not save stack traces for some exceptions.
Write a post-processor that filters out the traces from the log file.
Unless you are in danger of running out of disk space, I think #2 is the better option, because if you do have a bug you can go back to the full log and have all the exception history.
The philosophy behind idea #2 is that disk space is cheap, but information can be precious during debug. Log a lot of data. Normally, use scripts to examine the log after it has been written to disk.
For example, if there is a type of log entry that you never expect to see, but that demands immediate action if it does appear, write a script that searches for it, and send you an e-mail if it finds one.
One of the most useful forms of script in this approach is one that drops stack trace lines. Usually, you only need to know what exceptions are happening, and the stack trace takes up a lot of screen space without telling you much. If you do need to investigate an exception, go back to the full log, find the exception line, and look at the stack trace and at what was happening immediately before the exception.
If there are too many of your date exceptions, have the script drop even the exception line. If you want to track how often they are happening, run a script that counts date exceptions per hour.
That sort of script typically costs a few minutes of programming in your favorite regex-capable script language.
I'm getting a NullPointerException in a Nokia S40.
I want to know what is causing this exception.
The device shows:
NullPointerException java/lang/NullPointerException
This error only occurs in the device, running in the emulator the application works fine.
I use microlog to debug my application. But the application works fine if the log is enabled.
Is there a way to get the stack trace when I get this NullPointerException? I don't need all details like the line number just which method cause this exception.
UPDATE: I installed the same application in another Nokia S40 and the same error didn't occur.
Nokia 2660 - error
Nokia 6131 - no error
UPDATE 2: Somehow I find what was causing the NullPointerException.
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
public class OuterClass extends Canvas {
private Config config;
public OuterClass() {
this.config = new Config();
}
public void paint(Graphics graphics) {
HelperClass helper = new HelperClass(this.config);
helper.doStuff();
}
public void dispose() {
this.config = null;
}
public class Config implements IConfig {
public int getSomething() {
// ...
}
}
}
public class HelperClass {
private IConfig config;
public HelperClass(IConfig) {
this.config = config;
}
public doStuff() {
config.getSomething(); // Here is thrown NullPointerException
}
}
In some situations a thread is started and call the OuterClass.dispose() before the helper.doStuff() causing the NPE. I think when I enabled the log it made the thread slower and helper.doStuff() was called when I expected it to be called.
You are not going to find any way to save a Throwable stack trace on a Nokia Series40 handset.
The usual brute force way of debugging JavaME application on Series40 is to modify your code to create a stack trace yourself in memory.
What I'm talking about is:
Each Thread that you can identify (including system callback threads) needs its own Stack object, containing strings. Obviously, this increases the memory footprint of your application somewhat but keeping it in memory should limit the impact on race conditions.
When your code enters a method, it adds the method signature to the current Thread Stack. When the method exits (and you better only have one exit point per method) it pops the top of the Stack.
You can add aditional debug info on the stack, like values of variables in different places of the code.
You don't necessarily need to add this to every single method in your code.
You can add try{}catch(Throwable){} to the entry point of every thread you identified and either dump the stack in a file or on the screen (in a Form).
Obviously, this is not the kind of change you want to manually add in a lot of places in a large existing codebase. You can however make it part of your organisation coding standards for the future and write a source code parsing script to automatically add it to existing code.
I had some trouble in the past trying to print the stack trace to somewhere else than the standard output. The standard exception class doesn't provide the printStackTrace method that receives the output stream, therefore it only prints to the standard output stream.
It's possible, at least in Java SE, to redirect the java output stream to somewhere else by simply saying that System.out = . The PrintStream class receives an OutputStream, which means that you could create your own ByteArrayOutputStream, initialize a PrintStream, sets System.out to that stream, and then call ex.printStackTrace(). I don't have a J2ME environment here but I believe that, as long as it won't break when you try to set System.out to something else (nothing says that it's readonly in the docs), you should be able to do it.
After you do that, I would recommend writing it to a RecordStore that you have specifically for that, and then upload the records of that RecordStore to your server so you can get it.
I know it's not very easy but it may work. I would first test the System.out thing. If it works, everything else should work too.
My answer was wrong. As pointed out, the System.out and System.err fields are declared final. If you can't get the stack trace, and if you can't get the error when running the application on your emulator, try creating trace bullets on your code (alerts, logs, whatever you can) to isolate the piece of code where the problem is happening. It has to be something that could change between the emulator and the real device - for example, something related to retrieving/ saving records in a RecordStore, opening a Connection, etc... What did you try to do when you had the problem?
You could use Microlog to send an e-mail when the exception occurs.
Microlog
You could try catching the exception in some high-level try/catch block and then emailing the trace to yourself.