private static void checkAllowedInRealTime0(Object obj, int depth) throws InvalidClassException {
        if (depth >= MethodFrameCounter.MAX_STACK_DEPTH) { //todo: correct >? or >=?
            throw new RuntimeException();
        }
        Class<?> clazz = obj.getClass();

        if (clazz.getName().startsWith("java.") || clazz.getName().startsWith("javax.")) {
            checkAllowedInCompileTimeJdkType(clazz);
        } else {
            checkAllowedInCompileTimeCustomType(clazz);
        }        

        // array
        if (clazz.isArray()) {
            final int length = Array.getLength(obj);
            for (int k = 0; k < length; k++) {
                Object elem = Array.get(obj, k);
                checkAllowedInRealTime0(elem, depth + 1);
            }
        }
        // Collection
        if (Collection.class.isAssignableFrom(clazz)) {
            for (Object elem : ((Collection) obj)) {
                checkAllowedInRealTime0(elem, depth + 1);
            }
        }
        // Map
        if (Map.class.isAssignableFrom(clazz)) {
            for (Map.Entry<Object, Object> elem : ((Map<Object, Object>) obj).entrySet()) {
                checkAllowedInRealTime0(elem.getKey(), depth + 1);
                checkAllowedInRealTime0(elem.getValue(), depth + 1);
            }
        }
    }
private static void checkAllowedInRealTime0(Object obj, int depth) throws InvalidClassException {
        if (depth >= MethodFrameCounter.MAX_STACK_DEPTH) { 
            throw new RuntimeException();
        }
        Class<?> clazz = obj.getClass();

        if (clazz.getName().startsWith("java.") || clazz.getName().startsWith("javax.")) {
            checkAllowedInCompileTimeJdkType(clazz);
        } else {
            checkAllowedInCompileTimeCustomType(clazz);
        }        

        
        if (clazz.isArray()) {
            final int length = Array.getLength(obj);
            for (int k = 0; k < length; k++) {
                Object elem = Array.get(obj, k);
                checkAllowedInRealTime0(elem, depth + 1);
            }
        }
        
        if (Collection.class.isAssignableFrom(clazz)) {
            for (Object elem : ((Collection) obj)) {
                checkAllowedInRealTime0(elem, depth + 1);
            }
        }
        
        if (Map.class.isAssignableFrom(clazz)) {
            for (Map.Entry<Object, Object> elem : ((Map<Object, Object>) obj).entrySet()) {
                checkAllowedInRealTime0(elem.getKey(), depth + 1);
                checkAllowedInRealTime0(elem.getValue(), depth + 1);
            }
        }
    }
private static void checkAllowedInRealTime0 ( Object obj , int depth ) throws InvalidClassException { if ( depth >= MethodFrameCounter . MAX_STACK_DEPTH ) { //todo: correct >? or >=? throw new RuntimeException ( ) ; } Class < ? > clazz = obj . getClass ( ) ; if ( clazz . getName ( ) . startsWith ( "java." ) || clazz . getName ( ) . startsWith ( "javax." ) ) { checkAllowedInCompileTimeJdkType ( clazz ) ; } else { checkAllowedInCompileTimeCustomType ( clazz ) ; } // array if ( clazz . isArray ( ) ) { final int length = Array . getLength ( obj ) ; for ( int k = 0 ; k < length ; k ++ ) { Object elem = Array . get ( obj , k ) ; checkAllowedInRealTime0 ( elem , depth + 1 ) ; } } // Collection if ( Collection . class . isAssignableFrom ( clazz ) ) { for ( Object elem : ( ( Collection ) obj ) ) { checkAllowedInRealTime0 ( elem , depth + 1 ) ; } } // Map if ( Map . class . isAssignableFrom ( clazz ) ) { for ( Map . Entry < Object , Object > elem : ( ( Map < Object , Object > ) obj ) . entrySet ( ) ) { checkAllowedInRealTime0 ( elem . getKey ( ) , depth + 1 ) ; checkAllowedInRealTime0 ( elem . getValue ( ) , depth + 1 ) ; } } }
With stack counter

@param obj
@param depth of
@throws InvalidClassException
With stack counter