Deep cloning library for objects across different classloaders using XStream serialization
npx @tessl/cli install tessl/maven-org-powermock--powermock-classloading-xstream@2.0.0PowerMock Classloading XStream provides deep cloning capabilities for Java objects using XStream serialization. It enables objects to be deeply cloned across different classloaders, which is essential for PowerMock's advanced mocking features including static method mocking, final class mocking, and bytecode manipulation.
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-classloading-xstream</artifactId>
<version>2.0.9</version>
</dependency>import org.powermock.classloading.DeepCloner;import org.powermock.classloading.DeepCloner;
import java.net.URLClassLoader;
// Create a deep cloner with the current context classloader
DeepCloner cloner = new DeepCloner();
// Or specify a specific classloader
ClassLoader customClassLoader = new URLClassLoader(urls);
DeepCloner customCloner = new DeepCloner(customClassLoader);
// Clone an object
MyObject original = new MyObject("example");
MyObject cloned = cloner.clone(original);
// The cloned object is a deep copy
assert original != cloned;
assert original.equals(cloned); // Assuming equals() is properly implementedCreates complete deep copies of Java objects using XStream serialization, with support for cross-classloader cloning.
public class DeepCloner implements DeepClonerSPI {
// Create deep cloner using current context classloader
public DeepCloner();
// Create deep cloner using specified classloader
public DeepCloner(ClassLoader classLoader);
// Clone an object with full deep copy semantics
public <T> T clone(T objectToClone);
}Constructor Details:
DeepCloner(): Creates a deep cloner using the current thread's context ClassLoader (Thread.currentThread().getContextClassLoader())DeepCloner(ClassLoader classLoader): Creates a deep cloner using the specified ClassLoader for loading cloned classesMethod Details:
clone(T objectToClone):
Basic Cloning:
DeepCloner cloner = new DeepCloner();
String original = "Hello World";
String cloned = cloner.clone(original);Collection Cloning:
import java.util.Arrays;
import java.util.List;
DeepCloner cloner = new DeepCloner();
List<String> originalList = Arrays.asList("a", "b", "c");
List<String> clonedList = cloner.clone(originalList);Cross-ClassLoader Cloning:
import java.net.URL;
import java.net.URLClassLoader;
URLClassLoader targetClassLoader = new URLClassLoader(new URL[]{jarUrl});
DeepCloner cloner = new DeepCloner(targetClassLoader);
MyObject cloned = cloner.clone(originalObject);
// cloned object's class is loaded by targetClassLoaderpublic interface DeepClonerSPI {
<T> T clone(T objectToClone);
}The DeepClonerSPI interface from the org.powermock.classloading.spi package defines the contract that all deep cloners must implement.
This package requires the following dependencies:
The DeepCloner disables XStream's security restrictions to allow unrestricted type access, which is intended for testing scenarios where maximum flexibility is required. This configuration allows serialization of any type but should be used carefully in production environments.
The DeepCloner relies on XStream's exception handling for serialization errors. Common exceptions that may be thrown include:
toXML() and fromXML() methods for serialization/deserializationclassloader field from SingleClassloaderExecutor instances during serializationallowTypesByRegExp(new String[]{".*"}) for maximum compatibility