Home > CodeProject > Emulate the Internal keyword in Java

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 checks if a class is tagged as internal. But it’s 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 cutom 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 programing, 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.

About these ads
Categories: CodeProject
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: