Problem with hiding the implementation

R

Royan

Imagine I have two classes in two packages:

package org.fooA;
class A {
}


package org.fooZ;
public class Z {
public Z() {
//I need to instantiate class A here
}
}

I have two conditions that I want to meet

1) I want to hide class A from an end user, someone who is going to
use my code, so I don't want this person to instantiate class A and
make use of its functionality.
2) I want to instantiate class A from my own class Z that resides in
another package

The problem is that whatever I think about does not meet both
conditions. For instance if class A is defined as "package-private"
class i can not use it myself, if it is public it is not hidden and
can be instantiated from any part of the code.
 
M

Mark Space

Royan said:
The problem is that whatever I think about does not meet both
conditions. For instance if class A is defined as "package-private"
class i can not use it myself, if it is public it is not hidden and
can be instantiated from any part of the code.

Even worse, even if you could make A private, the user could still
decompile your .jar file and get all your classes, even those that are
private.

http://mindprod.com/jgloss/decompiler.html

Java is very susceptible to decompilers. Java decompiles very well.

My suggestion: use RMI. Don't give the user the code at all.

The other way is to encrypt the bits in the class file, and decrypt them
when you need them. This is a little out of my league. You may have
some luck with Google here.
 
A

Alex.From.Ohio.Java

Imagine I have two classes in two packages:

package org.fooA;
class A {

}

package org.fooZ;
public class Z {
public Z() {
//I need to instantiate class A here
}

}

I have two conditions that I want to meet

1) I want to hide class A from an end user, someone who is going to
use my code, so I don't want this person to instantiate class A and
make use of its functionality.
2) I want to instantiate class A from my own class Z that resides in
another package

The problem is that whatever I think about does not meet both
conditions. For instance if class A is defined as "package-private"
class i can not use it myself, if it is public it is not hidden and
can be instantiated from any part of the code.

You are right. It's impossible. These 2 requirements are in
contravention of each other.

Java doesn't have "my own" and "others" packages. All packages are
equal. There are no modifiers to implement what you want.


Alex.
http://www.myjavaserver.com/~alexfromohio/
 
S

Stefan Ram

Royan said:
I want to hide class A from an end user,

Make it public, but use an uppercase greek Alpha as its name.
This letter looks exactly like an »A« - so an end user will
never find out that it is an alpha and he will not be able to
call it.

Another idea:

Make the constructor of A private.

Add an inner class AGenerator to A, which implements a factory
method to create an instance of A. So an object of this inner
class is an A factory object.

Now, add a method »passAGeneratorToZ« to A, which will call
»Z.acceptAGeneratorFromA« with the factory method.

When Z is loaded, its static initializer then will call
A.passAGeneratorToZ(). This method then will call
»Z.acceptAGeneratorFromA(factoryObject)« to pass a factory
object to the class Z.

Now Z has a factory object for A, which it can use in its
constructor to get a new instance of A. But the end user can
not get the factory object in the same way, because it is
hard-wired in A that it will only be passed to
»Z.acceptAGeneratorFromA« - never to an end user method.
 
S

Stefan Ram

Another idea:

public interface AGenerator
{ public A newA(); }

public class A
{ private A(){}

private static class AGeneratorImplementation implements AGenerator
{ public A newA(){ return new A(); }}

public static void passAGeneratorToZ()
{ Z.acceptAGeneratorFromA( new AGeneratorImplementation() ); }}

public class Z
{ public Z()
{ final A a = Z.aGenerator.newA(); }

static { A.passAGeneratorToZ(); }

static private AGenerator aGenerator;

public static void acceptAGeneratorFromA( final AGenerator aGenerator )
{ Z.aGenerator = aGenerator; }}
 
S

Stefan Ram

public static void acceptAGeneratorFromA( final AGenerator aGenerator )
{ Z.aGenerator = aGenerator; }}

It is still possible that some »end user« calls this method
and foists an illegal reference on it.
The following declaration makes this method more secure:

public static void acceptAGeneratorFromA( final AGenerator aGenerator )
{ if( aGenerator == null )throw new java.lang.NullPointerException();
if( Main.aGenerator == null )Main.aGenerator = aGenerator; }

Usually, immediatly upon initialization of its class the field
»aGenerator« will be set by this method to a non-zero value.
Any attempt to modify it later will be difficult for a third party,
because of the final if-statement.
 
C

CHAFIK Wassime

Royan said:
Imagine I have two classes in two packages:

package org.fooA;
class A {
}


package org.fooZ;
public class Z {
public Z() {
//I need to instantiate class A here
}
}

I have two conditions that I want to meet

1) I want to hide class A from an end user, someone who is going to
use my code, so I don't want this person to instantiate class A and
make use of its functionality.
2) I want to instantiate class A from my own class Z that resides in
another package

The problem is that whatever I think about does not meet both
conditions. For instance if class A is defined as "package-private"
class i can not use it myself, if it is public it is not hidden and
can be instantiated from any part of the code.
Hi
it may be an *OverKill* but an OSGi framework will give you exactly what
you are looking for since each bundle has its own ClassLoader and each
bundle exports some specific packages then making a public
packA.packB.Zclass available to all classes within the bundle bundleA
and exporting only packageA ,tadaaaaaaa, allow all other bundles to
import only packA and they simply can't see packA.packB
basically OSGi enable you to hide all the implementation details...
this is a link to KnopflerFish an implementation of OSGi
http://www.knopflerfish.org
you'll find there also a tutorial to help you make your first steps
hope that'll help you
and sorry for my english
 
T

thufir

Add an inner class AGenerator to A, which implements a factory method
to create an instance of A. So an object of this inner class is an A
factory object.

I think this is discussed fairly well in "effective java", if that helps.


-Thufir
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top