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

scouter.agent.proxy.LoaderManager Maven / Gradle / Ivy

/*
 *  Copyright 2015 the original author or authors. 
 *  @https://github.com/scouter-project/scouter
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); 
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 */
package scouter.agent.proxy;

import scouter.agent.JavaAgent;
import scouter.agent.Logger;
import scouter.agent.util.ManifestUtil;
import scouter.util.ArrayUtil;
import scouter.util.BytesClassLoader;
import scouter.util.FileUtil;
import scouter.util.HashUtil;
import scouter.util.IntKeyLinkedMap;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.instrument.Instrumentation;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.JarFile;

/**
 * @author Paul S.J. Kim([email protected])
 * @author Gun Lee([email protected])
 */

public class LoaderManager {
	private static ClassLoader toolsLoader;
	private static IntKeyLinkedMap loaders = new IntKeyLinkedMap().setMax(10);

	public synchronized static ClassLoader getToolsLoader() {
		if (toolsLoader == null) {
			try {
				if (JavaAgent.isJava9plus()) {
					toolsLoader = ClassLoader.getSystemClassLoader();
				} else {
					File tools = ManifestUtil.getToolsFile();
					toolsLoader = new URLClassLoader(new URL[] { tools.toURI().toURL() });
				}
			} catch (Throwable e) {
				Logger.println("A134", e);
			}
		}

		return createLoader(toolsLoader, "scouter.tools");
	}

	public static ClassLoader getHttpLoader(ClassLoader parent) {
		return createLoader(parent, "scouter.http");
	}

	//TODO del
	public static ClassLoader getJdbcLoader(ClassLoader parent) {
		return createLoader(parent, "scouter.jdbc");
	}

	public static ClassLoader getDB2Loader(ClassLoader parent) {
		return createLoader(parent, "scouter.jdbc");
	}

	public static ClassLoader getHttpClient(ClassLoader parent) {
		return createLoader(parent, "scouter.httpclient");
	}

	public static ClassLoader getKafkaClient(ClassLoader parent) {
		return createLoader(parent, "scouter.kafka");
	}

	public static ClassLoader getRedisClient(ClassLoader parent) {
		return createLoader(parent, "scouter.redis");
	}

	private synchronized static ClassLoader createLoader(ClassLoader parent, String key) {

		int hashKey = (parent == null ? 0 : System.identityHashCode(parent));
		hashKey = hashKey ^ HashUtil.hash(key);
		ClassLoader loader = loaders.get(hashKey);
		if (loader == null) {
			try {
				byte[] bytes = deployJarBytes(key);
				if (bytes != null) {
					loader = new BytesClassLoader(bytes, parent);
					loaders.put(hashKey, loader);
				}
			} catch (Throwable e) {
				Logger.println("A137", "SUBLOADER " + key + " " + e);
			}
		}
		return loader;
	}

	public static ClassLoader appendToSystemOrBootLoader(String key) {
		if (JavaAgent.isJava9plus()) {
			appendToSystemLoader(JavaAgent.getInstrumentation(), key);
			return ClassLoader.getSystemClassLoader();
		} else {
			appendToBootLoader(JavaAgent.getInstrumentation(), key);
			return null;
		}
	}

	private static void appendToSystemLoader(Instrumentation inst, String key) {
		byte[] bytes = deployJarBytes(key);
		try {
			File tempJar = FileUtil.saveAsTemp(key, ".jar", bytes);
			inst.appendToSystemClassLoaderSearch(new JarFile(tempJar));
		} catch (IOException e) {
			Logger.println("A138", "Error on load " + key + ".jar " + e);
			throw new RuntimeException(e);
		}
	}

	private static void appendToBootLoader(Instrumentation inst, String key) {
		byte[] bytes = deployJarBytes(key);
		try {
			File tempJar = FileUtil.saveAsTemp(key, ".jar", bytes);
			inst.appendToBootstrapClassLoaderSearch(new JarFile(tempJar));
		} catch (IOException e) {
			Logger.println("A138", "Error on load " + key + ".jar " + e);
			throw new RuntimeException(e);
		}
	}

	private static byte[] deployJarBytes(String jarname) {
		try {
			InputStream is = JavaAgent.class.getResourceAsStream("/" + jarname + ".jar");
			byte[] newBytes = FileUtil.readAll(is);
			is.close();
			Logger.println("NONE", "LoadJarBytes " + jarname + " " + ArrayUtil.len(newBytes) + " bytes");
			return newBytes;
		} catch (Exception e) {
			Logger.println("NONE", "fail to load jar bytes " + jarname);
			return null;
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy