Search in sources :

Example 1 with MainClassLoader

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;
    }
}
Also used : MapReduceClassLoader(io.cdap.cdap.internal.app.runtime.batch.MapReduceClassLoader) Method(java.lang.reflect.Method) URL(java.net.URL) SLF4JBridgeHandler(org.slf4j.bridge.SLF4JBridgeHandler) MainClassLoader(io.cdap.cdap.common.app.MainClassLoader) MapReduceClassLoader(io.cdap.cdap.internal.app.runtime.batch.MapReduceClassLoader) UncaughtExceptionHandler(io.cdap.cdap.common.logging.common.UncaughtExceptionHandler) MainClassLoader(io.cdap.cdap.common.app.MainClassLoader)

Example 2 with MainClassLoader

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 });
    }
}
Also used : MainClassLoader(io.cdap.cdap.common.app.MainClassLoader)

Example 3 with MainClassLoader

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());
}
Also used : Executor(java.util.concurrent.Executor) MoreExecutors(com.google.common.util.concurrent.MoreExecutors) AtomicReference(java.util.concurrent.atomic.AtomicReference) Method(java.lang.reflect.Method) MainClassLoader(io.cdap.cdap.common.app.MainClassLoader) Test(org.junit.Test)

Example 4 with MainClassLoader

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());
    }
}
Also used : Preconditions(com.google.common.base.Preconditions) Method(java.lang.reflect.Method) IOException(java.io.IOException) MainClassLoader(io.cdap.cdap.common.app.MainClassLoader) Test(org.junit.Test)

Aggregations

MainClassLoader (io.cdap.cdap.common.app.MainClassLoader)4 Method (java.lang.reflect.Method)3 Test (org.junit.Test)2 Preconditions (com.google.common.base.Preconditions)1 MoreExecutors (com.google.common.util.concurrent.MoreExecutors)1 UncaughtExceptionHandler (io.cdap.cdap.common.logging.common.UncaughtExceptionHandler)1 MapReduceClassLoader (io.cdap.cdap.internal.app.runtime.batch.MapReduceClassLoader)1 IOException (java.io.IOException)1 URL (java.net.URL)1 Executor (java.util.concurrent.Executor)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 SLF4JBridgeHandler (org.slf4j.bridge.SLF4JBridgeHandler)1