Search |
||
The Open Road: Superpackages
Thu, 2008-03-06
In this installment of The Open Road, Elliotte Rusty Harold looks at how JSR 294 superpackages, intended for inclusion in Java SE 7, will allow for the creation of hierarchical packages, allowing you to organize your code more cleanly and effectively. First though, here's an update on the status of the OpenJDK project. The latest JDK 7 release is b24, released December 4, 2007, which is no different from b23, except that b24 was built from Mercurial sources. There are now several significant OpenJDK projects, including the OpenJDK 6 project, a backport of the evolving GPL JDK 7 codebase to the JDK 6 spec. The OpenJDK 6 project just released b06. As described in Joe Darcy's blog, imaging classes have been moved from closed to open, JAX-WS 2.1 has been included, and the SNMP portion of the build has been modified to not fail when binary plugs are absent. Several other improvements are included. Now, on to JDK 7 and our first feature preview: superpackages. Here's Elliotte. Since Java 1.0, packages have offered a convenient means of organizing code into different namespaces at the source code level. Classes in the same package can see non-public, non-protected, and non-private methods and fields in other classes in the same package that classes in other packages cannot see. Unfortunately, there's no standard adjective for members that have no explicit access specifier. The most common, though by no means standard, name for these fields and methods seems to be "default" access. They're also sometimes referred to as "package protected" or "package private." The Java Language Specification uses "default (package)," and that is what I'll use in this article. How Packages Affect VisibilityFor example, consider the three classes in Examples 1, 2, and 3.
A cat can make a dog bark and a dog can make a cat meow, but
neither a cat nor a dog can get the bacon out of the refrigerator.
The refrigerator can make a dog salivate, but it can't make either
animal speak. This is because Example 1. A
Dog class in the
com.elharo.animals package
Example 2. A
Cat class also in the
com.elharo.animals package
Example 3. A class in a new package
Hierarchical Names, Flat NamespacesThe package naming convention is hierarchical, but the namespace
division isn't. The package namespace structure is flat. A class in
Ninety percent or more of the time, this doesn't matter all that much, but
occasionally there are problems. For example, the JDOM XML API put its core model classes
like Another common problem arises when writing unit tests. Test code
often needs to see parts of a class that the general public isn't
allowed to access. Sometimes test classes want to directly test
non-public methods. Other times they want to inject dependencies.
Usually you'd think test code belongs in a separate package.
However, many programmers put their tests in the same package as
the tested code precisely because they want to be able to access
the non-public parts. Alternatively, some programmers make methods
WorkaroundsThere are two common solutions to these problems in Java 6 and
earlier. The first is to make methods The other alternative is to place all related classes in the same package. That's a little safer, and it's usually what I do--for instance, in my JDOM alternative library XOM, the input and output classes are in the same package as the core classes precisely so they can see each others' internal parts--but this loses the benefits of organizing large code bases hierarchically. Look! Up in the sky! It's a Bird! It's a Plane! No, It's Superpackage!JSR 294
proposes to improve the situation in Java 7 by introducing
superpackages. A superpackage is a new construct that,
like an interface or a class, has its own .java file. This
.java file lives in the usual file system hierarchy and is
always named super-package.java. For example, a superpackage
for Example 4. A superpackage for
com.elharo.pets
Once the superpackage is created, only exported classes are
visible outside the superpackage. For example, the
Inside the superpackage, everything is the same as before. However, if a class is placed in a superpackage and is accessed from outside the superpackage, everything changes. By default, all access from outside the superpackage is blocked. It's as if all the classes inside the superpackage had suddenly become private. The superpackage barrier forms an event horizon from which information can only escape if it's explicitly exported. Note the difference between how packages are created and how superpackages are created: packages are created internally when classes declare themselves to be members of those packages. Superpackages are created externally in a separate file. Exporting and Hiding MethodsWhat has this bought us? Remember the issue is usually that you
have classes and methods you want to expose to other members of the
superpackage but not to the general public. For classes, the
problem is solved: make them For example, let's see how we'd use this to provide a test class the ability to inject a set of mock system properties into a class. Begin by assuming we have a class set up as in Example 5. Example 5. A class that loads the system properties
You want to test the stubborn class with various values for the
different system properties. However, that's going to be hard to do
because some of these properties, such as To allow the test case in the
Example 6. A class that allows the system properties to be
injected
Now the test code can inject the test properties directly into the class. Unfortunately, so can everyone else, and that can be both a security risk and a source of bugs. It also makes the API needlessly complex and larger than it should be. Instead, make the Example 7. A class that allows the system properties to be
injected
Then add a new public class in the same package that can see the
non-public Example 9. A class that allows the system properties to be
injected
Finally, define the superpackage for
Example 9. A superpackage for
com.elharo.examples
Voila! We now have a public API that exists only in the superpackage. The compiler and the virtual machine will enforce this. This does mean that neither source nor byte code that uses these features will be processable with Java 6 and earlier tools. However there are enough other changes coming in Java 7 that this was likely to be true with or without superpackages. Summing UpSuperpackages are one of the better ideas being floated for Java 7. They address a real pain point for many developers. However, they don't introduce a lot of confusing new syntax, and if you don't need them you can fairly safely ignore them. The one change I'd really like to see is better support for working at the method level rather than the class level. I'd like to be able to tag individual methods as exported or not, rather than working with entire classes at a time. The spec is still in early draft review, so time remains for changes to be made and the syntax to be improved, and I'm told a new access specifier to accomplish this is indeed under consideration for the next draft. Nonetheless, even in its current imperfect state, superpackages are a significant addition to the Java programmer's toolbox. Resources
»
Related Topics >>
JSR Programming
Comments
Comments are listed in date ascending order (oldest first)
|
||
|
|