Sunday, February 23, 2020

Peril of reentrant defineClass: ClassCircularityError

Today I tried to make a Java application faster by eagerly loading a lot of classes into a classloader at once when the first of a set was requested. This did not work well. When the JVM loads a class in response to a defineClass call, it makes sure that there are no cycles in the inheritance hierarchy. This check is done immediately, requesting all parent classes from the classloader. If those haven't been loaded yet, my classloader would be called again (with the first defineClass call still on the call stack) and try to eagerly load a bunch of additional stuff. Apparently the JVM doesn't expect unrelated classes to be defined in this fallout from a defineClass call: if the next class defined isn't the next one up the inheritance hierarchy, a ClassCircularityError will be thrown even in the absence of actual circularity.

Friday, February 21, 2020

Implications of the Kotlin coroutines dispatcher initializing only once

I'm working on a project that tries to run several tasks in sandboxes in a Java process. It would be ideal to support Kotlin coroutines inside the sandboxes, but the default dispatcher causes a problem. The first time a coroutine is scheduled on the shared thread pool, the pool threads are started inside the current thread group. If that's triggered by trusted code, the threads belong to a trusted group but can be borrowed by untrusted coroutines. If the creation is triggered by untrusted code, the pool threads are associated with that one job which can be torn down, ruining the pool for any other jobs.

Since the pool is a static member of some internal class, I ended up needing to reload the coroutines library into each untrusted classloader. That way, every copy of the class has its own static members that are initialized inside the sandbox and apply only to one job.

Saturday, February 8, 2020

app-ads.txt for Google Play apps

I recently got an email from Google AdMob urging me to add an app-ads.txt file for one of my Google Play apps. This email directed me to a PDF of a technical specification which referred to another prior specification. While I could have spent the time digging into the details, it seemed strange to me that Google would say "here's the specs, go do the thing!" since they're usually quite developer-friendly. I looked through the specs a bit and tried researching what app-ads.txt is supposed to do and did not get far in the brief time I investigated.

But reading on in the email and poking around, I eventually discovered that understanding all the rules and goals of the file was not necessary. The AdMob console's "how to set up app-ads.txt" button mentioned by the email contains an AdMob-user-specific snippet that can be the entire content of the file. This was not clear to me because step 1 was to create the file "using the spec provided by the IAB Tech Lab."

So I specified an URL for my app in its Google Play listing, created app-ads.txt in its root as directed, and pasted the snippet into it. (I also went ahead and added a CONTACT line.) The next day, the AdMob console confirmed that the file was set up properly.