提交 5a34bb4d 编写于 作者: L leonidr

8004584: Augment applet contextualization

Summary: Do not create the main AppContext for applets
Reviewed-by: art, ahgross
上级 7598c795
...@@ -394,27 +394,23 @@ public class LogManager { ...@@ -394,27 +394,23 @@ public class LogManager {
// from the execution stack. // from the execution stack.
Object ecx = javaAwtAccess.getExecutionContext(); Object ecx = javaAwtAccess.getExecutionContext();
if (ecx == null) { if (ecx == null) {
// fall back to AppContext.getAppContext() // fall back to thread group seach of AppContext
ecx = javaAwtAccess.getContext(); ecx = javaAwtAccess.getContext();
} }
context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class); if (ecx != null) {
if (context == null) { context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class);
if (javaAwtAccess.isMainAppContext()) { if (context == null) {
context = userContext; if (javaAwtAccess.isMainAppContext()) {
} else { context = userContext;
context = new LoggerContext(); } else {
// during initialization, rootLogger is null when context = new LoggerContext();
// instantiating itself RootLogger }
if (manager.rootLogger != null) javaAwtAccess.put(ecx, LoggerContext.class, context);
context.addLocalLogger(manager.rootLogger);
} }
javaAwtAccess.put(ecx, LoggerContext.class, context);
} }
} }
} else {
context = userContext;
} }
return context; return context != null ? context : userContext;
} }
private List<LoggerContext> contexts() { private List<LoggerContext> contexts() {
...@@ -539,9 +535,22 @@ public class LogManager { ...@@ -539,9 +535,22 @@ public class LogManager {
return logger; return logger;
} }
synchronized void ensureRootLogger(Logger logger) {
if (logger == manager.rootLogger)
return;
// during initialization, rootLogger is null when
// instantiating itself RootLogger
if (findLogger("") == null && manager.rootLogger != null) {
addLocalLogger(manager.rootLogger);
}
}
// Add a logger to this context. This method will only set its level // Add a logger to this context. This method will only set its level
// and process parent loggers. It doesn't set its handlers. // and process parent loggers. It doesn't set its handlers.
synchronized boolean addLocalLogger(Logger logger) { synchronized boolean addLocalLogger(Logger logger) {
ensureRootLogger(logger);
final String name = logger.getName(); final String name = logger.getName();
if (name == null) { if (name == null) {
throw new NullPointerException(); throw new NullPointerException();
......
...@@ -52,7 +52,6 @@ import sun.security.util.SecurityConstants; ...@@ -52,7 +52,6 @@ import sun.security.util.SecurityConstants;
*/ */
public public
class AppletSecurity extends AWTSecurityManager { class AppletSecurity extends AWTSecurityManager {
private AppContext mainAppContext;
//URLClassLoader.acc //URLClassLoader.acc
private static Field facc = null; private static Field facc = null;
...@@ -77,7 +76,6 @@ class AppletSecurity extends AWTSecurityManager { ...@@ -77,7 +76,6 @@ class AppletSecurity extends AWTSecurityManager {
*/ */
public AppletSecurity() { public AppletSecurity() {
reset(); reset();
mainAppContext = AppContext.getAppContext();
} }
// Cache to store known restricted packages // Cache to store known restricted packages
...@@ -312,7 +310,7 @@ class AppletSecurity extends AWTSecurityManager { ...@@ -312,7 +310,7 @@ class AppletSecurity extends AWTSecurityManager {
AppContext appContext = AppContext.getAppContext(); AppContext appContext = AppContext.getAppContext();
AppletClassLoader appletClassLoader = currentAppletClassLoader(); AppletClassLoader appletClassLoader = currentAppletClassLoader();
if ((appContext == mainAppContext) && (appletClassLoader != null)) { if (AppContext.isMainContext(appContext) && (appletClassLoader != null)) {
// If we're about to allow access to the main EventQueue, // If we're about to allow access to the main EventQueue,
// and anything untrusted is on the class context stack, // and anything untrusted is on the class context stack,
// disallow access. // disallow access.
......
...@@ -162,7 +162,8 @@ public final class AppContext { ...@@ -162,7 +162,8 @@ public final class AppContext {
} }
/* The main "system" AppContext, used by everything not otherwise /* The main "system" AppContext, used by everything not otherwise
contained in another AppContext. contained in another AppContext. It is implicitly created for
standalone apps only (i.e. not applets)
*/ */
private static volatile AppContext mainAppContext = null; private static volatile AppContext mainAppContext = null;
...@@ -204,25 +205,6 @@ public final class AppContext { ...@@ -204,25 +205,6 @@ public final class AppContext {
*/ */
private static final AtomicInteger numAppContexts = new AtomicInteger(0); private static final AtomicInteger numAppContexts = new AtomicInteger(0);
static {
// On the main Thread, we get the ThreadGroup, make a corresponding
// AppContext, and instantiate the Java EventQueue. This way, legacy
// code is unaffected by the move to multiple AppContext ability.
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
ThreadGroup currentThreadGroup =
Thread.currentThread().getThreadGroup();
ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
while (parentThreadGroup != null) {
// Find the root ThreadGroup to construct our main AppContext
currentThreadGroup = parentThreadGroup;
parentThreadGroup = currentThreadGroup.getParent();
}
mainAppContext = new AppContext(currentThreadGroup);
return null;
}
});
}
/* /*
* The context ClassLoader that was used to create this AppContext. * The context ClassLoader that was used to create this AppContext.
...@@ -266,6 +248,27 @@ public final class AppContext { ...@@ -266,6 +248,27 @@ public final class AppContext {
private static final ThreadLocal<AppContext> threadAppContext = private static final ThreadLocal<AppContext> threadAppContext =
new ThreadLocal<AppContext>(); new ThreadLocal<AppContext>();
private final static void initMainAppContext() {
// On the main Thread, we get the ThreadGroup, make a corresponding
// AppContext, and instantiate the Java EventQueue. This way, legacy
// code is unaffected by the move to multiple AppContext ability.
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
ThreadGroup currentThreadGroup =
Thread.currentThread().getThreadGroup();
ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
while (parentThreadGroup != null) {
// Find the root ThreadGroup to construct our main AppContext
currentThreadGroup = parentThreadGroup;
parentThreadGroup = currentThreadGroup.getParent();
}
mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup);
return null;
}
});
}
/** /**
* Returns the appropriate AppContext for the caller, * Returns the appropriate AppContext for the caller,
* as determined by its ThreadGroup. If the main "system" AppContext * as determined by its ThreadGroup. If the main "system" AppContext
...@@ -278,8 +281,10 @@ public final class AppContext { ...@@ -278,8 +281,10 @@ public final class AppContext {
* @since 1.2 * @since 1.2
*/ */
public final static AppContext getAppContext() { public final static AppContext getAppContext() {
if (numAppContexts.get() == 1) // If there's only one system-wide, // we are standalone app, return the main app context
return mainAppContext; // return the main system AppContext. if (numAppContexts.get() == 1 && mainAppContext != null) {
return mainAppContext;
}
AppContext appContext = threadAppContext.get(); AppContext appContext = threadAppContext.get();
...@@ -293,29 +298,37 @@ public final class AppContext { ...@@ -293,29 +298,37 @@ public final class AppContext {
// when new AppContext objects are created. // when new AppContext objects are created.
ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
ThreadGroup threadGroup = currentThreadGroup; ThreadGroup threadGroup = currentThreadGroup;
// Special case: we implicitly create the main app context
// if no contexts have been created yet. This covers standalone apps
// and excludes applets because by the time applet starts
// a number of contexts have already been created by the plugin.
if (numAppContexts.get() == 0) {
// This check is not necessary, its purpose is to help
// Plugin devs to catch all the cases of main AC creation.
if (System.getProperty("javaplugin.version") == null &&
System.getProperty("javawebstart.version") == null) {
initMainAppContext();
}
}
AppContext context = threadGroup2appContext.get(threadGroup); AppContext context = threadGroup2appContext.get(threadGroup);
while (context == null) { while (context == null) {
threadGroup = threadGroup.getParent(); threadGroup = threadGroup.getParent();
if (threadGroup == null) { if (threadGroup == null) {
// If we get here, we're running under a ThreadGroup that return null;
// has no AppContext associated with it. This should never
// happen, because createNewContext() should be used by the
// toolkit to create the ThreadGroup that everything runs
// under.
throw new RuntimeException("Invalid ThreadGroup");
} }
context = threadGroup2appContext.get(threadGroup); context = threadGroup2appContext.get(threadGroup);
} }
// In case we did anything in the above while loop, we add // In case we did anything in the above while loop, we add
// all the intermediate ThreadGroups to threadGroup2appContext // all the intermediate ThreadGroups to threadGroup2appContext
// so we won't spin again. // so we won't spin again.
for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
threadGroup2appContext.put(tg, context); threadGroup2appContext.put(tg, context);
} }
// Now we're done, so we cache the latest key/value pair. // Now we're done, so we cache the latest key/value pair.
// (we do this before checking with any AWTSecurityManager, so if
// this Thread equates with the main AppContext in the cache, it
// still will)
threadAppContext.set(context); threadAppContext.set(context);
return context; return context;
...@@ -323,19 +336,20 @@ public final class AppContext { ...@@ -323,19 +336,20 @@ public final class AppContext {
}); });
} }
if (appContext == mainAppContext) {
// Before we return the main "system" AppContext, check to
// see if there's an AWTSecurityManager installed. If so,
// allow it to choose the AppContext to return.
AppContext secAppContext = getExecutionAppContext();
if (secAppContext != null) {
appContext = secAppContext; // Return what we're told
}
}
return appContext; return appContext;
} }
/**
* Returns true if the specified AppContext is the main AppContext.
*
* @param ctx the context to compare with the main context
* @return true if the specified AppContext is the main AppContext.
* @since 1.8
*/
public final static boolean isMainContext(AppContext ctx) {
return (ctx != null && ctx == mainAppContext);
}
private final static AppContext getExecutionAppContext() { private final static AppContext getExecutionAppContext() {
SecurityManager securityManager = System.getSecurityManager(); SecurityManager securityManager = System.getSecurityManager();
if ((securityManager != null) && if ((securityManager != null) &&
...@@ -348,16 +362,6 @@ public final class AppContext { ...@@ -348,16 +362,6 @@ public final class AppContext {
return null; return null;
} }
/**
* Returns the main ("system") AppContext.
*
* @return the main AppContext
* @since 1.8
*/
final static AppContext getMainAppContext() {
return mainAppContext;
}
private long DISPOSAL_TIMEOUT = 5000; // Default to 5-second timeout private long DISPOSAL_TIMEOUT = 5000; // Default to 5-second timeout
// for disposal of all Frames // for disposal of all Frames
// (we wait for this time twice, // (we wait for this time twice,
...@@ -810,7 +814,7 @@ public final class AppContext { ...@@ -810,7 +814,7 @@ public final class AppContext {
return getAppContext().isDisposed(); return getAppContext().isDisposed();
} }
public boolean isMainAppContext() { public boolean isMainAppContext() {
return (numAppContexts.get() == 1); return (numAppContexts.get() == 1 && mainAppContext != null);
} }
public Object getContext() { public Object getContext() {
return getAppContext(); return getAppContext();
......
...@@ -117,8 +117,6 @@ public abstract class SunToolkit extends Toolkit ...@@ -117,8 +117,6 @@ public abstract class SunToolkit extends Toolkit
} }
public SunToolkit() { public SunToolkit() {
// 7122796: Always create an EQ for the main AppContext
initEQ(AppContext.getMainAppContext());
} }
public boolean useBufferPerWindow() { public boolean useBufferPerWindow() {
...@@ -281,11 +279,14 @@ public abstract class SunToolkit extends Toolkit ...@@ -281,11 +279,14 @@ public abstract class SunToolkit extends Toolkit
*/ */
public static AppContext createNewAppContext() { public static AppContext createNewAppContext() {
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
return createNewAppContext(threadGroup);
}
static final AppContext createNewAppContext(ThreadGroup threadGroup) {
// Create appContext before initialization of EventQueue, so all // Create appContext before initialization of EventQueue, so all
// the calls to AppContext.getAppContext() from EventQueue ctor // the calls to AppContext.getAppContext() from EventQueue ctor
// return correct values // return correct values
AppContext appContext = new AppContext(threadGroup); AppContext appContext = new AppContext(threadGroup);
initEQ(appContext); initEQ(appContext);
return appContext; return appContext;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册