AppContext issue in Apple Java 6 -- same issue in Oracle Java 7?

Doug Zwick Doug.Zwick at blackboard.com
Wed Jul 3 09:21:25 PDT 2013


Artem Ananiev wrote:

> sun.awt.AppContext is designed to be completely invisible for
> applets/applications. You should never have to know what is the current
> AppContext, and whether other AppContexts exist in the same VM.

I agree 100%. The problem I am having is with edge cases where the correct AppContext is ambiguous. This happens because the AppKit thread must be shared between all Java AppContexts in the process.

> 2. In applet/webstart modes, there may be multiple AppContexts in the
> JVM. All the application code is supposed to run in a single AppContext,
> including all the helper threads running native code. If you create a
> new thread group, it will inherit the current AppContext. If you create
> a new thread group using another (not current) thread group as a
> parent... Well, you should not do that, and, actually, untrusted code is
> not allowed to do that.

Unfortunately this can happen by accident. If a native method running on the AppKit thread (or Toolkit thread) calls back into Java, and that Java method creates a Thread (or if the native code uses JNI to create a new Thread) without specifying the ThreadGroup, it will inherit the ThreadGroup of the AppKit (Toolkit) thread, which will be in some other context. We actually ran into this with a third-party library we are using. It created a Executor thread pool in the "main" ThreadGroup, presumably in a WebKit callback on the AppKit thread. That pool was used for sending callbacks from the 3rd party library into our code, which attempted to update our Swing UI. Or app would reliably deadlock within a few seconds of the WebKit component being shown.

> If there are multiple AppContexts in the same JVM, it's reasonable to
> assume that all of them run different applets (or Java Plugin code, or
> Java Web Start code). I don't see any scenarios, when an application or
> a 3rd-party library need to post events to multiple AppContexts.

Agreed 100%. Code should never post events to an AppContext belonging to "somebody else". To me, the solution is ensuring that code never runs in an environment where the AppContext is ambiguous. That is not the case for native code running on the AppKit thread. As long as that code stays in the native environment, the Java AppContext doesn't matter. It is when JNI is used to access the JVM that it matters. That would be the ideal place to bind the running code to the right AppContext. I don't know if that is a practical approach. If not, then the API pitched by Leonid would certainly work. Or perhaps just flag the AppKit thread as running in an ambiguous context, and throw an exception when attempting to do something requiring an AppContext.

The problem is that WebStart code using native callbacks and JNI must jump through non-obvious hoops in order to get things to work right. To solve this, we need to either have JNI get the code into the right context automatically, or provide a mechanism for the programmer to do so, either on the native side or on the Java side. Whatever approach is taken, unless it "just works" it needs to be public and well documented. Hiding it away in a private package does not help JNI programmers.

Lenoid Romanov wrote:

> The idea I had in mind when proposing this API was the following.
> Suppose a JNI call from the AppKit thread has been made. As a result,
> you want to execute a piece of Java code in the correct AppContext. But
> what is the correct AppContext? It depends. If that Java code doesn't do
> anything with UI, then it doesn't matter what AppContext it will be
> executed in. If it does, though, that is, it changes the state of some
> UI component, then you want that change to happen in the same AppContext
> where the UI component lives in. Hence the proposed Component parameter.

It is not clear, at least from the outside looking in, that UI is the only area effected by the AppContext. Even if that is the case today, will that continue in the future? Could things like signed applet privileges be specified by the AppContext? I don't know that a ThreadGroup would be any better. Some kind of opaque token identifying the AppContext would work. Given that the only identified vector at the moment is through JNI, it may well be practical to bury the context inside the JNIEnv data structure.


This email and any attachments may contain confidential and proprietary information of Blackboard that is for the sole use of the intended recipient. If you are not the intended recipient, disclosure, copying, re-distribution or other use of any of this information is strictly prohibited. Please immediately notify the sender and delete this transmission if you received this email in error.


More information about the macosx-port-dev mailing list