src/share/classes/java/lang/Thread.java

Print this page




1633 
1634     /** cache of subclass security audit results */
1635     /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
1636      * release */
1637     private static class Caches {
1638         /** cache of subclass security audit results */
1639         static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
1640             new ConcurrentHashMap<>();
1641 
1642         /** queue for WeakReferences to audited subclasses */
1643         static final ReferenceQueue<Class<?>> subclassAuditsQueue =
1644             new ReferenceQueue<>();
1645     }
1646 
1647     /**
1648      * Verifies that this (possibly subclass) instance can be constructed
1649      * without violating security constraints: the subclass must not override
1650      * security-sensitive non-final methods, or else the
1651      * "enableContextClassLoaderOverride" RuntimePermission is checked.
1652      */
1653     private static boolean isCCLOverridden(Class cl) {
1654         if (cl == Thread.class)
1655             return false;
1656 
1657         processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1658         WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1659         Boolean result = Caches.subclassAudits.get(key);
1660         if (result == null) {
1661             result = Boolean.valueOf(auditSubclass(cl));
1662             Caches.subclassAudits.putIfAbsent(key, result);
1663         }
1664 
1665         return result.booleanValue();
1666     }
1667 
1668     /**
1669      * Performs reflective checks on given subclass to verify that it doesn't
1670      * override security-sensitive non-final methods.  Returns true if the
1671      * subclass overrides any of the methods, false otherwise.
1672      */
1673     private static boolean auditSubclass(final Class subcl) {
1674         Boolean result = AccessController.doPrivileged(
1675             new PrivilegedAction<Boolean>() {
1676                 public Boolean run() {
1677                     for (Class cl = subcl;
1678                          cl != Thread.class;
1679                          cl = cl.getSuperclass())
1680                     {
1681                         try {
1682                             cl.getDeclaredMethod("getContextClassLoader", new Class[0]);
1683                             return Boolean.TRUE;
1684                         } catch (NoSuchMethodException ex) {
1685                         }
1686                         try {
1687                             Class[] params = {ClassLoader.class};
1688                             cl.getDeclaredMethod("setContextClassLoader", params);
1689                             return Boolean.TRUE;
1690                         } catch (NoSuchMethodException ex) {
1691                         }
1692                     }
1693                     return Boolean.FALSE;
1694                 }
1695             }
1696         );
1697         return result.booleanValue();
1698     }
1699 
1700     private native static StackTraceElement[][] dumpThreads(Thread[] threads);
1701     private native static Thread[] getThreads();
1702 
1703     /**
1704      * Returns the identifier of this Thread.  The thread ID is a positive
1705      * <tt>long</tt> number generated when this thread was created.
1706      * The thread ID is unique and remains unchanged during its lifetime.
1707      * When a thread is terminated, this thread ID may be reused.




1633 
1634     /** cache of subclass security audit results */
1635     /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
1636      * release */
1637     private static class Caches {
1638         /** cache of subclass security audit results */
1639         static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
1640             new ConcurrentHashMap<>();
1641 
1642         /** queue for WeakReferences to audited subclasses */
1643         static final ReferenceQueue<Class<?>> subclassAuditsQueue =
1644             new ReferenceQueue<>();
1645     }
1646 
1647     /**
1648      * Verifies that this (possibly subclass) instance can be constructed
1649      * without violating security constraints: the subclass must not override
1650      * security-sensitive non-final methods, or else the
1651      * "enableContextClassLoaderOverride" RuntimePermission is checked.
1652      */
1653     private static boolean isCCLOverridden(Class<?> cl) {
1654         if (cl == Thread.class)
1655             return false;
1656 
1657         processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1658         WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1659         Boolean result = Caches.subclassAudits.get(key);
1660         if (result == null) {
1661             result = Boolean.valueOf(auditSubclass(cl));
1662             Caches.subclassAudits.putIfAbsent(key, result);
1663         }
1664 
1665         return result.booleanValue();
1666     }
1667 
1668     /**
1669      * Performs reflective checks on given subclass to verify that it doesn't
1670      * override security-sensitive non-final methods.  Returns true if the
1671      * subclass overrides any of the methods, false otherwise.
1672      */
1673     private static boolean auditSubclass(final Class<?> subcl) {
1674         Boolean result = AccessController.doPrivileged(
1675             new PrivilegedAction<Boolean>() {
1676                 public Boolean run() {
1677                     for (Class<?> cl = subcl;
1678                          cl != Thread.class;
1679                          cl = cl.getSuperclass())
1680                     {
1681                         try {
1682                             cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
1683                             return Boolean.TRUE;
1684                         } catch (NoSuchMethodException ex) {
1685                         }
1686                         try {
1687                             Class<?>[] params = {ClassLoader.class};
1688                             cl.getDeclaredMethod("setContextClassLoader", params);
1689                             return Boolean.TRUE;
1690                         } catch (NoSuchMethodException ex) {
1691                         }
1692                     }
1693                     return Boolean.FALSE;
1694                 }
1695             }
1696         );
1697         return result.booleanValue();
1698     }
1699 
1700     private native static StackTraceElement[][] dumpThreads(Thread[] threads);
1701     private native static Thread[] getThreads();
1702 
1703     /**
1704      * Returns the identifier of this Thread.  The thread ID is a positive
1705      * <tt>long</tt> number generated when this thread was created.
1706      * The thread ID is unique and remains unchanged during its lifetime.
1707      * When a thread is terminated, this thread ID may be reused.