All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hyf.hotrefresh.core.util.InfraUtils Maven / Gradle / Ivy

package com.hyf.hotrefresh.core.util;

import com.hyf.hotrefresh.common.util.FastReflectionUtils;
import com.hyf.hotrefresh.common.util.ReflectionUtils;
import com.hyf.hotrefresh.core.agent.AgentHelper;
import com.hyf.hotrefresh.core.agent.InstrumentationHolder;

import javax.tools.JavaCompiler;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Method;

/**
 * @author baB_hyf
 * @date 2021/12/11
 */
public abstract class InfraUtils {

    private static final String BYTE_BUDDY_AGENT_CLASS    = "net.bytebuddy.agent.ByteBuddyAgent";
    private static final String ATTACHMENT_PROVIDER_CLASS = "net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider";
    private static final String CLASS_READER_CLASS        = "org.objectweb.asm.ClassReader";
    private static final String JAVAC_TOOL_CLASS          = "com.sun.tools.javac.api.JavacTool";

    private static Method   installMethod      = null;
    private static Class classReaderClass   = null;
    private static Method   getClassNameMethod = null;

    private static volatile JavaCompiler    compiler                          = null;
    private static volatile Instrumentation instrumentation                   = null;
    private static volatile Instrumentation systemStartProcessInstrumentation = null;

    static {
        initByteBuddyEnvironment();
        initAsmEnvironment();
    }

    /**
     * not recommend to use, just a intermediate object
     *
     * @return agent attach generated instrumentation
     */
    public static Instrumentation getInstrumentation() {
        if (instrumentation == null) {
            try {
                Object attachmentProvider = AgentHelper.getAttachmentProvider();
                instrumentation = ReflectionUtils.invokeMethod(installMethod, null, attachmentProvider);
                AgentHelper.installSpringLoaded(instrumentation);
            } catch (Throwable t) {
                throw new IllegalStateException("Failed to get instrumentation", t);
            }
        }
        return instrumentation;
    }

    public static Instrumentation getSystemStartProcessInstrumentation() {
        if (systemStartProcessInstrumentation == null) {
            try {
                Class clazz = InfraUtils.forName(InstrumentationHolder.class.getName());
                systemStartProcessInstrumentation = FastReflectionUtils.fastInvokeMethod(clazz, "getSystemStartProcessInstrumentation");
            } catch (Throwable t) {
                throw new IllegalStateException("Failed to get systemStartProcessInstrumentation", t);
            }
        }
        return systemStartProcessInstrumentation;
    }

    public static String getClassName(byte[] bytes) {
        try {
            Object o = classReaderClass.getConstructor(byte[].class).newInstance((Object) bytes);
            String classNameWithPath = ReflectionUtils.invokeMethod(getClassNameMethod, o);
            return classNameWithPath.replace("/", ".");
        } catch (Throwable t) {
            throw new IllegalStateException("Failed to get className", t);
        }
    }

    public static JavaCompiler getJavaCompiler() {
        if (compiler == null) {
            try {
                Class clazz = forName(JAVAC_TOOL_CLASS);
                Method createMethod = ReflectionUtils.getMethod(clazz, "create");
                compiler = ReflectionUtils.invokeMethod(createMethod, null);
            } catch (Throwable t) {
                throw new IllegalStateException("Failed to get java compiler", t);
            }
        }

        return compiler;
    }

    public static boolean canLoad(Class clazz) {
        ClassLoader cl = clazz.getClassLoader();

        // bootstrap class loader loaded
        if (cl == null) {
            return true;
        }

        ClassLoader p = Util.getInfrastructureJarClassLoader();
        while (p != null) {
            if (cl == p) {
                return true;
            }
            p = p.getParent();
        }

        return false;
    }

    private static void initByteBuddyEnvironment() {
        Class agentClass = forName(BYTE_BUDDY_AGENT_CLASS);
        Class attachmentProviderClass = forName(ATTACHMENT_PROVIDER_CLASS);
        installMethod = ReflectionUtils.getMethod(agentClass, "install", attachmentProviderClass);
    }

    private static void initAsmEnvironment() {
        classReaderClass = forName(CLASS_READER_CLASS);
        getClassNameMethod = ReflectionUtils.getMethod(classReaderClass, "getClassName");
    }

    public static Class forName(String className) {
        return ReflectionUtils.forName(className, Util.getInfrastructureJarClassLoader());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy