9

Hi is there a way to copy one class loaded context (atrributes etc) from one classloader (for instance a 'made' class Point) to another classloader?

Making clear, Example: I have an object Point on CL 1. Now running on another CL2, I want to creat this object in CL 3.

Some obj:

class Point {
int x;
int y;
public Point() {}
//getters and setters

Scenery:

... 
class CL2 {

// Running on CL 2
...
// Point obj from CL 1
Object point = gotFromCL1();

// Want to create the object on Cl2
Object pointCL2 = point.conversion();

But I can't use sun.reflection (not available) and serialization doesn't work since CL2 automatically "reconstruct" the object with CL 1.

One solution that I tought was do an "100%" java reflection rconstruct, basically getting the fields of object from CL2 and setting up on the new obj.

PS: It needs to run on Java 1.4.2 :'(

2
  • Can you please elaborate a bit more about the context of the problem? Tell a bit more about the functional requirements and the actual problem for which you think that this is the solution. First thing which comes to mind is that you're actually looking for serialization. Commented Nov 16, 2009 at 21:50
  • Great question. Unfortunately, no good answer: I have two classloaders, one of which knows a class and one which doesn't. Commented Mar 21, 2010 at 23:19

5 Answers 5

7

See Transloader on how to copy classes between ClassLoaders if you need to do one of the following:

  • Clone almost any object graph from one ClassLoader to another

  • Take any object from a foreign ClassLoader and invoke any method on it without cloning it

Sign up to request clarification or add additional context in comments.

2 Comments

Since I can't use sun.reflect which is massively used there :'(
Then, update the question with all relevant information. There might still be people out there which may help you, if they know what kind of problem you have and what kind of restrictions the solution has. For example, if you want to map objects with the same or similar structure, but which are loaded from different classes, you also could use a Bean Mapper library such as Dozer.
1

PowerMock classloading also provides something similar to TransLoader and it supports more advance use cases such as (some) reflection. You can easily execute a Runnable or Callable:

ClassloaderExecutor cle = new ClassloaderExecutor(classloader);
cle.execute(aRunnable); 
Object result = cle.execute(aCallable); // Result is cloned back to original CL

Have a look at the test case in the svn repo.

It's also available in Maven:

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-classloading</artifactId>
    <version>1.4.6</version>
</dependency>  

Comments

0

If the class is as simple as you describe it in your case, you could look at XMLEncoder. There are significant restrictions using it, but in simple cases it should get the job done.

EDIT: Given this limitation, I would say put the data in a Map and use that. You could even have the two classes store their state in a Map internally so that movement is pretty fluid.

If that can't work, then it looks like you are facing a roll your own XML/JSON or just plain CSV, depending on the complexity of the data.

4 Comments

Good idea, but unfortunately I'm working on ME cdc pbp , and I have a limited bean :(, I unfortunately dont have xmlencoder there :'( Any simpler solution?
I can't put the data on a map since I don't know what kind of object I'll store. What you think about injecting attributes via reflection? :3 I tried that but its really nasty code... didnt suceed :(
I thought you can't use reflection? I'm confused.
Map can store any kind of Object, so I don't know what you mean by not knowing what kind of Object you will store.
0

I believe he has the same Class (with the same name) but loaded and defined by two classloaders. The best thing to do is fix your system so the class is not loaded and twice.

Comments

0

There are several options. If your class is Serializable, you can serialise it and deserialise it again using another ClassLoader. Spring's ConfigurableObjectInputStream is a good help here:

ByteArrayOutputStream stream = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(stream);
out.writeObject(object);
byte[] data = stream.toByteArray()

Object result = new ConfigurableObjectInputStream(new ByteArrayInputStream(data), classLoader).readObject();

You can get it using maven by including

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

If your class is not serialisable, you can clone the object to another ClassLoader using PowerMock components as @Johan suggested. If you just want to copy the Object to a different ClasLoader, you can use PowerMock's DeepCloner like this:

DeepCloner deepCloner = new DeepCloner(classLoader);
Object result = deepCloner.clone(object);

to do that, you need the following dependency:

<dependency>
   <groupId>org.powermock</groupId>
   <artifactId>powermock-classloading-xstream</artifactId>
   <version>2.0.7</version>
</dependency>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.