Type (class/interface) visibility can be managed at three levels:

1, at Java language level, a type can be declared as either public, private, or package private. A public type is visible globally, a private type (usually as a private nested type) is visible only to the enclosing element, and a package private type is visible only in the current package. This is the most common mechanism for handling type visibility and information hiding.

2, at module level, a type can be declared via module metadata to be exported externally, or kept strictly internal. Examples of such module systems are OSGi, Jigsaw, JBoss Modules, etc. In a runtime environment based on such module framework, the dependency and interaction between module components are clearly defined. Public classes in a module are not externally exposed unless declared so.

3, at component level, an implementation class can be proxied or wrapped to mitigate any external exposure. With 1 & 2, some types may still end up being exposed. But that is not too bad with a proxy or wrapper. Even though the client application can load the proxied implementation class, but what is directly exposed is the immutable proxy/wrapper.

For example, getServletContext() returns an implementation of javax.servlet.ServletContext, but it will not be the actual implementation class in the application server. Instead it is most likely an immutable proxy that exposes what is needed in javax.servlet.ServletContext interface. The similar pattern is also used in the implementation of ServletRequest, ServletResponse, javax.ejb.EJBContext, javax.ejb.TimerService, etc.

Why do we want to hide certain types? A software module provides services by publishing essential interfaces and classes, which become the liability of the module. These published types are expected to be there and maintained for the life of the module. When it comes time to redesign, you will need to evaluate how to keep backward compatibility while evolving the API to adapt to the new technology. This is also the time you really wish these interfaces/classes/methods had never been exposed.

Java EE application deployed to application server is an interesting case. User-provided application code and application server code cooperate to make the app work, but they should also be isolated from each other and keep a respectful distance. Application server internal implementation types should be completely hidden from user applications for security purpose. If the application packages the same library that the server contains, care must be taken that the server does not inadvertently load the application's version via thread context classloader.
0

Add a comment

Labels
Archive
Popular Posts
Popular Posts
  • Two JVM options are often used to tune JVM heap size: -Xmx for maximum heap size, and -Xms for initial heap size. Here are some common mi...
  • Simple enum . The ; after the last element is optional, when this is the end of enum definition. public enum Color { WHITE, BLACK, RED, ...
  • How to set project classpath in Eclipse and NetBeans are similar: just right-click the project name, choose Properties to bring up the Prope...
  • Let's say I need to spawn multiple threads to do the work, and continue to the next step only after all of them complete. I will need t...
  • This is a sample web.xml based on Servlet 2.5 (part of Java EE 5) that declares common elements. All top-level elements are optional, and c...
  • The default string value for java enum is its face value, or the element name. However, you can customize the string value by overriding toS...
  • Prior to JDK 6, we can check if a string is empty in 2 ways: if(s != null && s.length() == 0) if(("").equals(s)) Checking ...
  • When writing javadocs, IntelliJ automatically adds a closing tag for html elements. For instance, after typing <lt>, it automaticaly a...
  • StringBuilder was introduced in JDK 1.5. What's the difference between StringBuilder and StringBuffer? According to javadoc , StringBu...
  • With array, we can easily declare and initialize it at the same time: String[] favorites = new String[] {"EJB", "JPA", ...
Loading