POTD: Custom Access Modifier

My project of the day (or “POTD”) is Custom Access Modifier — an annotation and an enforcer that lets you define application-defined custom access modifiers,

So let me explain this a bit more. Say you have a library that people use, and say you are thinking about deprecating one of the methods. Yes, you can just put @Deprecated, but that doesn’t actually prevent people from continuing to use them. This is where you can put the custom access modifier, like this:

 
public class Library {
    @Deprecated @Restricted(DoNotUse.class)
    public void foo() {
        ...
    }
}

This causes compilation to fail for new source files that try to call the foo method. But at the resulting class file still contains the method, so existing applications continue to work. As per the JVM spec, this contraint enforcement is strictly in the user land and thus voluntary, and at the runtime there’s no check nor overhead.

Or say you have a “public” class that’s never intended to be used outside your library? Not a problem.

 
@Restricted(NoExternalUse.class)
public class FooBarImpl {
    ...
}

In the first version, I packaged the enforcer as a Maven mojo, but it should be trivial to write an Ant task or CLI. A real usability improvement is if this can be done as JSR-269 compatible annotation processor, but unfortunately the enforcer needs bytecode level access to the source files being compiled, and I don’t think JSR-269 gives me that, which is a pity.

The real flexibility here is that you can define your own access restrictions, not just using those that I provided out of the box.

The reason I came up with this is to better assist the feature deprecation in Hudson. With 6+ years of the code history, there are a fair amount of deprecated code in the foundation. We’d eventually like to remove them, but we can’t just delete them all the sudden — there might be plugins using them out there. But with this plugin, I can actually make sure that plugins are not using those deprecated features that are candidates for removal.

I hope you’ll find this tool useful. The source is on GitHub.

comments powered by Disqus