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

Artem Ananiev artem.ananiev at oracle.com
Wed Jul 3 02:18:47 PDT 2013


On 7/3/2013 3:26 AM, Doug Zwick wrote:
> Michael Hall wrote:
>
>> On Jun 28, 2013, at 12:32 PM, Artem Ananiev wrote:
>>>
>>> This is a bug in eAWT, which uses SwingUtilities.invokeLater(),
>>> but should use SunToolkit.postEvent(AppContext, AWTEvent) or
>>> similar.
>>
>> This is the only place where invokeLater isn't thread safe?
>
> I would expect that invokeLater is not safe when called from a
> different AppContext. It looks like there is 1:1 correspondence
> between AppContext and the "main", "javawsSecurityThreadGroup" and
> "javawsApplicationThreadGroup" ThreadGroups, but this does not
> necessarily mean that the AppContext is bound to a Thread.
>
> From this old FAQ I concluded that Runnables queued via invokeLater
> from the wrong AppContext go to the wrong EDT:
>
> http://lopica.sourceforge.net/faq.html#two-event-queues
>
> Now all threads of a JWS app should run in the
> javawsApplicationThreadGroup and have the corresponding AppContext.
> However, taking a thread dump of our JWS app reveals that the AppKit
> thread is in the "main" ThreadGroup, and seems to use the
> corresponding AppContext when calling invokeLater, so any use of
> invokeLater on the AppKit thread would be expected to go to the Swing
> EDT corresponding to that context. In our case that is
> AWT-EventQueue-0 in the "main" ThreadGroup ("our" EDT is
> AWT-EventQueue-2 in the "javawsApplicationThreadGroup" ThreadGroup).
> As far as I have been able to determine, this is the only way you can
> get control into your application code with the wrong AppContext. I
> believe that the bugs in EAWT and the ScreenMenuBar implementation
> are manifestations of this (the JRE code was called back by native
> code on the AppKit thread, and they dispatched events or Runnables to
> the wrong EDT). Sending events directly to the right EDT, in the case
> of JNI callbacks, does not seem possible. It also does not appear
> possible to directly determine what the AppContext is, as AppContext
> seems to be defined in a non-public package, and I could find no way
> to directly interrogate it using public APIs. Using non-public APIs
> is not advisable, as they can change without notice.
>
> Leonid Romanov wrote:
>
>> What do you think about introducing a new API, like
>> SwingUtilities.invokeLater(Runnable runnable, Component target)
>> which would invoke the runnable using the target's AppContext? It
>> might be useful both for AWT/Swing engineers and apps writers.
>
>
> Arten Ananiev wrote:
>
>> Such API is useful, when your code is on a thread like the toolkit
>> thread (AppKit thread on OS X). So a better place would be
>> SunToolkit or SwingUtilities2, but SunToolkit already has a method
>> named executeOnEventHandlerThread().
>
>
> Something like this would be of benefit to OS X JNI implementors. If
> JNI code on other platforms can call back into Java code on the
> toolkit thread and the AppContext is not well defined (or wrong),
> then they would have need of it too. As it stands, I had to set up a
> utility thread with the right AppContext and a queue of Runnables
> (and the usual synchronize/wait/notify overhead to make it work) and
> have that thread use SwingUtilities.invokeLater to put things on the
> Swing thread when I queue them up from the AppKit thread. That is a
> bit painful and adds unnecessary latency, which such a utility would
> avoid. IIRC SunToolkit is not in a public package (i.e. a "java.xxx"
> or "javax.xxx" package). I don't see "SwingUtilities2" in a public
> package, either. I'd like to see such a utility provided in a public
> package, with the support commitments that that implies. Or perhaps
> better yet, having JNI itself somehow set the AppContext when a
> native thread calls back into the JVM.

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.

Note that desktop and applet/webstart apps are slightly different:

1. In desktop mode, a single AppContext is created for the system (root) 
thread group and all the sub-groups. There is one EDT and one event 
queue in the JVM, so invokeLater() always posts the event to the right 
queue.

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.

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.

Thanks,

Artem

> Also, is a Component the best way to key the AppContext? When writing
> JNI code (especially callbacks from system utilities) a Component
> instance isn't always handy. Ideally the AppContext itself should be
> used, but since it is not publicly available, that is problematic.
>
>
>
> 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