Extending a statically hidden class

I am using a library and I would like to extend one of its classes. My class "is of type A" and instances of A_Extension should be used whenever an object of type A is expected. Therefore the proper solution is inheritance.

More specifically:

import library.A;

publicclass A_Extensionextends A{

public A_Extension(){

DataStore aDataStore =new DataStore();//just a datastore, could be buffer, queue, etc.

super(aDataStore);

}

//override a couple of methods here. A has 5 public, a couple of package access and a couple

//of protected methods in total.

}

The problem is that A does not have a constructor that can take a DataStore as input. Yet, I can get an object of type A that contains a data store! Using a decompiler, I obtained:

//A.java

package library;

publicclass A{

...

static A create(DataStore aDataStore){

returnnew A_X(aDataStore);

}

}

--

//A_X.java

package library;

class A_Xextends A{

...

A_X(DataStore aDataStore){

...

}

}

How can I extend A_X? A solution would (NOT) be for A_Extension to contain a reference to an A object that has a datastore and then delegates public methods:

publicclass A_Extensionextends A{

private A a;

public A_Extension(){

this.a = A.create(new DataStore());

}

public m1(){

a.m1();

}

//but what happens to protected/ package access methods?

}

The only solution that I came up so far, is to decompile the whole library (or ask for the source code) and add my class into the "library" package, so that it is possible to directly extend class A_X. But this is "hacking".

Is there a possible way to do that? Or is it not, because class A_X is ompletely hidden until runtime? Is it perhaps that this is a well-known design pattern (that I am not aware of), so that the developer bans the users from altering the behaviour of an A object that contains a DataStore? Or is it a design flaw?

Thanks a lot. If my description is confusing, please say it in reply!

[3590 byte] By [ntalamaia] at [2007-11-26 19:56:03]
# 1
You don't have to be in the same jar file to be in the same package. Well unless its sealed or somethin. Create your own package structure with the same name, and your in.
_dnoyeBa at 2007-7-9 22:49:40 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

> You don't have to be in the same jar file to be in

> the same package. Well unless its sealed or

> somethin. Create your own package structure with the

> same name, and your in.

This is simply a more neat way than decompiling/ requesting the source code, right?

What if class Extension_A needs to be in another package as well (let mypackage that contains a lot of auxiliary classes). Then all classes of my package should be included to the library package, which is not correct as a design because they simply don't fit in there.

Thanks.

ntalamaia at 2007-7-9 22:49:40 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

Why would you want to extend A_X? How will your extended class be created and used in your application? A.create() will definitely not return it, unless you rewrite A (which would be a strange approach).

A obviously is a factory that hides the real implementation.

You should have your own factory returning your implementation of A.

stefan.schulza at 2007-7-9 22:49:40 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

> > You don't have to be in the same jar file to be in

> > the same package. Well unless its sealed or

> > somethin. Create your own package structure with

> the

> > same name, and your in.

>

> This is simply a more neat way than decompiling/

> requesting the source code, right?

Not exactly. But if you want to think of it that way...

>

> What if class Extension_A needs to be in another

> package as well (let mypackage that contains a lot of

> auxiliary classes). Then all classes of my package

> should be included to the library package, which is

> not correct as a design because they simply don't fit

> in there.

>

It is correct as a design because that is how the library desiner designed his code. You are the one trying to violate it. But you can not violate it. Only work around it.

> Thanks.

Anyway, you can always make a class more public. Just create an auxiliary class in the required package, and make that class public. Then extend that auxiliary class in your package. But this will mean unless you wrap the class, your class methods will also be public. But its no big deal to have public methods. The class itself can still be package private if you want.

If you are suggesting that you have many classes to deal with in this way, I suggest you get started :)

_dnoyeBa at 2007-7-9 22:49:40 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

> Why would you want to extend A_X? How will your

> extended class be created and used in your

> application? A.create() will definitely not return

> it, unless you rewrite A (which would be a strange

> approach).

My extended class's instances will be used like any A's instances, apart from having the additional synchronisation that I want/ need. I will simple do A_Extension obj = new A_Extension();

and pass this obj wherever A is expected.

> A obviously is a factory that hides the real

> implementation.

> You should have your own factory returning your

> implementation of A.

How is this possible, since my implementation of A needs to extend A_X and not A: a does not contain a data store, nor its methods can deal with data. So unless I reimplement A_X (actually copy-pasting from the decompiler) and add directly to it my extra behaviour, I have no (?) other way of getting my implementation.

ntalamaia at 2007-7-9 22:49:41 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

> > This is simply a more neat way than decompiling/

> > requesting the source code, right?

>

> Not exactly. But if you want to think of it that

> way...

I my thinking is that it is a much simpler/elegant way of violating package access restrictions. Of course by getting the source code, you can do many more (perhaps dodgy) things, but that's another issue.

> It is correct as a design because that is how the

> library desiner designed his code. You are the one

> trying to violate it. But you can not violate it.

> Only work around it.

I didn't expect that violating package access would be so easy.. Thanks for the tip.

>

> If you are suggesting that you have many classes to

> deal with in this way, I suggest you get started :)

Nope, I only need to extend this one. It is just the extended class that needed to be in another package (it logically belongs there) and also uses some auxiliary classes.

Now that my problem is solved I have two questions:

1) Why does Java allow violating package access so easily? It could perhaps demand that for two classes to belong to the same package, they should also belong to the same physical directory.

2) What could I do if A_X was private? Is there any easy work-around in this case? Or should I implement my own A_X? (perhaps by looking in the decompiler)

ntalamaia at 2007-7-9 22:49:41 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

> My extended class's instances will be used like any

> A's instances, apart from having the additional

> synchronisation that I want/ need. I will simple do

> A_Extension obj = new A_Extension();

and

> pass this obj wherever A is expected.

Ok, so, theoretically, you could create your own implementation of A.

> How is this possible, since my implementation of A

> needs to extend A_X and not A: a does not contain a

> data store, nor its methods can deal with data. So

> unless I reimplement A_X (actually copy-pasting from

> the decompiler) and add directly to it my extra

> behaviour, I have no (?) other way of getting my

> implementation.

Well, the original library creator intentionally didn't want anyone to change the behaviour and code he or she created. If it is a library, it should be accompanied by a license (complete or referred to). You should definitely respect the copyright on that library. As it obviously isn't open source, reusing the code is not intended or wished by the original author. The least you should do is ask him or her for what you want to do and if it would possible to get the respective license and code! Decompiling and copying code with no valid license is no option, really.

stefan.schulza at 2007-7-9 22:49:41 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

> Now that my problem is solved I have two questions:

> 1) Why does Java allow violating package access so

> easily? It could perhaps demand that for two classes

> to belong to the same package, they should also

> belong to the same physical directory.

It doesent. You have not violated package access. You have entered the package in order to gain access. This is perfectly legal. Now if you are thinking about package access as if its a security feature, that is incorrect. In any event, if you start using 'signed' jars, then I do not believe you can extend the package from outside of the signed jar.

> 2) What could I do if A_X was private? Is there any

> easy work-around in this case? Or should I implement

> my own A_X? (perhaps by looking in the decompiler)

classes can not be private. Well inner classes can I believe. IN that case, you would have a problem :)

_dnoyeBa at 2007-7-9 22:49:41 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

I believe this has been a fruitful discussion, at least from my side.

@stefan

phew... thanks for telling me... the binary (jar) comes with a license that prohibits any reverse engineering. Also, "Licensee may not modify the API ...". At least I can contact the authors for getting the source code (LGPL this time). I know its no excuse, but this is the first time I am using a library...

I agree on your other comment.

@_dnoyeB

Thanks for clarifying these security "thingies".

ntalamaia at 2007-7-9 22:49:41 > top of Java-index,Other Topics,Patterns & OO Design...