/*
* Copyright 2014 NAVER Corp.
*
* 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 com.navercorp.pinpoint.bootstrap;
import com.navercorp.pinpoint.bootstrap.classloader.PinpointClassLoaderFactory;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.Callable;
/**
* @author emeroad
*/
public class AgentClassLoader {
private static final SecurityManager SECURITY_MANAGER = System.getSecurityManager();
private final URLClassLoader classLoader;
private String bootClass;
private final ContextClassLoaderExecuteTemplate<Object> executeTemplate;
public AgentClassLoader(URL[] urls) {
if (urls == null) {
throw new NullPointerException("urls");
}
ClassLoader bootStrapClassLoader = AgentClassLoader.class.getClassLoader();
this.classLoader = createClassLoader(urls, bootStrapClassLoader);
this.executeTemplate = new ContextClassLoaderExecuteTemplate<Object>(classLoader);
}
private URLClassLoader createClassLoader(final URL[] urls, final ClassLoader bootStrapClassLoader) {
if (SECURITY_MANAGER != null) {
return AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() {
public URLClassLoader run() {
return PinpointClassLoaderFactory.createClassLoader(urls, bootStrapClassLoader);
}
});
} else {
return PinpointClassLoaderFactory.createClassLoader(urls, bootStrapClassLoader);
}
}
public void setBootClass(String bootClass) {
this.bootClass = bootClass;
}
public Agent boot(final AgentOption agentOption) {
final Class<?> bootStrapClazz = getBootStrapClass();
final Object agent = executeTemplate.execute(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
Constructor<?> constructor = bootStrapClazz.getConstructor(AgentOption.class);
return constructor.newInstance(agentOption);
} catch (InstantiationException e) {
throw new BootStrapException("boot create failed. Error:" + e.getMessage(), e);
} catch (IllegalAccessException e) {
throw new BootStrapException("boot method invoke failed. Error:" + e.getMessage(), e);
}
}
});
if (agent instanceof Agent) {
return (Agent) agent;
} else {
String agentClassName;
if (agent == null) {
agentClassName = "Agent is null";
} else {
agentClassName = agent.getClass().getName();
}
throw new BootStrapException("Invalid AgentType. boot failed. AgentClass:" + agentClassName);
}
}
private Class<?> getBootStrapClass() {
try {
return this.classLoader.loadClass(bootClass);
} catch (ClassNotFoundException e) {
throw new BootStrapException("boot class not found. bootClass:" + bootClass + " Error:" + e.getMessage(), e);
}
}
}