Daniel
Daniel

Reputation: 1919

New Google App Engine Datastore API doesn't seem to throw as many exceptions?

I wrote some code against the Java Google App Engine 1.6.4.1 API, and to get my code to compile, I had to handle lots of exceptions, such as ConcurrentModificationException. I upgraded to 1.6.5, and now I can just delete most of my exception handlers and my code compiles just fine. What is going on?

UPDATE: several classes of exceptions are no longer being thrown; as this may have happened for different reasons for different exceptions, here are the Exceptions that are no longer being thrown by

Here is an example of someone getting an IllegalArgumentException in GAE: Google App Engine - "java.lang.IllegalArgumentException: datastore transaction or write too big." Can this no longer occur?

The Transaction Interface documentation says that you can get any one of the last three when performing a commit(): https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/Transaction#commit()

Throws:

java.lang.IllegalStateException - If the transaction has already been committed, rolled back, a commit or a rollback is in progress (via an async call), or an attempt to commit or roll back has already failed. If there are any outstanding async datastore calls when this method is invoked, this method will block on the completion of those calls before proceeding.

DatastoreFailureException - If a datastore error occurs.

java.util.ConcurrentModificationException - If some other transaction modified the same entity groups concurrently.

And yet I am no longer required to handle them in order to get my code to compile. This seems odd.

Upvotes: 1

Views: 611

Answers (2)

David Gay
David Gay

Reputation: 11

I wrote some code against the Java Google App Engine 1.6.4.1 API, and to get my code to compile, I had to handle lots of exceptions, such as ConcurrentModificationException.

Something is weird here: ConcurrentModificationException and the other exceptions you list are subclasses of RuntimeException. You never need to catch those to satisfy a Java compiler.

Upvotes: 0

jamesmortensen
jamesmortensen

Reputation: 34038

The newest release of Google App Engine made it required to set the <threadsafe>true</threadsafe> property in the appengine-web.xml. Prior to this release, this was not required.

ConcurrentModificationExceptions occur when a single instance of an object in your application is being modified simultaneously by more than one thread. This can of course result in inconsistent data and results, and some classes will throw this exception in lieu of returning bad data or making inconsistent changes to your database.

With the threadsafe property set to true, concurrent requests are now enabled.

Using Concurrent Requests

By default, App Engine sends requests serially to a given web server. You can configure App Engine to send multiple requests in parallel by adding the element to appengine-web.xml:

<threadsafe>true</threadsafe>

Prior to 1.6.5, the threadsafe directive was optional, introduced in 1.4.3:

Java applications can enable concurrent request support by setting <threadsafe>
to True in their appengine-web.xml. This flag indicates that request handlers
for your app are thread safe and multiple request handlers may safely run
at the same time in the same memory space for your application.

While this is now required, there doesn't seem to be any information immediately available that would explain why exactly your ConcurrentModificationExceptions have suddenly vanished. If you haven't made changes to your code to make it thread safe, as was suggested in the 1.4.3 release notes, then there is a strong possibility that those thread safety issues are still present.

Here is more information on the 1.4.3 release from the blog post Announcing App Engine 1.4.3 Release:

Concurrent Requests: Until now, Java applications relied on starting additional instances to dynamically scale up for higher traffic levels. Now with support for concurrent requests, each application instance may serve multiple user requests at the same time. To start, ensure your application’s code is threadsafe, then enable concurrent requests by adding the flag to your appengine-web.xml.

If the exceptions you've reported have disappeared, your code may still have some thread safety issues. It's possible that you may not be seeing these because you've increased the number of instances or have done something else in your application to mitigate the ConcurrentModificationExceptions.

Considering 1.6.5 has been released for less than a month, I would be extremely hesitant to remove my exception handlers from my code. After all, their job is to detect and handle problems that occur, and if you remove them, then you lose whatever graceful degradation you may have had in place prior to their removal.

Additionally, the absence of something, such as exceptions, does not constitute proof that that something will not again appear at some unknown point in the future.

From the javadocs for ConcurrentModificationException:

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.

For example, it is not generally permssible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Upvotes: 2

Related Questions