Programming Google App Engine with Java

Errata for Programming Google App Engine with Java

Submit your own errata for this product.


The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color Key: Serious Technical Mistake Minor Technical Mistake Language or formatting error Typo Question Note Update



Version Location Description Submitted By Date Submitted Date Corrected
PDF
Page 12
Second paragraph in "Google Cloud Endpoints"

Non-browser clients for web apps, especially native mobile apps *****runnign***** on smartphones The word running is spelt as runnign This is from the PDF Early Release edition dated Sept 25, 2014

Note from the Author or Editor:
This was fixed in a later draft.

Anonymous  Jan 13, 2015 
PDF
Page 13
First line in section Namespaces

wrong spelled memcache (memcahe)

Note from the Author or Editor:
Fixed in draft. Thanks!

Anonymous  Oct 19, 2014 
PDF
Page 14
Sixth paragraph in "Developer Tools" section

You also use the ****tool kit**** to interact with App Engine directly "toolkit" is one word so should not have a space in it. All other references to toolkit in the PDF do not contain a space. PDF version dated 25th September 2014

Note from the Author or Editor:
Fixed in draft.

Anonymous  Jan 13, 2015 
PDF
Page 15
Second web link in "Getting Started" section

The link to the quick start guide for App Engine is incorrect. The PDF uses: http://console.developers.google.com/start/appengine/ The correct link actually uses https and must not have a '/' character on the end. The correct URL is: https://console.developers.google.com/start/appengine Google "officially" links to this URL in "step 2" on the Cloud SDK at https://cloud.google.com/sdk/ which you refer to in the previous paragraph. This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Fixed in draft.

Anonymous  Jan 13, 2015 
PDF
Page 17
The bulleted list in "Setting Up the Cloud SDK"

Consider adding Python to this list as on the next page it says: "These tools are implemented in Python, so you will need Python installed on your machine to use them."

Note from the Author or Editor:
Accepted, draft updated.

Anonymous  Jan 13, 2015 
PDF
Page 19
Last paragraph in "Installing Java" section on the top of page 19

"Java Enterprise Edition (Java EE)" is actually called "Java Platform, Enterprise Edition (Java EE)" See: http://www.oracle.com/technetwork/java/javaee/overview/index.html Or: https://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition

Note from the Author or Editor:
Accepted, draft updated.

Anonymous  Jan 13, 2015 
PDF
Page 38
3rd bullet point - user EL expression

Bullet point 3 contains several EL expressions from the JSP but the text in the paragraph has extra '\' characters in them. E.g. $\{user != null\} should be ${user != null} $\{logoutUrl\} should be ${logoutUrl} This is to match the example code from Example 2-5 on page 36 PDF version dated 25th September 2014

Note from the Author or Editor:
Fixed in draft. (ASCIIDoc escape chars were in a DocBook-escaped region.)

Anonymous  Jan 16, 2015 
PDF
Page 39
First paragraph

The PDF contains the text: "If you have a /\* URL mapping that might match a JSP path, you must..." There appears to be an extra '\' character between the '/' and '*' characters. PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 23, 2015 
PDF
Page 43
Comment in the catch NumberFormatException block

The comment says "User entered a value that wasn't an integer." However, this is wrong as the String is converted to a Double in the code so it should say: "User entered a value that wasn't a double" This problem also affects the same catch block on page 47 This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Accepted, fixed in draft.

Anonymous  Jan 17, 2015 
PDF
Page 45
Second paragrah (the one with the picture)

The text in paragraph 2 talks about calling getProperty() and calling intValue() on it. However, the code above on page 44 actually calls doubleValue() PDF version dated 25th September 2014

Note from the Author or Editor:
Accepted. Updated the tip, which had several statements made inaccurate by a previous change from int to double.

Anonymous  Jan 17, 2015 
PDF
Page 47
First code sample

The comment says "User entered a value that wasn't an integer." However, this is wrong as the String is converted to a Double in the code so it should say: "User entered a value that wasn't a double" (This issue was fixed previously on page 41 in an earlier draft but not this occurrence) PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 23, 2015 
PDF
Page 49
5th paragraph of "Registering the Application"

The text in the PDF says: "You can have up to 25 projects per Google account" This is not actually true as according to the "Google App Engine General Questions" at https://cloud.google.com/appengine/kb/general#create it says: "Each account can host 25 free applications and an unlimited number of paid applications Google App Engine." Perhaps the PDF text should be updated to include the word "free" so it becomes: "You can have up to 25 free projects per Google account" This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Accepted, updated in draft.

Anonymous  Jan 17, 2015 
PDF
Page 59
3rd paragraph

It says "To set up a custom domain, go to Cloud Console, select App Engine, then Settings." However, a custom domain is per application and the location in the Cloud Console looks like it has changed as you need to: 1) Go to the Cloud Console 2) Select the project for which you want to set the custom domain 3) Select Compute and then select App Engine 4) Then select Settings PDF version dated 25th September 2014

Note from the Author or Editor:
Made a minor clarification change.

Anonymous  Jan 18, 2015 
PDF
Page 63
Example servlet mapping at top of page

The servlet mapping is inconsistent with the descriptive text in the paragraph above which says "includes the <servlet-name> that matches a servlet declaration, and a <url-pattern>". The example actually contains a "url-mapping" which is incorrect . It should be a "url-pattern" PDF version dated 25th September 2014

Note from the Author or Editor:
Accepted, corrected here and in a later chapter in draft.

Anonymous  Jan 20, 2015 
PDF
Page 65
First paragraph

The first paragraph contains: "...with the <resource-files> and <static-files> elements, respectively. These elements can contain an <include> element and an <exclude> element..." This appears to be incorrect as rather than "...can contain an..." (i.e. 0 or 1 occurrences), it appears that it can be 0 or more occurrences. This is mentioned in the "Including and excluding files" section in Configuring appengine-web.xml at [1] Additionally, the file google-cloud-sdk/platform/appengine-java-sdk/docs/appengine-web.dtd contains the following: <!ELEMENT static-files (include|exclude)*> <!ELEMENT resource-files (include|exclude)*> This DTD states 0 or more occurrences of the include/exclude elements PDF version dated 25th September 2014 [1] https://cloud.google.com/appengine/docs/java/config/appconfig#Java_appengine_web_xml_Including_and_excluding_files

Note from the Author or Editor:
Accepted, fixed in draft.

Anonymous  Jan 20, 2015 
PDF
Page 77
First paragraph

"If the role name is \*, then any user..." This should be "*" rather than "\*" This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Markup error, fixed in draft.

Anonymous  Jan 22, 2015 
PDF
Page 88
Last paragraph of Deployments limits section

The PDF says: "An application can only be uploaded a limited number of times per day, currently 1,000." This looks to be incorrect as the current limit appears to be 10000. See https://cloud.google.com/appengine/docs/quotas#Deployments which says: "Deployments The number of times the application has been uploaded by a developer. The current quota is 10,000 per day." This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Accepted. I just removed the paragraph, since 10,000 times a day is once every 9 seconds, and is not really a notable limit.

Anonymous  Jan 23, 2015 
PDF
Page 88
Last paragraph of Projects section

The link to Google's pad support program has not been converted into a proper hyperlink. It shows as <ulink url="https://cloud.google.com/support/">paid support programs</ulink> This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
This was fixed in a later draft.

Anonymous  Jan 23, 2015 
PDF
Page 91
2nd paragraph in The Java Runtime Environment

The PDF says: "The Java runtime environment uses the Java 6 virtual machine (JVM)." This seems to be incorrect as it appears that Java 7 is used and not Java 6. This is confirmed by the Google documentation at https://cloud.google.com/appengine/docs/java/#Java_Introduction which says: "App Engine runs your Java web application using a Java 7 JVM in a safe "sandboxed" environment." Also, in the release notes at https://code.google.com/p/googleappengine/wiki/SdkForJavaReleaseNotes, it appears that Java 6 support was dropped in version 1.9.0 This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Fixed in draft: replaced two remaining instances of "Java 6" with "Java 7."

Anonymous  Jan 23, 2015 
PDF
Page 101
Last paragraph

The text in the PDF says: "The default maximum is 8 concurrent request handlers" And "you can increase this limit to as much as 80" Looking at the documentation at https://cloud.google.com/appengine/docs/java/modules/ it appears these limits have been increased: "max-concurrent-requests: Optional. The number of concurrent requests an automatic scaling instance can accept before the scheduler spawns a new instance (Default: 10, Maximum: 100). " This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Fixed in draft.

Anonymous  Jan 25, 2015 
PDF
Page 144
Last sentence on page

The page is taking about the get() method on the DatastoreService and says: "The get() method returns null if no entity with that key exists." Reading the JavaDoc for the DatastoreService at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreService#get(com.google.appengine.api.datastore.Key) it says: "EntityNotFoundException - If the specified entity could not be found." The JavaDoc seems to suggest that the get() method does not return null but rather throws EntityNotFoundException. I have not actually tested this with code. I am just comparing the JavaDoc with the PDF This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Fixed in draft.

Anonymous  Jan 29, 2015 
PDF
Page 145
First paragraph

There is a formatting problem with the end of the first paragraph as it has '+' characters around the words "Key" and "Entity". It says: "To make a batched get, simply pass an Iterable<Key> to get() . The method returns a Map of +Key+s to +Entity+s:" This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Fixed markup error.

Anonymous  Jan 29, 2015 
PDF
Page 145
First paragraph after the first code example

The text is referring back to the get() method returning null if not found but this is not true. The PDF text says: "As with the non-batch call, the value for a key is null if there is no entity with that key." The documentation at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreService#get(java.lang.Iterable) says: "The result Map will only contain Keys for which Entities could be found. " This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Fixed in draft.

Anonymous  Jan 29, 2015 
PDF
Page 152
Footer #1

"...but there is an unofficial GQL library for Java called gql4j if you’d like to try it." According to the gql4j project's website at https://code.google.com/p/gql4j/ it says: "This project is deprecated now. Anyone interested please contact me." As this project's last release was in November 2011 and is deprecated, perhaps it is not worth encouraging users to try ggl4j for new projects? This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Acknowledged but it's not a strong recommendation (it's in a footnote), and while the library is unsupported by its author it does still exist, and is simple enough to be unlikely to change.

Anonymous  Feb 01, 2015 
PDF
Page 155
Second paragraph

The PDF says: "If a query is likely to have only one result, or if only the first result is desired, calling the asSingleEntity() method retrieves the result and returns an Entity object, or null ." This does not match up with the Javadoc at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/PreparedQuery#asSingleEntity() which says: "Retrieves the one and only result for the Query. Returns: the single, matching result, or null if no entities match Throws: PreparedQuery.TooManyResultsException - if more than one result is returned from the Query." The wording in the PDF does not match this Javadoc as the PDF suggests that if there are 2 results then it will return the first result. However, the Javadoc says it will throw TooManyResultsException This is from the PDF version dated September 25th, 2014

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 01, 2015 
PDF
Page 196
Second code example

The second code example shows 0 being passed in as the second parameter to the addChild() method. Reading the documentation for KeyFactory.Builder().addChild(), from https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/KeyFactory.Builder#addChild(java.lang.String, long) it says: "id - the numeric identifier of the child in kind, unique across entities of this kind with the same parent, must not be zero" This seems to suggest that the second id parameter cannot be 0 When I try to run the code that adds a child with 0 as the id, I get: java.lang.IllegalArgumentException: id cannot be zero at com.google.appengine.api.datastore.KeyFactory.createKey(KeyFactory.java:52) at com.google.appengine.api.datastore.KeyFactory.createKey(KeyFactory.java:47) at com.google.appengine.api.datastore.KeyFactory$Builder.addChild(KeyFactory.java:289) PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 03, 2015 
PDF
Page 200
3rd paragraph just before code sample

The PDF says: "If the transaction cannot be committed due to a concurrency failure (or other datastore error), the commit throws a DatastoreFailureException :" This does not match the Transaction.commit() Javadoc at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/Transaction#commit() it says that the commit method only throws DatastoreFailureException "If a datastore error occurs." The commit method throws java.util.ConcurrentModificationException for concurrency problems and java.lang.IllegalStateException for rollback, etc problems PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 03, 2015 
PDF
Page 202
First code example

The example code to retry the transaction will not actually retry the transaction for a concurrency failure as it only retries if a DataStoreFailureException is thrown. It should be retrying for ConcurrentModificationException See the example code provided by Google at: https://cloud.google.com/appengine/docs/java/datastore/transactions#Java_Uses_for_transactions Also reading the Javadoc for DataStoreFailureException at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreFailureException it says: "DatastoreFailureException is thrown when any unknown error occurs while communicating with the data store. Clients should not attempt to retry after receiving this exception." Notice the comment to not retry when this exception is thrown. PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 03, 2015 
PDF
Page 211
2nd to last paragraph

It looks like the image file is missing for the Cloud Database Dashboard in the Cloud Console. The PDF contains the text: "images::figs/incoming/data‐store_admin_console.png["The Cloud Datastore Dashboard in the Cloud Console"]" PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft, image was missing from Java version.

Anonymous  Feb 04, 2015 
PDF
Page 213
3rd paragraph in Managing Indexes

It looks like the Cloud Datastore Indexes panel image is missing. The PDF contains the text: The Cloud Datastore Indexes panel in the Cloud Console. images::figs/incoming/data‐ store_admin_indexes.png["The Cloud Datastore Indexes panel in the Cloud Console"] PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft, images were missing from Java version.

Anonymous  Feb 04, 2015 
PDF
Page 216
Second paragraph

There is a stray '+' character at the end of the second sentence. The PDF says: "(This kind name is also available as the constant Entities.NAMESPACE_METADATA_KIND from the com.google.appengine.api.datastore.Entities class+.) PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 06, 2015 
PDF
Page 217
Last paragraph

The PDF has the following text: "An Index has accessor methods getKind() , isAncestor() , and getProperties() . getProperties() returns a List<Index.Property>..." Because the first sentence ends with "getProperties()." and the next sentence starts with "getProperties()", I misread this sentence as "getProperties().getProperties()" - i.e. the object returned by the getProperties() method has a getProperties() method on it. This can be clarified by changing the text so the second getProperties() is changed to "The getProperties() method". The text would then read: "An Index has accessor methods getKind() , isAncestor() , and getProperties() . The getProperties() method returns a List<Index.Property>..." PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 06, 2015 
PDF
Page 219
Code example: line creating child entity

The code in the second example does not compile due to the line: Entity child = new Entity("MyKind", parent); There is no Entity constructor that takes a String and a Entity. I believe the code should be: Entity child = new Entity("MyKind", parent.getKey()); There is also an example of this in the Google documentation at https://cloud.google.com/appengine/docs/java/datastore/entities#Java_Ancestor_paths PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 06, 2015 
PDF
Page 219
3rd paragraph of "Remote Controls" section

The PDF states: "The client library and several tools that use it are implemented in Python only, but they can be used with Java apps" If I read the App Engine documentation correctly, this appears to be no longer true as a Java implementation was provided with version 1.4.3 of app engine. The documentation for the Java version of the Remote API can be found at https://cloud.google.com/appengine/docs/java/tools/remoteapi However, there does not appear to be a Java equivalent of the remote_api_shell.py script. As this is the Java version of the book and there is a Java version of the Remote API, perhaps it is worth reworking the "Using the Remote API from a Python Script" section starting on page 222? PDF version dated 23rd January 2015

Note from the Author or Editor:
Rewrote this section with a new Java client example, and removed the Python client material.

Anonymous  Feb 06, 2015 
PDF
Page 225
First paragraph

The end of the first paragraph says "These interfaces provide two essential features." From the text it is clear that the first essential feature is "...a mechanism for describing the structure of data objects" From reading the text, It is less clear what the second essential feature is. PDF version dated 23rd January 2015

Note from the Author or Editor:
Revised the paragraph.

Anonymous  Feb 07, 2015 
PDF
Page 229
Final code sample

The start of the paragraph above the final code sample says: "If you’d prefer not to create a dependency on an App Engine–specific class,..." The code example immediately below this then has an import statement that lists a Google App Engine class: "import com.google.appengine.api.datastore.Key;" As the code example does not use the Key class, this import statement can be removed. PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 07, 2015 
PDF
Page 236
3rd paragraph up from bottom of page

The PDF states: "If you are only expecting one result, you can call getSingleResult() instead. This gets the first result if any, or null if there are no results:" According to the JavaDoc for getSingleResult(), at http://docs.oracle.com/javaee/5/api/javax/persistence/Query.html#getSingleResult(), the method call does not return null - it throws exceptions to indicate no results/more than 1 result. The Javadoc says: NoResultException - if there is no result NonUniqueResultException - if more than one result PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 08, 2015 
PDF
Page 238
second to last paragraph

Minor point - the PDF states: "To execute a DELETE query, call the Query object’s executeUpdate() method. This method returns no results." Technically, this method does return a result - it returns "the number of entities updated or deleted" - see Javadoc at http://docs.oracle.com/javaee/5/api/javax/persistence/Query.html#executeUpdate() Perhaps a more accurate wording would be: "This method does not return entities. Instead it returns the number of entities updated or deleted" PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 08, 2015 
PDF
Page 244
Last sentence

The PDF says: "To read the unit tests, click the Source tab, then click Browse in the navigation bar. The path is svn/trunk/tests/org/datanucleus/store/appengine/." It looks like the unit tests are now in: svn/trunk/tests/com/google/appengine/datanucleus/ PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 08, 2015 
PDF
Page 257
App Engine JDBC url line

In the code sample, the code line that defines the url for the App Engine connection is too long and extends off the side of the page so it is truncated. The line in the PDF reads: url = "jdbc:google:mysql://" + instanceId + "/" + database + "?user=" + us PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 10, 2015 
PDF
Page 273
3rd paragraph

The PDF says: "Memcache integers are 64 bits in size. Incrementing beyond the maximum 64-bit integer causes the value to wrap around to 0, and decrementing has the same behavior in reverse." It appears that according to the Javadoc at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/memcache/MemcacheService#increment(java.lang.Object, long) when incrementing and number wrap around occurs, the value is the "signed 64-bit min (-2^63 )" The Javadoc says: "Incrementing by positive amounts will reach signed 64-bit max ( 2^63 - 1) and then wrap-around to signed 64-bit min (-2^63 ), continuing increments from that point." PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 11, 2015 
PDF
Page 273
Code example

The code example contains the following line: result = memcache.increment(key, 9, 0); This code does not compile and produces the following error: The method increment(Object, long, Long) in the type MemcacheService is not applicable for the arguments (Object, int, int) The problem is that Java will not autobox the third parameter from an int primitive to a Long object. The line of code needs to be updated to add an 'L' to the third parameter: result = memcache.increment(key, 9, 0L); Ideally, an 'L' should be added to the second parameter to identify it as a long but Java will auto convert an int to a long. PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 11, 2015 
PDF
Page 275
First paragraph

The PDF states: "The three-argument form of this method returns a java.util.Set<T> containing all the keys not set by the call." This seems to be backwards compared to the Javadoc at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/memcache/MemcacheService#putAll(java.util.Map, com.google.appengine.api.memcache.Expiration, com.google.appengine.api.memcache.MemcacheService.SetPolicy) which states: "Returns: the set of keys for which entries were created. Keys in values may not be in the returned set because of the policy regarding pre-existing entries." The rest of the paragraph will need to be updated too. Additionally, the code sample following the paragraph will also need to be updated as the memcache,putAll(valueMap) method is a void method so does not return a Set PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 11, 2015 
PDF
Page 275
Last paragraph

The sentence that starts "It takes a Map of keys to instances of the wrapper...." has a stray '+' character in it and there is too much fixed width font text in it. The following text is in a fixed width font: "MemcacheService.CasValues, each of which holds the original +MemcacheService.IdentifiableValue" It looks like there is a missing ASCIIDoc escape character after "MemcacheService.CasValues" PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 11, 2015 
PDF
Page 277
Second paragraph

The second paragraph talks about the "ErrorHandler interface". This interface is now deprecated - see https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/memcache/ErrorHandler A new ConsistentErrorHandler interface was added that improves on the error handling - see https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/memcache/ConsistentErrorHandler Perhaps the text should be updated to refer to the newer ConsistentErrorHandler interface and new implementations rather than the older deprecated ErrorHandler interface and implementations (code sample needs updating too)? PDF version dated 23rd January 2015

Note from the Author or Editor:
Replaced mentions of ErrorHandler with ConsistentErrorHandler, and LogAndContinueErrorHandler with ConsistentLogAndContinueErrorHandler. Code sample doesn't need to change because StrictErrorHandler was upgraded in place.

Anonymous  Feb 11, 2015 
PDF
Page 281
Last paragraph

The last sentence says: "A request can be up to 5 megabytes in size (including headers)...." Looking at the latest documentation at https://cloud.google.com/appengine/docs/java/urlfetch/#Java_Quotas_and_limits it appears that the current limit is actually 10 megabytes. PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 11, 2015 
PDF
Page 288
First paragraph in Request and Response Sizes section

There is another reference to the 5 megabyte request limit. "The request can be up to 5 megabytes in size" Looking at the latest documentation at https://cloud.google.com/appengine/docs/java/urlfetch/#Java_Quotas_and_limits it appears that the current limit is actually 10 megabytes. PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 11, 2015 
PDF
Page 297
Last sentence of first paragraph

The PDF states: "Currently, common file archive types, like .zip, are also not allowed." According to https://cloud.google.com/appengine/docs/java/mail/#Java_Sending_mail_with_attachments it looks like you can now send zip files as the file type is listed in the allowed MIME Type table. There is a note at the end of the table about what can be in the zip file and there are some file extensions that are not allowed. PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 13, 2015 
PDF
Page 305
Last line of code sample

The final line of code sample extends past the end of the page and is truncated. The code needs reformatting so part of it is not missing. PDF version dated 23rd January 2015

Note from the Author or Editor:
Markup error, fixed in draft.

Anonymous  Feb 18, 2015 
PDF
Page 307
Last paragraph

The PDF states: "Calling this object’s getStatusMap() method returns a Map<JID, SendResponseStatus>" According to the Javadoc at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/xmpp/SendResponse#getStatusMap() the actual type of the value for this map is "SendResponse.Status" and not "SendResponseStatus" as reported in the PDF. The difference is the missing '.' character between "SendResponse" and "Status" PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 18, 2015 
PDF
Page 316
else if line of code sample

The code example in the PDF uses PresenceType.AVAILABLE for both if statements: if (presence.getPresenceType() == PresenceType.AVAILABLE) { ... } else if (presence.getPresenceType() == PresenceType.AVAILABLE) { ... } The second if statement should be comparing against PresenceType.UNAVAILABLE i.e. } else if (presence.getPresenceType() == PresenceType.UNAVAILABLE) { PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft. (A 1st ed. code sample typo. whew.)

Anonymous  Feb 18, 2015 
PDF
Page 326
Code sample at bottom of page

The "doPost()" code sample extends past the edge of the page and truncates the end of the lines. PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 19, 2015 
PDF
Page 327
Last code sample

The final code sample in the PDF on page 327 that uses etaMillis() does not compile because the number 1356940800000 is too long for a Java integer. The final line needs to be changed by adding an 'L' character at the end of the number so it becomes: .etaMillis(1356940800000L)); PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 19, 2015 
PDF
Page 327
Final code sample

The comment above the code sample says that 1356940800000 is "December 31, 2012, midnight UTC" Decoding this epoch, it appears to actually be "Mon Dec 31 2012 08:00:00 UTC". See http://currentmillis.com/ as an example of one of the many websites that will do the conversion. It appears that 1356940800000 is "December 31, 2012, midnight Pacific Time" The correct value for UTC is 1356912000000 PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 19, 2015 
PDF
Page 329
Third paragraph starting "Task queues have special behavior"

The PDF talks about setting the target for a task using the target() and withTarget() methods: "You can set a specific version for a task by using the target() ( withTarget() ) builder method of TaskOptions" Reading the Javadoc at https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/taskqueue/TaskOptions.Builder it does not list any target related methods. Am I missing something or is there no task related methods on TaskOptions.Builder or TaskOptions? PDF version dated 23rd January 2015

Note from the Author or Editor:
Removed the sentence that mentions this. (Maybe the API was removed?)

Anonymous  Feb 19, 2015 
PDF
Page 332
3rd paragraph up from bottom of page

The PDF describes the "...5 parameters that control how push queues retry a given task". The PDF uses '_' characters to separate the words in the names but the names in the actual XML use a '-' character For example, the descriptive text uses "task_retry_limit" but the actual parameter name is "task-retry-limit" as can be seen at https://cloud.google.com/appengine/docs/java/config/queue#retry_parameters This can be seen in each of the 5 parameters described in the PDF There is also one reference to "retry_parameters" on page 333 that should be "retry-parameters" PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 19, 2015 
PDF
Page 339
Code example at top of page

The code in the code sample at the top of the page does not compile due to the following lines being in error: PDF says: for (userKeyStr : guildMemberKeyStrs) { Line should be: for (String userKeyStr : guildMemberKeyStrs) { PDF says: task = task.param("total_amount", Long(amount).toString()); Line should be: task = task.param("total_amount", Long.toString(amount)); PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 22, 2015 
PDF
Page 345
Code sample

The code in the code sample does not compile because the run() method needs to be public. The PDF says: void run() { The line needs to be: public void run() { PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 22, 2015 
PDF
Page 368
Second to last paragraph

The image for the "Logs panel in the Cloud Console" is missing. The PDF contains the text: "images::figs/incoming/logs_console.png" PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft.

Anonymous  Feb 23, 2015 
PDF
Page 377
Second to last paragraph

The image is missing from the second to last paragraph. The PDF contains the text: "images::figs/incoming/deploy‐ing_versions.png" PDF version dated 23rd January 2015

Note from the Author or Editor:
Fixed in draft. (Several images had bad markup.)

Anonymous  Feb 23, 2015 
PDF
Page 380
First paragraph of "Quotas and Billing"

The first paragraph of "Quotas and Billing" in the PDF contains the text: "...refer back to [Link to Come] in Chapter 2." The "[Link to Come]" should probably be replaced by a proper link to the correct section in Chapter 2. PDF version dated 23rd January 2015

Note from the Author or Editor:
Removed the sentence with the bad ref.

Anonymous  Feb 23, 2015