How to Hot‑Deploy Custom Java Interface Implementations via JARs and Spring

This guide shows how to let users upload a JAR that contains a custom implementation of a predefined Java interface, then hot‑replace the implementation at runtime using either Spring‑managed bean injection or pure reflection, with full code examples and a test harness.

Java Web Project
Java Web Project
Java Web Project
How to Hot‑Deploy Custom Java Interface Implementations via JARs and Spring

Define a Simple Interface

We start with a minimal calculator interface that declares two methods, int calculate(int a, int b) and int add(int a, int b):

public interface Calculator {
    int calculate(int a, int b);
    int add(int a, int b);
}

Simple Implementation of the Interface

The implementation class demonstrates two ways a user might provide the logic: an annotation‑based approach (managed by Spring) for calculate and a reflection‑based approach for add. The class injects a CalculatorCore bean to illustrate Spring dependency wiring.

@Service
public class CalculatorImpl implements Calculator {
    @Autowired
    CalculatorCore calculatorCore;

    // Annotation‑based method
    @Override
    public int calculate(int a, int b) {
        int c = calculatorCore.add(a, b);
        return c;
    }

    // Reflection‑based method
    @Override
    public int add(int a, int b) {
        return new CalculatorCore().add(a, b);
    }
}

The CalculatorCore simply adds two integers:

@Service
public class CalculatorCore {
    public int add(int a, int b) {
        return a + b;
    }
}

Hot Deployment Using Reflection

When a user uploads a JAR, the system records the JAR’s absolute path ( jarAddress) and builds a URL ( jarPath). The hot‑deployment method loads the JAR with a URLClassLoader, obtains the implementation class by its fully‑qualified name, instantiates it via reflection, and invokes the add method.

public static void hotDeployWithReflect() throws Exception {
    URLClassLoader urlClassLoader = new URLClassLoader(
        new URL[]{ new URL(jarPath) }, Thread.currentThread().getContextClassLoader());
    Class clazz = urlClassLoader.loadClass("com.nci.cetc15.calculator.impl.CalculatorImpl");
    Calculator calculator = (Calculator) clazz.newInstance();
    int result = calculator.add(1, 2);
    System.out.println(result);
}

Hot Deployment Using Spring Annotation Scanning

If the uploaded JAR contains Spring components, the system must scan the JAR, identify classes annotated with Spring stereotypes, and register them into the existing Spring container. The process re‑uses the same class‑loader logic, then iterates over every discovered class name.

public static void hotDeployWithSpring() throws Exception {
    Set<String> classNameSet = DeployUtils.readJarFile(jarAddress);
    URLClassLoader urlClassLoader = new URLClassLoader(
        new URL[]{ new URL(jarPath) }, Thread.currentThread().getContextClassLoader());
    for (String className : classNameSet) {
        Class clazz = urlClassLoader.loadClass(className);
        if (DeployUtils.isSpringBeanClass(clazz)) {
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
            defaultListableBeanFactory.registerBeanDefinition(
                DeployUtils.transformName(className), beanDefinitionBuilder.getBeanDefinition());
        }
    }
}

The utility class DeployUtils provides three key methods: readJarFile(String jarAddress) – iterates over a JAR’s entries, extracts class names ending with .class, converts path separators to dots, and returns a Set<String> of fully‑qualified class names. isSpringBeanClass(Class<?> cla) – checks whether a class is a concrete, non‑interface, non‑abstract type and whether it carries one of the Spring annotations @Component, @Repository, or @Service. transformName(String className) – converts the simple class name to a bean name by lower‑casing the first character (e.g., CalculatorImplcalculatorImpl).

Removing Beans When a JAR Is Deleted

When a JAR is replaced or removed, the previously registered beans must be deregistered from the Spring container. The removal logic mirrors the registration process: load the JAR, find Spring beans, and call removeBeanDefinition with the same transformed bean name.

public static void delete() throws Exception {
    Set<String> classNameSet = DeployUtils.readJarFile(jarAddress);
    URLClassLoader urlClassLoader = new URLClassLoader(
        new URL[]{ new URL(jarPath) }, Thread.currentThread().getContextClassLoader());
    for (String className : classNameSet) {
        Class clazz = urlClassLoader.loadClass(className);
        if (DeployUtils.isSpringBeanClass(clazz)) {
            defaultListableBeanFactory.removeBeanDefinition(DeployUtils.transformName(className));
        }
    }
}

Test Harness

A simple test program repeatedly attempts to hot‑deploy the JAR. It creates a Spring ApplicationContext, obtains the underlying DefaultListableBeanFactory, and runs an infinite loop that calls hotDeployWithReflect(). If the JAR is not yet present, an exception is caught, printed, and the thread sleeps for ten seconds before retrying, allowing a developer to drop the JAR into the monitored directory manually.

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
while (true) {
    try {
        hotDeployWithReflect();
        // hotDeployWithSpring();
        // delete();
    } catch (Exception e) {
        e.printStackTrace();
        Thread.sleep(1000 * 10);
    }
}
Source: https://blog.csdn.net/zhangzhiqiang_0912
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaReflectionSpringDynamic LoadingHot DeploymentJar
Java Web Project
Written by

Java Web Project

Focused on Java backend technologies, trending internet tech, and the latest industry developments. The platform serves over 200,000 Java developers, inviting you to learn and exchange ideas together. Check the menu for Java learning resources.

0 followers
Reader feedback

How this landed with the community

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.