Search in sources :

Example 6 with CloseableClassLoader

use of io.cdap.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class AbstractArtifactManager method createClassLoader.

@Override
public CloseableClassLoader createClassLoader(@Nullable String namespace, ArtifactInfo artifactInfo, @Nullable ClassLoader parentClassLoader) throws IOException, UnauthorizedException {
    ClassLoaderFolder folder = BundleJarUtil.prepareClassLoaderFolder(getArtifactLocation(artifactInfo, namespace), () -> DirUtils.createTempDir(tmpDir));
    DirectoryClassLoader directoryClassLoader = new DirectoryClassLoader(folder.getDir(), parentClassLoader == null ? bootstrapClassLoader : parentClassLoader, "lib");
    return new CloseableClassLoader(directoryClassLoader, new ClassLoaderCleanup(directoryClassLoader, folder));
}
Also used : DirectoryClassLoader(io.cdap.cdap.common.lang.DirectoryClassLoader) CloseableClassLoader(io.cdap.cdap.api.artifact.CloseableClassLoader) ClassLoaderFolder(io.cdap.cdap.common.lang.jar.ClassLoaderFolder)

Example 7 with CloseableClassLoader

use of io.cdap.cdap.api.artifact.CloseableClassLoader 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 8 with CloseableClassLoader

use of io.cdap.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class ArtifactClassLoaderFactory method createClassLoader.

/**
 * Creates a multi level classloader where each location in the specified iterator corresponds to a classloader whose
 * parent is built from the location behind it.
 *
 * @param artifactLocations the locations of the artifact to create the classloader from
 * @return a closeable classloader based off the specified artifacts; on closing the returned {@link ClassLoader},
 *         all temporary resources created for the classloader will be removed
 * @see #createClassLoader(File)
 */
CloseableClassLoader createClassLoader(Iterator<Location> artifactLocations, EntityImpersonator entityImpersonator) {
    if (!artifactLocations.hasNext()) {
        throw new IllegalArgumentException("Cannot create a classloader without an artifact.");
    }
    Location artifactLocation = artifactLocations.next();
    if (!artifactLocations.hasNext()) {
        return createClassLoader(artifactLocation, entityImpersonator);
    }
    try {
        ClassLoaderFolder classLoaderFolder = entityImpersonator.impersonate(() -> BundleJarUtil.prepareClassLoaderFolder(artifactLocation, () -> DirUtils.createTempDir(tmpDir)));
        CloseableClassLoader parentClassLoader = createClassLoader(artifactLocations, entityImpersonator);
        return new CloseableClassLoader(new DirectoryClassLoader(classLoaderFolder.getDir(), parentClassLoader, "lib"), () -> {
            Closeables.closeQuietly(parentClassLoader);
            Closeables.closeQuietly(classLoaderFolder);
        });
    } catch (Exception e) {
        throw Throwables.propagate(e);
    }
}
Also used : DirectoryClassLoader(io.cdap.cdap.common.lang.DirectoryClassLoader) CloseableClassLoader(io.cdap.cdap.api.artifact.CloseableClassLoader) ClassLoaderFolder(io.cdap.cdap.common.lang.jar.ClassLoaderFolder) Location(org.apache.twill.filesystem.Location)

Example 9 with CloseableClassLoader

use of io.cdap.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class DefaultArtifactRepository method addArtifact.

@Override
public ArtifactDetail addArtifact(final Id.Artifact artifactId, final File artifactFile, @Nullable Set<ArtifactRange> parentArtifacts, @Nullable Set<PluginClass> additionalPlugins, Map<String, String> properties) throws Exception {
    if (additionalPlugins != null) {
        validatePluginSet(additionalPlugins);
    }
    parentArtifacts = parentArtifacts == null ? Collections.emptySet() : parentArtifacts;
    CloseableClassLoader parentClassLoader = null;
    EntityImpersonator entityImpersonator = new EntityImpersonator(artifactId.toEntityId(), impersonator);
    List<ArtifactDescriptor> parentDescriptors = new ArrayList<>();
    if (!parentArtifacts.isEmpty()) {
        validateParentSet(artifactId, parentArtifacts);
        parentDescriptors = getParentArtifactDescriptors(artifactId, parentArtifacts);
    }
    additionalPlugins = additionalPlugins == null ? Collections.emptySet() : additionalPlugins;
    ArtifactClassesWithMetadata artifactClassesWithMetadata = inspectArtifact(artifactId, artifactFile, parentDescriptors, additionalPlugins);
    ArtifactMeta meta = new ArtifactMeta(artifactClassesWithMetadata.getArtifactClasses(), parentArtifacts, properties);
    ArtifactDetail artifactDetail = artifactStore.write(artifactId, meta, artifactFile, entityImpersonator);
    ArtifactDescriptor descriptor = artifactDetail.getDescriptor();
    // info hides some fields that are available in detail, such as the location of the artifact
    ArtifactInfo artifactInfo = new ArtifactInfo(descriptor.getArtifactId(), artifactDetail.getMeta().getClasses(), artifactDetail.getMeta().getProperties());
    // add system metadata for artifacts
    writeSystemMetadata(artifactId.toEntityId(), artifactInfo);
    // add plugin metadata, these metadata can be in any scope depending on the artifact scope
    metadataServiceClient.batch(artifactClassesWithMetadata.getMutations());
    return artifactDetail;
}
Also used : ArtifactInfo(io.cdap.cdap.api.artifact.ArtifactInfo) EntityImpersonator(io.cdap.cdap.security.impersonation.EntityImpersonator) ArrayList(java.util.ArrayList) CloseableClassLoader(io.cdap.cdap.api.artifact.CloseableClassLoader)

Example 10 with CloseableClassLoader

use of io.cdap.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class InMemoryConfigurator method config.

/**
 * Executes the <code>Application.configure</code> within the same JVM.
 * <p>
 * This method could be dangerous and should be used only in standalone mode.
 * </p>
 *
 * @return A instance of {@link ListenableFuture}.
 */
@Override
public ListenableFuture<ConfigResponse> config() {
    // Create the classloader
    EntityImpersonator classLoaderImpersonator = new EntityImpersonator(artifactId.toEntityId(), impersonator);
    try (CloseableClassLoader classLoader = artifactRepository.createArtifactClassLoader(new ArtifactDescriptor(artifactId.getNamespace().getId(), artifactId.toArtifactId(), artifactLocation), classLoaderImpersonator)) {
        SettableFuture<ConfigResponse> result = SettableFuture.create();
        Object appMain = classLoader.loadClass(appClassName).newInstance();
        if (!(appMain instanceof Application)) {
            throw new IllegalStateException(String.format("Application main class is of invalid type: %s", appMain.getClass().getName()));
        }
        Application<?> app = (Application<?>) appMain;
        ConfigResponse response = createResponse(app, classLoader);
        result.set(response);
        return result;
    } catch (Throwable t) {
        return Futures.immediateFailedFuture(t);
    }
}
Also used : ArtifactDescriptor(io.cdap.cdap.internal.app.runtime.artifact.ArtifactDescriptor) EntityImpersonator(io.cdap.cdap.security.impersonation.EntityImpersonator) ConfigResponse(io.cdap.cdap.app.deploy.ConfigResponse) CloseableClassLoader(io.cdap.cdap.api.artifact.CloseableClassLoader) Application(io.cdap.cdap.api.app.Application)

Aggregations

CloseableClassLoader (io.cdap.cdap.api.artifact.CloseableClassLoader)10 EntityImpersonator (io.cdap.cdap.security.impersonation.EntityImpersonator)6 ClassLoaderFolder (io.cdap.cdap.common.lang.jar.ClassLoaderFolder)4 DirectoryClassLoader (io.cdap.cdap.common.lang.DirectoryClassLoader)3 ArtifactDescriptor (io.cdap.cdap.internal.app.runtime.artifact.ArtifactDescriptor)3 Application (io.cdap.cdap.api.app.Application)2 InvalidArtifactException (io.cdap.cdap.common.InvalidArtifactException)2 IOException (java.io.IOException)2 JsonIOException (com.google.gson.JsonIOException)1 Injector (com.google.inject.Injector)1 ApplicationClass (io.cdap.cdap.api.artifact.ApplicationClass)1 ArtifactClasses (io.cdap.cdap.api.artifact.ArtifactClasses)1 ArtifactId (io.cdap.cdap.api.artifact.ArtifactId)1 ArtifactInfo (io.cdap.cdap.api.artifact.ArtifactInfo)1 AccessException (io.cdap.cdap.api.security.AccessException)1 RunnableTask (io.cdap.cdap.api.service.worker.RunnableTask)1 RunnableTaskContext (io.cdap.cdap.api.service.worker.RunnableTaskContext)1 RunnableTaskRequest (io.cdap.cdap.api.service.worker.RunnableTaskRequest)1 SystemAppTaskContext (io.cdap.cdap.api.service.worker.SystemAppTaskContext)1 ConfigResponse (io.cdap.cdap.app.deploy.ConfigResponse)1