8004584: Augment applet contextualization
Do not create the main AppContext for applets Reviewed-by: art, ahgross
This commit is contained in:
parent
fcd5e6c404
commit
d76b61b2e8
@ -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 {
|
|||||||
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;
|
|||||||
*/
|
*/
|
||||||
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 {
|
|||||||
*/
|
*/
|
||||||
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 {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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 {
|
|||||||
*/
|
*/
|
||||||
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 {
|
|||||||
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 {
|
|||||||
* @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 {
|
|||||||
// 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 {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
|||||||
*/
|
*/
|
||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user