Q:

How to use @Nullable and @Nonnull annotations more effectively?

I can see that @Nullable and @Nonnull annotations could be helpful in preventing NullPointerExceptions but they do not propagate very far.

The effectiveness of these annotations drop off completely after one level of indirection, so if you only add a few they don't propagate very far. 
Since these annotations are not well enforced there is a danger of assuming a value marked with @Nonnull is not null and consequently not performing null checks. 

The code below causes a parameter marked with @Nonnull to be null without raising any complaints.  It throws a NullPointerException when it is run.
public class Clazz {
    public static void main(String[] args){
        Clazz clazz = new Clazz();

        // this line raises a complaint with the IDE (IntelliJ 11)
        clazz.directPathToA(null);

        // this line does not
        clazz.indirectPathToA(null); 
    }

    public void indirectPathToA(Integer y){
        directPathToA(y);
    }

    public void directPathToA(@Nonnull Integer x){
        x.toString(); // do stuff to x        
    }
}

Is there a way to make these annotations more strictly enforced and/or propagate further?

A:

Short answer: I guess these annotations are only useful for your IDE to warn you of potentially null pointer errors.
As said in the "Clean Code" book, you should check your public method's parameters and also avoid checking invariants.
Another good tip is never returning null values, but using Null Object Pattern instead.

A:

Other than your IDE giving you hints when you pass null to methods that expect the argument to not be null, there are further advantages:

Static code analysis tools can test the same as your IDE (e.g. FindBugs)
You can use AOP to check these assertions

This can help your code be more maintainable (since you do not need null checks) and less error-prone.

A:

I think this original question indirectly points to a general recommendation that run-time null-pointer check is still needed, even though @NonNull is used. Refer to the following link: 
Java 8's new Type Annotations
In the above blog, it is recommended that:

Optional Type Annotations are not a substitute for runtime validation
  Before Type Annotations, the primary location for describing things
  like nullability or ranges was in the javadoc. With Type annotations,
  this communication comes into the bytecode in a way for compile-time
  verification. Your code should still perform runtime validation.

