use of io.cdap.cdap.common.app.MainClassLoader in project cdap by caskdata.
the class MapReduceContainerLauncher method launch.
/**
* Launches the given main class. The main class will be loaded through the {@link MapReduceClassLoader}.
*
* @param mainClassName the main class to launch
* @param args arguments for the main class
*/
@SuppressWarnings("unused")
public static void launch(String mainClassName, String[] args) throws Exception {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler());
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
List<URL> urls = ClassLoaders.getClassLoaderURLs(systemClassLoader, new ArrayList<>());
// Remove the URL that contains the given main classname to avoid infinite recursion.
// This is needed because we generate a class with the same main classname in order to intercept the main()
// method call from the container launch script.
URL resource = systemClassLoader.getResource(mainClassName.replace('.', '/') + ".class");
if (resource == null) {
throw new IllegalStateException("Failed to find resource for main class " + mainClassName);
}
if (!urls.remove(ClassLoaders.getClassPathURL(mainClassName, resource))) {
throw new IllegalStateException("Failed to remove main class resource " + resource);
}
// Create a MainClassLoader for dataset rewrite
URL[] classLoaderUrls = urls.toArray(new URL[urls.size()]);
ClassLoader mainClassLoader = new MainClassLoader(classLoaderUrls, systemClassLoader.getParent());
// Install the JUL to SLF4J Bridge
try {
mainClassLoader.loadClass(SLF4JBridgeHandler.class.getName()).getDeclaredMethod("install").invoke(null);
} catch (Exception e) {
// Log the error and continue
LOG.warn("Failed to invoke SLF4JBridgeHandler.install() required for jul-to-slf4j bridge", e);
}
ClassLoaders.setContextClassLoader(mainClassLoader);
// Creates the MapReduceClassLoader. It has to be loaded from the MainClassLoader.
try {
final ClassLoader classLoader = (ClassLoader) mainClassLoader.loadClass(MapReduceClassLoader.class.getName()).newInstance();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
if (classLoader instanceof AutoCloseable) {
try {
((AutoCloseable) classLoader).close();
} catch (Exception e) {
System.err.println("Failed to close ClassLoader " + classLoader);
e.printStackTrace();
}
}
}
});
Thread.currentThread().setContextClassLoader(classLoader);
// Setup logging and stdout/stderr redirect
// Invoke MapReduceClassLoader.getTaskContextProvider()
classLoader.getClass().getDeclaredMethod("getTaskContextProvider").invoke(classLoader);
// Invoke StandardOutErrorRedirector.redirectToLogger()
classLoader.loadClass("io.cdap.cdap.common.logging.StandardOutErrorRedirector").getDeclaredMethod("redirectToLogger", String.class).invoke(null, mainClassName);
Class<?> mainClass = classLoader.loadClass(mainClassName);
Method mainMethod = mainClass.getMethod("main", String[].class);
mainMethod.setAccessible(true);
LOG.info("Launch main class {}.main({})", mainClassName, Arrays.toString(args));
mainMethod.invoke(null, new Object[] { args });
LOG.info("Main method returned {}", mainClassName);
} catch (Throwable t) {
// print to System.err since the logger may not have been redirected yet
System.err.println(String.format("Exception raised when calling %s.main(String[]) method", mainClassName));
t.printStackTrace();
throw t;
}
}
use of io.cdap.cdap.common.app.MainClassLoader in project cdap by caskdata.
the class MasterEnvironmentMain method main.
public static void main(String[] args) throws Exception {
MainClassLoader classLoader = MainClassLoader.createFromContext();
if (classLoader == null) {
LOG.warn("Failed to create CDAP system ClassLoader. AuthEnforce annotation will not be rewritten.");
doMain(args);
} else {
LOG.debug("Using {} as the system ClassLoader", classLoader);
Thread.currentThread().setContextClassLoader(classLoader);
Class<?> mainClass = classLoader.loadClass(MasterEnvironmentMain.class.getName());
mainClass.getMethod("doMain", String[].class).invoke(null, new Object[] { args });
}
}
use of io.cdap.cdap.common.app.MainClassLoader in project cdap by caskdata.
the class ClassLoaderTest method testMoreExecutorsRewrite.
@Test
public void testMoreExecutorsRewrite() throws Exception {
MainClassLoader classLoader = MainClassLoader.createFromContext();
Assert.assertNotNull(classLoader);
Class<?> cls = classLoader.loadClass(MoreExecutors.class.getName());
// Call the newly added directExecutor method
Method method = cls.getMethod("directExecutor");
Executor executor = (Executor) method.invoke(null);
String currentThreadName = Thread.currentThread().getName();
AtomicReference<String> executorThreadName = new AtomicReference<>();
executor.execute(() -> executorThreadName.set(Thread.currentThread().getName()));
Assert.assertEquals(currentThreadName, executorThreadName.get());
}
use of io.cdap.cdap.common.app.MainClassLoader in project cdap by caskdata.
the class ClassLoaderTest method testPreconditionsRewrite.
@Test
public void testPreconditionsRewrite() throws Exception {
MainClassLoader classLoader = MainClassLoader.createFromContext();
Assert.assertNotNull(classLoader);
Class<?> cls = classLoader.loadClass(Preconditions.class.getName());
// Call the newly added method checkArgument(boolean, String, Object)
Method method = cls.getMethod("checkArgument", boolean.class, String.class, Object.class);
method.invoke(null, true, "check argument %s", "t1");
try {
method.invoke(null, false, "fail argument %s", "t1");
} catch (Exception e) {
Assert.assertEquals("fail argument t1", Throwables.getRootCause(e).getMessage());
}
// Call the newly added method checkState(boolean, String, Object)
method = cls.getMethod("checkState", boolean.class, String.class, Object.class);
method.invoke(null, true, "check state %s", "t2");
try {
method.invoke(null, false, "fail state %s", "t2");
} catch (Exception e) {
Assert.assertEquals("fail state t2", Throwables.getRootCause(e).getMessage());
}
// Call the newly added method checkNotNull(boolean, String, Object)
method = cls.getMethod("checkNotNull", Object.class, String.class, Object.class);
method.invoke(null, "a", "check not null %s", "t3");
try {
method.invoke(null, null, "fail null %s", "t3");
} catch (Exception e) {
Assert.assertEquals("fail null t3", Throwables.getRootCause(e).getMessage());
}
}
Aggregations