提交 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 {
// from the execution stack.
Object ecx = javaAwtAccess.getExecutionContext();
if (ecx == null) {
// fall back to AppContext.getAppContext()
// fall back to thread group seach of AppContext
ecx = javaAwtAccess.getContext();
}
context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class);
if (context == null) {
if (javaAwtAccess.isMainAppContext()) {
context = userContext;
} else {
context = new LoggerContext();
// during initialization, rootLogger is null when
// instantiating itself RootLogger
if (manager.rootLogger != null)
context.addLocalLogger(manager.rootLogger);
if (ecx != null) {
context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class);
if (context == null) {
if (javaAwtAccess.isMainAppContext()) {
context = userContext;
} else {
context = new LoggerContext();
}
javaAwtAccess.put(ecx, LoggerContext.class, context);
}
javaAwtAccess.put(ecx, LoggerContext.class, context);
}
}
} else {
context = userContext;
}
return context;
return context != null ? context : userContext;
}
private List<LoggerContext> contexts() {
......@@ -539,9 +535,22 @@ public class LogManager {
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
// and process parent loggers. It doesn't set its handlers.
synchronized boolean addLocalLogger(Logger logger) {
ensureRootLogger(logger);
final String name = logger.getName();
if (name == null) {
throw new NullPointerException();
......
......@@ -52,7 +52,6 @@ import sun.security.util.SecurityConstants;
*/
public
class AppletSecurity extends AWTSecurityManager {
private AppContext mainAppContext;
//URLClassLoader.acc
private static Field facc = null;
......@@ -77,7 +76,6 @@ class AppletSecurity extends AWTSecurityManager {
*/
public AppletSecurity() {
reset();
mainAppContext = AppContext.getAppContext();
}
// Cache to store known restricted packages
......@@ -312,7 +310,7 @@ class AppletSecurity extends AWTSecurityManager {
AppContext appContext = AppContext.getAppContext();
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,
// and anything untrusted is on the class context stack,
// disallow access.
......
......@@ -162,7 +162,8 @@ public final class AppContext {
}
/* 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;
......@@ -204,25 +205,6 @@ public final class AppContext {
*/
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.
......@@ -266,6 +248,27 @@ public final class AppContext {
private static final ThreadLocal<AppContext> threadAppContext =
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,
* as determined by its ThreadGroup. If the main "system" AppContext
......@@ -278,8 +281,10 @@ public final class AppContext {
* @since 1.2
*/
public final static AppContext getAppContext() {
if (numAppContexts.get() == 1) // If there's only one system-wide,
return mainAppContext; // return the main system AppContext.
// we are standalone app, return the main app context
if (numAppContexts.get() == 1 && mainAppContext != null) {
return mainAppContext;
}
AppContext appContext = threadAppContext.get();
......@@ -293,29 +298,37 @@ public final class AppContext {
// when new AppContext objects are created.
ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
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);
while (context == null) {
threadGroup = threadGroup.getParent();
if (threadGroup == null) {
// If we get here, we're running under a ThreadGroup that
// 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");
return null;
}
context = threadGroup2appContext.get(threadGroup);
}
// In case we did anything in the above while loop, we add
// all the intermediate ThreadGroups to threadGroup2appContext
// so we won't spin again.
for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
threadGroup2appContext.put(tg, context);
}
// 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);
return context;
......@@ -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;
}
/**
* 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() {
SecurityManager securityManager = System.getSecurityManager();
if ((securityManager != null) &&
......@@ -348,16 +362,6 @@ public final class AppContext {
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
// for disposal of all Frames
// (we wait for this time twice,
......@@ -810,7 +814,7 @@ public final class AppContext {
return getAppContext().isDisposed();
}
public boolean isMainAppContext() {
return (numAppContexts.get() == 1);
return (numAppContexts.get() == 1 && mainAppContext != null);
}
public Object getContext() {
return getAppContext();
......
......@@ -117,8 +117,6 @@ public abstract class SunToolkit extends Toolkit
}
public SunToolkit() {
// 7122796: Always create an EQ for the main AppContext
initEQ(AppContext.getMainAppContext());
}
public boolean useBufferPerWindow() {
......@@ -281,11 +279,14 @@ public abstract class SunToolkit extends Toolkit
*/
public static AppContext createNewAppContext() {
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
return createNewAppContext(threadGroup);
}
static final AppContext createNewAppContext(ThreadGroup threadGroup) {
// Create appContext before initialization of EventQueue, so all
// the calls to AppContext.getAppContext() from EventQueue ctor
// return correct values
AppContext appContext = new AppContext(threadGroup);
initEQ(appContext);
return appContext;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册