Search in sources :

Example 1 with ProgramClassLoader

use of co.cask.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
   * @throws IOException if there was an error copying or unpacking the artifact
   */
CloseableClassLoader createClassLoader(File unpackDir) throws IOException {
    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;
    if (programRunner instanceof ProgramClassLoaderProvider) {
        programClassLoader = new ProgramClassLoader(cConf, unpackDir, ((ProgramClassLoaderProvider) programRunner).createProgramClassLoaderParent());
    } else {
        programClassLoader = new ProgramClassLoader(cConf, unpackDir, FilterClassLoader.create(getClass().getClassLoader()));
    }
    final ClassLoader finalProgramClassLoader = programClassLoader;
    final ProgramRunner finalProgramRunner = programRunner;
    return new CloseableClassLoader(programClassLoader, new Closeable() {

        @Override
        public void close() {
            Closeables.closeQuietly((Closeable) finalProgramClassLoader);
            if (finalProgramRunner instanceof Closeable) {
                Closeables.closeQuietly((Closeable) finalProgramRunner);
            }
        }
    });
}
Also used : ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) ProgramClassLoaderProvider(co.cask.cdap.app.runtime.ProgramClassLoaderProvider) Closeable(java.io.Closeable) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) FilterClassLoader(co.cask.cdap.common.lang.FilterClassLoader) ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) ProgramRunner(co.cask.cdap.app.runtime.ProgramRunner) IOException(java.io.IOException)

Example 2 with ProgramClassLoader

use of co.cask.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(), SparkRuntimeUtils.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(co.cask.cdap.common.lang.FilterClassLoader) ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) FilterClassLoader(co.cask.cdap.common.lang.FilterClassLoader) ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) DefaultProgram(co.cask.cdap.app.program.DefaultProgram) ProgramDescriptor(co.cask.cdap.app.program.ProgramDescriptor) File(java.io.File)

Example 3 with ProgramClassLoader

use of co.cask.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, Predicates.in(exportPackages));
    // followed by template export-packages, then by a plugin lib jars.
    return new CombineClassLoader(programClassLoader.getParent(), ImmutableList.of(filteredTemplateClassLoader));
}
Also used : CombineClassLoader(co.cask.cdap.common.lang.CombineClassLoader) ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) DirectoryClassLoader(co.cask.cdap.common.lang.DirectoryClassLoader) PackageFilterClassLoader(co.cask.cdap.common.lang.PackageFilterClassLoader) CombineClassLoader(co.cask.cdap.common.lang.CombineClassLoader) Manifest(java.util.jar.Manifest) PackageFilterClassLoader(co.cask.cdap.common.lang.PackageFilterClassLoader)

Example 4 with ProgramClassLoader

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

the class ArtifactRepositoryTest method createAppClassLoader.

private static ProgramClassLoader createAppClassLoader(File jarFile) throws IOException {
    final File unpackDir = DirUtils.createTempDir(TMP_FOLDER.newFolder());
    BundleJarUtil.unJar(Files.newInputStreamSupplier(jarFile), unpackDir);
    return new ProgramClassLoader(cConf, unpackDir, FilterClassLoader.create(ArtifactRepositoryTest.class.getClassLoader()));
}
Also used : ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) File(java.io.File)

Example 5 with ProgramClassLoader

use of co.cask.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
   * @throws IOException If failed to create the program
   */
public static Program create(CConfiguration cConf, Program originalProgram, ProgramId programId, @Nullable ProgramRunner programRunner) throws IOException {
    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(co.cask.cdap.api.app.ApplicationSpecification) ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) FilterClassLoader(co.cask.cdap.common.lang.FilterClassLoader) ProgramClassLoader(co.cask.cdap.internal.app.runtime.ProgramClassLoader) ProgramId(co.cask.cdap.proto.id.ProgramId)

Aggregations

ProgramClassLoader (co.cask.cdap.internal.app.runtime.ProgramClassLoader)5 FilterClassLoader (co.cask.cdap.common.lang.FilterClassLoader)3 File (java.io.File)2 ApplicationSpecification (co.cask.cdap.api.app.ApplicationSpecification)1 CloseableClassLoader (co.cask.cdap.api.artifact.CloseableClassLoader)1 DefaultProgram (co.cask.cdap.app.program.DefaultProgram)1 ProgramDescriptor (co.cask.cdap.app.program.ProgramDescriptor)1 ProgramClassLoaderProvider (co.cask.cdap.app.runtime.ProgramClassLoaderProvider)1 ProgramRunner (co.cask.cdap.app.runtime.ProgramRunner)1 CombineClassLoader (co.cask.cdap.common.lang.CombineClassLoader)1 DirectoryClassLoader (co.cask.cdap.common.lang.DirectoryClassLoader)1 PackageFilterClassLoader (co.cask.cdap.common.lang.PackageFilterClassLoader)1 ProgramId (co.cask.cdap.proto.id.ProgramId)1 Closeable (java.io.Closeable)1 IOException (java.io.IOException)1 Manifest (java.util.jar.Manifest)1