[英]Copy java object/class from one classloader to another classloader
嗨,有沒有辦法將一個類加載的上下文(屬性等)從一個類加載器(例如“制造”類 Point)復制到另一個類加載器?
澄清一下,例如:我在 CL 1 上有一個對象 Point。現在在另一個 CL2 上運行,我想在 CL 3 中創建這個對象。
一些對象:
class Point {
int x;
int y;
public Point() {}
//getters and setters
風景:
...
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();
但是我不能使用 sun.reflection(不可用)並且序列化不起作用,因為 CL2 會自動用 CL 1“重建”對象。
我想到的一個解決方案是做一個“100%”的 java 反射 rconstruct,基本上從 CL2 獲取對象的字段並在新的 obj 上設置。
PS:它需要在 Java 1.4.2 上運行 :'(
如果您需要執行以下操作之一,請參閱Transloader了解如何在 ClassLoader 之間復制類:
將幾乎任何對象圖從一個 ClassLoader克隆到另一個
從外部 ClassLoader 獲取任何對象並調用其上的任何方法而不克隆它
如果該類與您在案例中描述的一樣簡單,則可以查看XMLEncoder 。 使用它有很大的限制,但在簡單的情況下它應該可以完成工作。
編輯:鑒於此限制,我會說將數據放在 Map 中並使用它。 您甚至可以讓這兩個類在內部將它們的狀態存儲在 Map 中,以便移動非常流暢。
如果這不起作用,那么您似乎面臨着自己的 XML/JSON 或純 CSV 卷,具體取決於數據的復雜性。
我相信他有相同的類(具有相同的名稱)但由兩個類加載器加載和定義。 最好的辦法是修復你的系統,這樣類就不會被加載兩次。
PowerMock 類加載還提供了類似於 TransLoader 的東西,它支持更高級的用例,例如(某些)反射。 您可以輕松地執行 Runnable 或 Callable:
ClassloaderExecutor cle = new ClassloaderExecutor(classloader); cle.execute(aRunnable); Object result = cle.execute(aCallable); // Result is cloned back to original CL
查看 svn repo 中的測試用例。
它也可以在 Maven 中使用:
<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-classloading</artifactId> <version>1.4.6</version> </dependency>
有幾種選擇。 如果您的類是Serializable
,您可以序列化它並使用另一個 ClassLoader 再次反序列化它。 Spring 的ConfigurableObjectInputStream
在這里提供了很好的幫助:
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();
您可以通過包含使用 maven 來獲取它
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
如果您的類不可序列化,您可以按照@Johan 的建議使用 PowerMock 組件將對象克隆到另一個 ClassLoader。 如果您只想將對象復制到不同的 ClasLoader,您可以像這樣使用 PowerMock 的DeepCloner
:
DeepCloner deepCloner = new DeepCloner(classLoader);
Object result = deepCloner.clone(object);
為此,您需要以下依賴項:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-classloading-xstream</artifactId>
<version>2.0.7</version>
</dependency>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.