Search in sources :

Example 1 with ProgramClassLoader

use of io.cdap.cdap.internal.app.runtime.ProgramClassLoader in project cdap by caskdata.

the class PluginClassLoader method createParent.

static ClassLoader createParent(ClassLoader templateClassLoader) {
    // Find the ProgramClassLoader from the template ClassLoader
    ClassLoader programClassLoader = templateClassLoader;
    while (programClassLoader != null && !(programClassLoader instanceof ProgramClassLoader)) {
        programClassLoader = programClassLoader.getParent();
    }
    // This shouldn't happen
    Preconditions.checkArgument(programClassLoader != null, "Cannot find ProgramClassLoader");
    // Package filtered classloader of the template classloader, which only classes in "Export-Packages" are loadable.
    Manifest manifest = ((ProgramClassLoader) programClassLoader).getManifest();
    Set<String> exportPackages = ManifestFields.getExportPackages(manifest);
    ClassLoader filteredTemplateClassLoader = new PackageFilterClassLoader(templateClassLoader, exportPackages::contains);
    // followed by template export-packages, then by a plugin lib jars.
    return new CombineClassLoader(programClassLoader.getParent(), filteredTemplateClassLoader);
}
Also used : CombineClassLoader(io.cdap.cdap.common.lang.CombineClassLoader) ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) DirectoryClassLoader(io.cdap.cdap.common.lang.DirectoryClassLoader) CombineClassLoader(io.cdap.cdap.common.lang.CombineClassLoader) PackageFilterClassLoader(io.cdap.cdap.common.lang.PackageFilterClassLoader) Manifest(java.util.jar.Manifest) PackageFilterClassLoader(io.cdap.cdap.common.lang.PackageFilterClassLoader)

Example 2 with ProgramClassLoader

use of io.cdap.cdap.internal.app.runtime.ProgramClassLoader in project cdap by caskdata.

the class Programs method create.

/**
 * Creates a new {@link Program} using information from an existing program. The new program has the same
 * runtime dependencies and must be from the same application as the original program.
 *
 * @param cConf the CDAP configuration
 * @param originalProgram the original program
 * @param programId the new program id
 * @param programRunner the {@link ProgramRunner} for executing the new program. If provided and if it implements
 *                      {@link ProgramClassLoaderProvider}, then the
 *                      {@link ClassLoader} created for the {@link Program} will be determined based on it.
 *                      Otherwise, the {@link ClassLoader} will only have visibility
 *                      to cdap-api and hadoop classes.
 * @return a new {@link Program} instance for the given programId
 */
public static Program create(CConfiguration cConf, Program originalProgram, ProgramId programId, @Nullable ProgramRunner programRunner) {
    ClassLoader classLoader = originalProgram.getClassLoader();
    // The classloader should be ProgramClassLoader
    Preconditions.checkArgument(classLoader instanceof ProgramClassLoader, "Program %s doesn't use ProgramClassLoader", originalProgram);
    // The new program should be in the same namespace and app
    ProgramId originalId = originalProgram.getId();
    Preconditions.checkArgument(originalId.getNamespaceId().equals(programId.getNamespaceId()), "Program %s is not in the same namespace as %s", programId, originalId);
    Preconditions.checkArgument(originalId.getParent().equals(programId.getParent()), "Program %s is not in the same application as %s", programId, originalId);
    // Make sure the program is defined in the app
    ApplicationSpecification appSpec = originalProgram.getApplicationSpecification();
    ensureProgramInApplication(appSpec, programId);
    return Programs.create(cConf, programRunner, new ProgramDescriptor(programId, appSpec), originalProgram.getJarLocation(), ((ProgramClassLoader) classLoader).getDir());
}
Also used : ApplicationSpecification(io.cdap.cdap.api.app.ApplicationSpecification) ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) FilterClassLoader(io.cdap.cdap.common.lang.FilterClassLoader) ProgramId(io.cdap.cdap.proto.id.ProgramId)

Example 3 with ProgramClassLoader

use of io.cdap.cdap.internal.app.runtime.ProgramClassLoader in project cdap by caskdata.

the class ArtifactClassLoaderFactory method createClassLoader.

/**
 * Create a classloader that loads classes from a directory where an artifact jar has been expanded, with access to
 * packages that all program type has access to. The classloader created is only for artifact inspection purpose
 * and shouldn't be used for program execution as it doesn't have the proper class filtering for the specific
 * program type for the program being executed.
 *
 * @param unpackDir the directory where the artifact jar has been expanded
 * @return a closeable classloader based off the specified artifact; on closing the returned {@link ClassLoader},
 *         all temporary resources created for the classloader will be removed
 */
CloseableClassLoader createClassLoader(File unpackDir) {
    ProgramRunner programRunner = null;
    try {
        // Try to create a ProgramClassLoader from the Spark runtime system if it is available.
        // It is needed because we don't know what program types that an artifact might have.
        // TODO: CDAP-5613. We shouldn't always expose the Spark classes.
        programRunner = programRunnerFactory.create(ProgramType.SPARK);
    } catch (Exception e) {
        // If Spark is not supported, exception is expected. We'll use the default filter.
        LOG.trace("Spark is not supported. Not using ProgramClassLoader from Spark", e);
    }
    ProgramClassLoader programClassLoader = null;
    if (programRunner instanceof ProgramClassLoaderProvider) {
        programClassLoader = new ProgramClassLoader(cConf, unpackDir, ((ProgramClassLoaderProvider) programRunner).createProgramClassLoaderParent());
    }
    if (programClassLoader == null) {
        programClassLoader = new ProgramClassLoader(cConf, unpackDir, FilterClassLoader.create(getClass().getClassLoader()));
    }
    final ClassLoader finalProgramClassLoader = programClassLoader;
    final ProgramRunner finalProgramRunner = programRunner;
    return new CloseableClassLoader(programClassLoader, () -> {
        Closeables.closeQuietly((Closeable) finalProgramClassLoader);
        if (finalProgramRunner instanceof Closeable) {
            Closeables.closeQuietly((Closeable) finalProgramRunner);
        }
    });
}
Also used : ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) ProgramClassLoaderProvider(io.cdap.cdap.app.runtime.ProgramClassLoaderProvider) Closeable(java.io.Closeable) ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) FilterClassLoader(io.cdap.cdap.common.lang.FilterClassLoader) DirectoryClassLoader(io.cdap.cdap.common.lang.DirectoryClassLoader) CloseableClassLoader(io.cdap.cdap.api.artifact.CloseableClassLoader) CloseableClassLoader(io.cdap.cdap.api.artifact.CloseableClassLoader) ProgramRunner(io.cdap.cdap.app.runtime.ProgramRunner)

Example 4 with ProgramClassLoader

use of io.cdap.cdap.internal.app.runtime.ProgramClassLoader in project cdap by caskdata.

the class SparkRuntimeContextProvider method createProgram.

private static Program createProgram(CConfiguration cConf, SparkRuntimeContextConfig contextConfig) throws IOException {
    File programJar = new File(PROGRAM_JAR_NAME);
    File programDir = new File(PROGRAM_JAR_EXPANDED_NAME);
    ClassLoader parentClassLoader = new FilterClassLoader(SparkRuntimeContextProvider.class.getClassLoader(), SparkResourceFilters.SPARK_PROGRAM_CLASS_LOADER_FILTER);
    ClassLoader classLoader = new ProgramClassLoader(cConf, programDir, parentClassLoader);
    return new DefaultProgram(new ProgramDescriptor(contextConfig.getProgramId(), contextConfig.getApplicationSpecification()), Locations.toLocation(programJar), classLoader);
}
Also used : FilterClassLoader(io.cdap.cdap.common.lang.FilterClassLoader) ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) FilterClassLoader(io.cdap.cdap.common.lang.FilterClassLoader) DefaultProgram(io.cdap.cdap.app.program.DefaultProgram) ProgramDescriptor(io.cdap.cdap.app.program.ProgramDescriptor) File(java.io.File)

Example 5 with ProgramClassLoader

use of io.cdap.cdap.internal.app.runtime.ProgramClassLoader in project cdap by caskdata.

the class PluginInstantiatorTest method testResourceOrder.

/**
 * If a plugin has some resources in main jar and in libraries, main jar should take precedence
 */
@Test
public void testResourceOrder() throws IOException {
    File appDir = TMP_FOLDER.newFolder();
    File pluginsDir = TMP_FOLDER.newFolder();
    File pluginDir = TMP_FOLDER.newFolder();
    File pluginArchive = TMP_FOLDER.newFile();
    File jarDir = TMP_FOLDER.newFolder();
    ArtifactId artifactId = new ArtifactId("dummy", new ArtifactVersion("1.0"), ArtifactScope.USER);
    CConfiguration cConf = CConfiguration.create();
    cConf.set(Constants.CFG_LOCAL_DATA_DIR, TMP_FOLDER.newFolder().getAbsolutePath());
    ProgramClassLoader programClassLoader = new ProgramClassLoader(cConf, appDir, this.getClass().getClassLoader());
    PluginInstantiator pluginInstantiator = new PluginInstantiator(cConf, programClassLoader, pluginsDir);
    FileUtils.write(new File(jarDir, "test.class"), "jarData");
    FileUtils.write(new File(pluginDir, "test.class"), "pluginData");
    BundleJarUtil.createJar(jarDir, new File(pluginDir, "library.jar"));
    BundleJarUtil.createJar(pluginDir, pluginArchive);
    pluginInstantiator.addArtifact(Locations.toLocation(pluginArchive), artifactId);
    PluginClassLoader loader = pluginInstantiator.getPluginClassLoader(artifactId, Collections.emptyList());
    Assert.assertEquals("pluginData", IOUtils.toString(loader.getResource("test.class")));
    pluginInstantiator.close();
}
Also used : ArtifactVersion(io.cdap.cdap.api.artifact.ArtifactVersion) ArtifactId(io.cdap.cdap.api.artifact.ArtifactId) ProgramClassLoader(io.cdap.cdap.internal.app.runtime.ProgramClassLoader) File(java.io.File) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) Test(org.junit.Test)

Aggregations

ProgramClassLoader (io.cdap.cdap.internal.app.runtime.ProgramClassLoader)5 FilterClassLoader (io.cdap.cdap.common.lang.FilterClassLoader)3 DirectoryClassLoader (io.cdap.cdap.common.lang.DirectoryClassLoader)2 File (java.io.File)2 ApplicationSpecification (io.cdap.cdap.api.app.ApplicationSpecification)1 ArtifactId (io.cdap.cdap.api.artifact.ArtifactId)1 ArtifactVersion (io.cdap.cdap.api.artifact.ArtifactVersion)1 CloseableClassLoader (io.cdap.cdap.api.artifact.CloseableClassLoader)1 DefaultProgram (io.cdap.cdap.app.program.DefaultProgram)1 ProgramDescriptor (io.cdap.cdap.app.program.ProgramDescriptor)1 ProgramClassLoaderProvider (io.cdap.cdap.app.runtime.ProgramClassLoaderProvider)1 ProgramRunner (io.cdap.cdap.app.runtime.ProgramRunner)1 CConfiguration (io.cdap.cdap.common.conf.CConfiguration)1 CombineClassLoader (io.cdap.cdap.common.lang.CombineClassLoader)1 PackageFilterClassLoader (io.cdap.cdap.common.lang.PackageFilterClassLoader)1 ProgramId (io.cdap.cdap.proto.id.ProgramId)1 Closeable (java.io.Closeable)1 Manifest (java.util.jar.Manifest)1 Test (org.junit.Test)1