2014年3月17日月曜日

AccessControlException when using local MySQL for Google Cloud SQL

  If you are developing an application for Google App Engine + Google Cloud SQL and using local MySQL during development, you may encounter AccessControlExeption like below.
java.security.AccessControlException:
    access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
  This exception is raised when your application tries to use Thread because Google App Engine does not allow application to use Thread.

  Reading the stack trace, you will find the point where Thread is created.
at java.lang.Thread.<init>(Thread.java:444)
at java.util.TimerThread.<init>(Timer.java:499)
at java.util.Timer.<init>(Timer.java:101)
at java.util.Timer.<init>(Timer.java:146)
at com.mysql.jdbc.ConnectionImpl.getCancelTimer(ConnectionImpl.java:392)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2195)
  From the information above, it can be guessed that a Thread instance will not be created if PreparedStatement.executeInternal method does not call ConnectionImpl.getCancelTimer method.

  Below is an excerpt from the source code of executeInternal method.
if (locallyScopedConnection.getEnableQueryTimeouts() &&
    this.timeoutInMillis != 0 &&
    locallyScopedConnection.versionMeetsMinimum(5, 0, 0))
{
    timeoutTask = new CancelTask(this);
    locallyScopedConnection
        .getCancelTimer()
        .schedule(timeoutTask, this.timeoutInMillis);
  The code snippet indicates that getCancelTimer method is not called if timeouts are not set.

  So, check your jdoconfig.xml. If DatastoreReadTimeoutMillis and/or DatastoreWriteTimeoutMillis are configured, comment them out during development.