Introduction
A problem recently occurred when I was writing a distributed system. I wanted to allow access to some methods of ClassA
in package X
, to some other class, ClassB
in package Y
. So that is easy and I declare the methods public
so that ClassB
can invoke them. The problem with my system is that the classes are Services that are also to be invoked remotely in a distributed environment. In that case, the public
methods of ClassA
are available for invocation as well. I don't want to expose all of the methods in a remote API, but I still want them available if a direct reference to the object is available. In fact, the system uses several methods to solve this problem, but the following method is particularly elegant.
Background
This trick is part of the licas distributed service-based system.
Using the Code
What I can do is declare a local API class in the same package as ClassA
and make the methods in question protected. The LocalAPI
is not exposed as a remote Object
and so can be created locally only. So in package X
, we might have something like:
package X
public ClassA
{
protected method_1(param1, param2)
}
public Class LocalAPI
{
public method_1(param1, param2, classA)
{
classA.method_1(param1, param2);
}
}
Then in package Y
, we might have:
package Y
public ClassB
{
ClassA classA;
invoke_method_1()
{
LocalAPI lapi = new LocalAPI();
lapi.method_1(param1, param2, classA);
}
}
So ClassB
creates a LocalAPI
and uses the method with the same interface, except for the addition of the direct object reference. If I have a direct reference, I can invoke the public
API method, but if I don't have a direct reference, then I can't. If I try to do this through a remote invocation or Java Reflection, for example, it will fail:
package Z
public Class Invoke
{
}
Points of Interest
A flip-side of this might be that legacy objects with protected
method lists could be exposed as public if a similar LocalAPI
class was used to interface between them, using direct Object
references.