edu.rice.cs.cunit.threadCheck
Class ThreadCheck

java.lang.Object
  extended by edu.rice.cs.cunit.threadCheck.ThreadCheck

public class ThreadCheck
extends java.lang.Object

Class that checks whether threads may execute certain classes at runtime..

Author:
Mathias Ricken

Nested Class Summary
static class ThreadCheck.ArgumentPredicateViolation
           
static class ThreadCheck.ExceptionInArgumentPredicateViolation
           
static class ThreadCheck.ExceptionInPredicateViolation
           
static class ThreadCheck.NotRunByIdViolation
           
static class ThreadCheck.NotRunByThreadGroupViolation
           
static class ThreadCheck.NotRunByThreadNameViolation
           
static class ThreadCheck.OnlyRunByViolation
           
static class ThreadCheck.PredicateViolation
           
static class ThreadCheck.ReflectionPredicateViolation
           
static class ThreadCheck.ThreadCheckAnnotationRecord
          Storage class for predicate annotations.
static class ThreadCheck.Violation
           
 
Field Summary
private static java.util.Map<java.lang.Thread,java.util.HashSet<java.lang.String>> _allowedGroups
          Map from thread to a list of allowed thread group names for the next call of checkCurrentThread_OnlyRunBy.
private static java.util.Map<java.lang.Thread,java.util.HashSet<java.lang.Long>> _allowedIds
          Map from thread to a list of allowed ids for the next call of checkCurrentThread_OnlyRunBy.
private static java.util.Map<java.lang.Thread,java.util.HashSet<java.lang.String>> _allowedNames
          Map from thread to a list of allowed thread names for the next call of checkCurrentThread_OnlyRunBy.
private static java.util.Map<java.lang.Thread,java.lang.Boolean> _allowEventThread
          Map from thread to a boolean indicating whether the event thread is allowed to run.
private static long _checkCount
          Number of checks performed.
private static java.util.HashSet<java.lang.Thread> _inCheckCode
          True if the code currently executing is due to thread checking; used to avoid infinite recursions.
private static java.io.PrintWriter _log
          PrintWriter with the warning log.
private static java.io.ObjectOutputStream _logData
          ObjectOutputStream with the warning log as data.
private static long _violationCount
          Number of violationms found.
static java.lang.String DEFAULT_DAT_SUFFIX
          Default filename for the data log, if none specified by Java property.
static java.lang.String DEFAULT_LOG_FILENAME
          Default filename for the log, if none specified by Java property.
static java.lang.String LOG_FILENAME_PROPERTY
          Name of the Java property that determines the log filename.
 
Constructor Summary
ThreadCheck()
           
 
Method Summary
static void addAllowedGroup_OnlyRunBy(java.lang.String allowed)
          Add an allowed group name pattern to the list.
static void addAllowedId_OnlyRunBy(long allowed)
          Add an allowed id to the list.
static void addAllowedName_OnlyRunBy(java.lang.String allowed)
          Add an allowed thread name pattern to the list.
static java.lang.Boolean checkCombineAnnotation(java.lang.annotation.Annotation ann, Combine co, java.lang.Object thisO, java.lang.Object[] methodArgs)
          Handle a @Combine-style annotation.
static void checkCurrentThread_OnlyRunBy()
          Check if the current thread's name, id or, or group matches any of items in the three _allowed* lists, and if that is NOT the case, records a warning.
static void checkCurrentThread_Predicate(boolean predicateResult, java.lang.String predicateClass)
          Check if a predicate has failed, and if so, log a violation.
static void checkCurrentThread_Predicate(java.lang.Object[] args, boolean predicateResult, java.lang.String predicateClass)
          Check if a predicate has failed, and if so, log a violation.
static void checkCurrentThread_PredicateException(java.lang.Throwable t, java.lang.Object[] args, java.lang.String predicateClass)
          Log an exception in a predicate.
static void checkCurrentThread_PredicateException(java.lang.Throwable t, java.lang.String predicateClass)
          Log an exception in a predicate.
static void checkCurrentThreadGroup(java.lang.String threadGroupName)
          Check if the current thread matches the regex for the thread group name, and if this is true, records a warning.
static void checkCurrentThreadId(long threadId)
          Check if the current thread matches the thread ID, and if this is true, records a warning.
static void checkCurrentThreadName(java.lang.String threadName)
          Check if the current thread matches the regex for the thread name, and if that is the case, records a warning.
static void checkCurrentThreadReflection(java.lang.Class callerClass, java.lang.String methodName, java.lang.String methodDesc, java.lang.Object thisO, java.lang.Object[] methodArgs)
          Checks if the current thread may execute the method from where this method was called purely using reflection.
static void checkForSubtypingClassWarnings(java.lang.Class cf, java.lang.reflect.Method mi, java.lang.Class scf, ThreadCheck.ThreadCheckAnnotationRecord classAR, ThreadCheck.ThreadCheckAnnotationRecord superClassAR)
          Check for subtyping warnings.
static java.lang.Boolean checkPredicateLinkAnnotation(java.lang.annotation.Annotation ann, PredicateLink pl, java.lang.Object thisO, java.lang.Object[] methodArgs)
          Handle a @PredicateLink-style annotation.
static java.lang.String form(java.lang.String word, long count)
          Return the correct form, singular or plural, of the word, depending on the count.
static ThreadCheck.ThreadCheckAnnotationRecord getClassAnnotations(java.lang.Class cf)
          Get the annotations for the specified class file.
static ThreadCheck.ThreadCheckAnnotationRecord getMethodAnnotations(java.lang.Class cf, java.lang.reflect.Method mi)
          Get the annotations for the specified method in the specified class file.
static java.lang.String getMethodDescriptor(java.lang.reflect.Method m)
          Return the method descriptor for the method.
static java.lang.reflect.Method getMethodWithNameAndDescriptor(java.lang.Class methodClass, java.lang.String methodName, java.lang.String methodDesc)
          Return the method with the specified name and descriptor.
static ThreadCheck.ThreadCheckAnnotationRecord getPredicateSets(java.lang.annotation.Annotation[] annotations)
          Get the predicate sets from the array of annotations.
private static void initLog()
          Initialize the error log.
private static java.lang.Boolean processCombineMember(java.lang.annotation.Annotation member, PredicateLink memberPL, Combine memberCO, java.lang.Object thisO, java.lang.Object[] methodArgs)
          Process the value of a member annotation in a @Combine-style annotation.
static void setAllowedEventThread_OnlyRunBy(boolean realized)
          Allow the event thread at the next call of checkCurrentThread_OnlyRunBy.
static void writeLog(ThreadCheck.Violation v)
          Write to the error log, and potentially initialize it first.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

LOG_FILENAME_PROPERTY

public static final java.lang.String LOG_FILENAME_PROPERTY
Name of the Java property that determines the log filename.

See Also:
Constant Field Values

DEFAULT_LOG_FILENAME

public static final java.lang.String DEFAULT_LOG_FILENAME
Default filename for the log, if none specified by Java property.

See Also:
Constant Field Values

DEFAULT_DAT_SUFFIX

public static final java.lang.String DEFAULT_DAT_SUFFIX
Default filename for the data log, if none specified by Java property.

See Also:
Constant Field Values

_inCheckCode

private static volatile java.util.HashSet<java.lang.Thread> _inCheckCode
True if the code currently executing is due to thread checking; used to avoid infinite recursions.


_log

private static volatile java.io.PrintWriter _log
PrintWriter with the warning log.


_logData

private static volatile java.io.ObjectOutputStream _logData
ObjectOutputStream with the warning log as data.


_checkCount

private static volatile long _checkCount
Number of checks performed.


_violationCount

private static volatile long _violationCount
Number of violationms found.


_allowedNames

private static volatile java.util.Map<java.lang.Thread,java.util.HashSet<java.lang.String>> _allowedNames
Map from thread to a list of allowed thread names for the next call of checkCurrentThread_OnlyRunBy.


_allowedIds

private static volatile java.util.Map<java.lang.Thread,java.util.HashSet<java.lang.Long>> _allowedIds
Map from thread to a list of allowed ids for the next call of checkCurrentThread_OnlyRunBy.


_allowedGroups

private static volatile java.util.Map<java.lang.Thread,java.util.HashSet<java.lang.String>> _allowedGroups
Map from thread to a list of allowed thread group names for the next call of checkCurrentThread_OnlyRunBy.


_allowEventThread

private static volatile java.util.Map<java.lang.Thread,java.lang.Boolean> _allowEventThread
Map from thread to a boolean indicating whether the event thread is allowed to run.

Constructor Detail

ThreadCheck

public ThreadCheck()
Method Detail

checkCurrentThreadName

public static void checkCurrentThreadName(java.lang.String threadName)
Check if the current thread matches the regex for the thread name, and if that is the case, records a warning.

Parameters:
threadName - regex of a thread name that the current thread's name may NOT match

checkCurrentThreadId

public static void checkCurrentThreadId(long threadId)
Check if the current thread matches the thread ID, and if this is true, records a warning.

Parameters:
threadId - ID number that the current thread's ID may not match

checkCurrentThreadGroup

public static void checkCurrentThreadGroup(java.lang.String threadGroupName)
Check if the current thread matches the regex for the thread group name, and if this is true, records a warning.

Parameters:
threadGroupName - regex of a thread group name that the current thread's group name may NOT match

writeLog

public static void writeLog(ThreadCheck.Violation v)
Write to the error log, and potentially initialize it first.

Parameters:
v - violation to log

initLog

private static void initLog()
Initialize the error log.


addAllowedName_OnlyRunBy

public static void addAllowedName_OnlyRunBy(java.lang.String allowed)
Add an allowed thread name pattern to the list.

Parameters:
allowed - regex that is allowed

addAllowedId_OnlyRunBy

public static void addAllowedId_OnlyRunBy(long allowed)
Add an allowed id to the list.

Parameters:
allowed - id that is allowed

addAllowedGroup_OnlyRunBy

public static void addAllowedGroup_OnlyRunBy(java.lang.String allowed)
Add an allowed group name pattern to the list.

Parameters:
allowed - regex that is allowed

setAllowedEventThread_OnlyRunBy

public static void setAllowedEventThread_OnlyRunBy(boolean realized)
Allow the event thread at the next call of checkCurrentThread_OnlyRunBy.

Parameters:
realized - true if the component has been realized (or if the check should always be performed)

checkCurrentThread_OnlyRunBy

public static void checkCurrentThread_OnlyRunBy()
Check if the current thread's name, id or, or group matches any of items in the three _allowed* lists, and if that is NOT the case, records a warning.


checkCurrentThread_Predicate

public static void checkCurrentThread_Predicate(boolean predicateResult,
                                                java.lang.String predicateClass)
Check if a predicate has failed, and if so, log a violation.

Parameters:
predicateResult - result of the call to the predicate method
predicateClass - name of the predicate (name of the annotation)

checkCurrentThread_Predicate

public static void checkCurrentThread_Predicate(java.lang.Object[] args,
                                                boolean predicateResult,
                                                java.lang.String predicateClass)
Check if a predicate has failed, and if so, log a violation.

Parameters:
args - method arguments
predicateResult - result of the call to the predicate method
predicateClass - name of the predicate (name of the annotation)

checkCurrentThread_PredicateException

public static void checkCurrentThread_PredicateException(java.lang.Throwable t,
                                                         java.lang.String predicateClass)
Log an exception in a predicate.

Parameters:
t - exception thrown
predicateClass - name of the predicate (name of the annotation)

checkCurrentThread_PredicateException

public static void checkCurrentThread_PredicateException(java.lang.Throwable t,
                                                         java.lang.Object[] args,
                                                         java.lang.String predicateClass)
Log an exception in a predicate.

Parameters:
t - exception thrown
args - method arguments
predicateClass - name of the predicate (name of the annotation)

checkCurrentThreadReflection

public static void checkCurrentThreadReflection(java.lang.Class callerClass,
                                                java.lang.String methodName,
                                                java.lang.String methodDesc,
                                                java.lang.Object thisO,
                                                java.lang.Object[] methodArgs)
Checks if the current thread may execute the method from where this method was called purely using reflection. If it may not execute, a violation is logged.

Parameters:
callerClass - class of the caller
methodName - name of the method
methodDesc - descriptor of the method
thisO - value of this, or null in a static context
methodArgs - array of method arguments, or null if none passed

checkPredicateLinkAnnotation

public static java.lang.Boolean checkPredicateLinkAnnotation(java.lang.annotation.Annotation ann,
                                                             PredicateLink pl,
                                                             java.lang.Object thisO,
                                                             java.lang.Object[] methodArgs)
Handle a @PredicateLink-style annotation.

Parameters:
ann - annotation
pl - associated @PredicateLink
thisO - value of this, or null
Returns:
false if there was a violation, or null if there was an error

checkCombineAnnotation

public static java.lang.Boolean checkCombineAnnotation(java.lang.annotation.Annotation ann,
                                                       Combine co,
                                                       java.lang.Object thisO,
                                                       java.lang.Object[] methodArgs)
Handle a @Combine-style annotation.

Parameters:
ann - annotation
co - associated @Combine
thisO - value of this, or null
methodArgs - array of method arguments, or null if none passed
Returns:
false if there was a violation, or null if there was an error

processCombineMember

private static java.lang.Boolean processCombineMember(java.lang.annotation.Annotation member,
                                                      PredicateLink memberPL,
                                                      Combine memberCO,
                                                      java.lang.Object thisO,
                                                      java.lang.Object[] methodArgs)
Process the value of a member annotation in a @Combine-style annotation.

Parameters:
member - member annotation
memberPL - @PredicateLink meta-annotation associated with this member
memberCO - @Combine meta-annotation associated with this member
thisO - value of this
methodArgs - array of method arguments, or null if none passed
Returns:
true if permitted, false if violation, or null if error occurred.

getMethodWithNameAndDescriptor

public static java.lang.reflect.Method getMethodWithNameAndDescriptor(java.lang.Class methodClass,
                                                                      java.lang.String methodName,
                                                                      java.lang.String methodDesc)
Return the method with the specified name and descriptor.

Parameters:
methodClass - class
methodName - name
methodDesc - descriptor
Returns:
method, or null

getMethodDescriptor

public static java.lang.String getMethodDescriptor(java.lang.reflect.Method m)
Return the method descriptor for the method.

Parameters:
m - method
Returns:
descriptor

form

public static java.lang.String form(java.lang.String word,
                                    long count)
Return the correct form, singular or plural, of the word, depending on the count.

Parameters:
word - word
count - count
Returns:
word+"s" if count!=1, or word if count==1

getMethodAnnotations

public static ThreadCheck.ThreadCheckAnnotationRecord getMethodAnnotations(java.lang.Class cf,
                                                                           java.lang.reflect.Method mi)
Get the annotations for the specified method in the specified class file.

Parameters:
cf - class file
mi - method information
Returns:
annotations

getClassAnnotations

public static ThreadCheck.ThreadCheckAnnotationRecord getClassAnnotations(java.lang.Class cf)
Get the annotations for the specified class file.

Parameters:
cf - class file
Returns:
annotations

getPredicateSets

public static ThreadCheck.ThreadCheckAnnotationRecord getPredicateSets(java.lang.annotation.Annotation[] annotations)
Get the predicate sets from the array of annotations.

Parameters:
annotations - array of annotations
Returns:
annotation record.

checkForSubtypingClassWarnings

public static void checkForSubtypingClassWarnings(java.lang.Class cf,
                                                  java.lang.reflect.Method mi,
                                                  java.lang.Class scf,
                                                  ThreadCheck.ThreadCheckAnnotationRecord classAR,
                                                  ThreadCheck.ThreadCheckAnnotationRecord superClassAR)
Check for subtyping warnings.

Parameters:
cf - class file
mi - method information, or null if on class level
scf - superclass/interface class file
classAR - subclass annotations
superClassAR - superclass annotations