Backend Development 9 min read

Using JVM‑Sandbox for Exception Injection and Code Enhancement in Java Services

This article introduces JVM‑Sandbox, explains its non‑intrusive AOP capabilities, and provides a step‑by‑step tutorial on installing the sandbox, loading custom modules, performing code enhancement via instrumentation, and testing exception injection in a Java service.

转转QA
转转QA
转转QA
Using JVM‑Sandbox for Exception Injection and Code Enhancement in Java Services

Background – The current testing platform at ZhiZhuan uses JVM injection and traffic replay to mock hard‑to‑cover scenarios and reduce risk of code changes, both built on jvm‑sandbox technology. The author shares initial experiences.

Introduction – jvm‑sandbox installs a sandbox JVM inside the target JVM, loading proxy classes via a custom classloader to achieve AOP without restarting or intruding the application. It offers non‑intrusive, class‑isolated, pluggable, multi‑tenant, and highly compatible features for fault localization, flow control, fault simulation, method recording, dynamic logging, security monitoring, and data masking.

Step 1: Install the Sandbox – Add the -javaagent:/sandbox/lib/sandbox-agent.jar option when starting service A. The javaagent triggers AgentLauncher.premain , which calls install to load the sandbox into the target JVM. The installation process adds sandbox‑spy.jar to the BootstrapClassLoader, creates a custom SandboxClassLoader , instantiates CoreConfigure , and starts a Jetty server for HTTP‑based sandbox control.

java -javaagent:/sandbox/lib/sandbox-agent.jar
public static void premain(String featureString, Instrumentation inst) {
    // avoid affecting service startup
    try {
        LAUNCH_MODE = LAUNCH_MODE_AGENT;
        install(toFeatureMap(featureString), inst);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
private static synchronized InetSocketAddress install(final Map
featureMap, final Instrumentation inst) {
    final String namespace = getNamespace(featureMap);
    final String propertiesFilePath = getPropertiesFilePath(featureMap);
    final String coreFeatureString = toFeatureString(featureMap);
    try {
        final String home = getSandboxHome(featureMap);
        // inject Spy into BootstrapClassLoader
        inst.appendToBootstrapClassLoaderSearch(new JarFile(new File(getSandboxSpyJarPath(home))));
        // create custom classloader
        final ClassLoader sandboxClassLoader = loadOrDefineClassLoader(namespace, getSandboxCoreJarPath(home));
        // load CoreConfigure class
        final Class
classOfConfigure = sandboxClassLoader.loadClass(CLASS_OF_CORE_CONFIGURE);
        final Object objectOfCoreConfigure = classOfConfigure.getMethod("toConfigure", String.class, String.class)
            .invoke(null, coreFeatureString, propertiesFilePath);
        // load CoreServer class
        final Class
classOfProxyServer = sandboxClassLoader.loadClass(CLASS_OF_PROXY_CORE_SERVER);
        final Object objectOfProxyServer = classOfProxyServer.getMethod("getInstance").invoke(null);
        final boolean isBind = (Boolean) classOfProxyServer.getMethod("isBind").invoke(objectOfProxyServer);
        if (!isBind) {
            try {
                classOfProxyServer.getMethod("bind", classOfConfigure, Instrumentation.class)
                    .invoke(objectOfProxyServer, objectOfCoreConfigure, inst);
            } catch (Throwable t) {
                classOfProxyServer.getMethod("destroy").invoke(objectOfProxyServer);
                throw t;
            }
        }
        return (InetSocketAddress) classOfProxyServer.getMethod("getLocal").invoke(objectOfProxyServer);
    } catch (Throwable cause) {
        throw new RuntimeException("sandbox attach failed.", cause);
    }
}

Step 2: Load Module B – jvm‑sandbox follows a plugin architecture. Modules (system or custom) are placed under /sandbox/bin/../module or /.sandbox-module . Custom modules implement the Module interface, declare a unique ID via @Information , and define event watchers and command handlers. In this example, exception injection logic resides in custom module B, loaded by ModuleJarClassLoader .

void load(final ModuleJarLoadCallback mjCb, final ModuleJarLoader.ModuleLoadCallback mCb) {
    for (final File moduleJarFile : listModuleJarFileInLib()) {
        try {
            mjCb.onLoad(moduleJarFile);
            new ModuleJarLoader(moduleJarFile, mode).load(mCb);
        } catch (Throwable cause) {
            logger.warn("loading module-jar occur error! module-jar={};", moduleJarFile, cause);
        }
    }
}

Step 3: Code Enhancement – After loading, the module’s watch method registers a SandboxClassFileTransformer with the Instrumentation instance. All subsequent class loads pass through this transformer, which matches target classes, retransforms them via retransformClasses , and activates an EventListenerHandler to listen for sandbox commands.

Create SandboxClassFileTransformer and register it.

Instrumentation adds the transformer, affecting all future class loads.

Match and select classes that need enhancement.

Use retransformClasses to modify already loaded classes.

Activate EventListenerHandler to receive sandbox instructions.

The following image shows the decompiled class before exception injection, and the next image shows the class after injection where the Spy class weaves code into method entry, return, and exception paths.

Step 4: Test Service A – With the exception injection active, the file‑generation method always fails, demonstrating the sandbox’s ability to dynamically alter business logic.

Summary

The experience shows that by packaging desired enhancements as custom modules, placing them in the sandbox’s module directory, and installing jvm‑sandbox on a target service, developers can dynamically control and augment business code via HTTP requests, making jvm‑sandbox a flexible and easy‑to‑use code‑enhancement tool. Interested readers can try it at https://github.com/alibaba/jvm-sandbox .

JavaJVMInstrumentationSandboxCode EnhancementException Injection
转转QA
Written by

转转QA

In the era of knowledge sharing, discover 转转QA from a new perspective.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.