Wednesday Feb 17, 2010

Using an annotation processor to enforce Java-like access rules

Sometimes you need to expose a method from one class to another class, but do not wish to make this method public for anyone to call (because you are not prepared to maintain it compatibly forever). If they happen to be in the same package, you can just use package-private access. But this does not work if they are not in the same package.

Some module systems - NetBeans, OSGi - let you declare that some packages or classes are not to be accessed outside of the declaring module, even if marked public. The FriendPackages pattern can be useful in case you want to expose your method to a class in another package so long as that other package is private and is in the same module. But there are many cases where you want to make a method accessible to a particular caller in another module.

Ideally you could just use something like Java's public keyword - i.e., an annotation. But what would pay attention to that annotation? Well, an annotation processor. (At least at compile time; runtime access checks are another matter, but anyone using reflection probably knows how to call setAccessible anyway, so runtime checks would only be useful in security sandboxes.)

If you are compiling using JDK 7, the new AbstractTypeProcessor class in the Tree API lets you write annotation processors which not only can examine the full source tree, but get access to type information - such as what the receiver type of a method call is. This is critical.

I have started to prototype an annotation @Public which can be placed on a nominally public member to declare that it should be visible only to the enumerated classes; and an accompanying annotation processor: PublicProcessor By placing the JAR containing the annotation and its processor in your classpath, and compiling with JDK 7+ javac, you can have a new access modifier intermediate between package-private and public!

Thursday Jun 04, 2009

Chronicle of a ConcurrentModificationException Foretold

In a somewhat feverish mid-conference dream last night, I invented a new Java complexity metric. It is quite simple: the number of calls to methods which either return void or take no arguments or both, including calls to no-argument constructors.

As a quick example, you can see that any usages of the bean "pattern" will cause this count to shoot upwards rather quickly.

The metric is called the code's "omen".

Wednesday Sep 24, 2008

Many annotations are referentially @Opaque

Often Java elements (such as classes or methods) have meaning beyond their "denotational semantics": the name (or, occasionally, just presence) of the element itself is significant to how the application runs, beyond simple references from other Java source code. For example, a field marked with @javax.persistence.Column cannot be freely renamed or shuffled around according to traditional refactoring tools.

It would be great if there were a consistent way to mark these kinds of annotations. Authors of Java frameworks could then indicate to tools that Java elements marked with them need to be treated conservatively.

My suggestion is to introduce a meta-annotation (i.e. annotation placed on other annotations): @Opaque. Here is source code for the annotation and some possible example usages.

About

jglick

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today