Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

Emulate the internal keyword in Java

, 4 Apr 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
Emulate the internal keyword in Java.

C# introduced the internal keyword to enables information hiding across program boundaries. It can improve the ease of maintenance on much larger programs. When a public class is declared as internal, it’s accessible from the assembly containing this class, but hidden from any other assembly using it.

Java doesn’t have an equivalent of the internal keyword, and not provides any solution out of the box to have the same behavior.

Let’s declare a class Test like this:

package com.sample;
class Test
{
}

The class Test is visible inside the package but not outside it, and if we declare Test as public, it will be visible from any class inside or outside the jar.

What’s the solution we have to make the class test visible inside the jar and hidden from any other jar?

Alternatives

1. Naming convention

The method most used to inform that some classes are internals is to put them inside a package named internal, for example here are all internal packages from the hibernate core jar.

internal

With this solution we inform the library user that these classes are internals, but they can be instantiated from other jars.

2. Custom class loader

To resolve the issue of the first alternative, we have to not accept the instantiation of classes inside internal package, for that we have to know how they are instantiated.

ClassLoader:

The Java Classloader is a part of the Java Runtime Environment that dynamically loads Java classes into the Java Virtual Machine. Usually classes are only loaded on demand.

It is the class responsible for finding and loading class files at run time. Creating your own ClassLoader lets you customize the JVM in useful and interesting ways, allowing you to completely redefine how class files are brought into the system.

To have more control over class instantiation, we can create our own class loader and add a custom logic. And in this case we can refuse the creation of a specific class if it’s inside an internal package. And to use our custom class loader the setContextClassLoader method is invoked.

We can improve this solution by defining an internal annotation instead of checking the package name, for example we can declare an internal class like this:

@internal
public class InternalClass
{
}

And the custom class loader check if a class is tagged as internal. But its not perfect yet, the drawback of this solution is that the using of internal class is detected at runtime and not when compiling the code, refusing the creation of internal class could create problems in production environment. To avoid this behavior we can only log a warning instead of refusing the creation.

And to check the not using of internal classes at the development level, we can use JArchitect and create a custom CQLinq query like this:

from t in Types where
t.TypesUsingMe.Where(a=>a.ParentProject!=t.ParentProject).Count()>0 && t.HasAnnotation("internal")
select t

What’s interesting with the custom class loader solution is that we can restrict a package to use only some specified packages.

3. External Framework

OSGi became very popular today, thanks to its modularity approach and its capability to enforce logical boundaries between modules. OSGI is an example of framework using a custom class loader to define many rules related to visibility and accessibility between packages and jars.

OSGI give us many possibilities to define logical boundaries and emulate the internal behavior, here’s a post describing the OSGI framework.

4)Wait for java 9

Java 9 will come with jigsaw another alternative to OSGI to simplify modular programming, and in this case the JRE class loader is modified to restrict the creation of classes depending on configuration files defining the boundaries. This post describe the jigsaw alternative.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Issam Lahlali
Software Developer (Senior)
United States United States
CppDepend lead developer.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150326.1 | Last Updated 4 Apr 2013
Article Copyright 2013 by Issam Lahlali
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid