use of io.cdap.cdap.common.lang.jar.ClassLoaderFolder in project cdap by caskdata.
the class DefaultArtifactInspector method inspectArtifact.
/**
* Inspect the given artifact to determine the classes contained in the artifact.
*
* @param artifactId the id of the artifact to inspect
* @param artifactFile the artifact file
* @param parentDescriptor {@link ArtifactDescriptor} of parent and grandparent (if any) artifacts.
* @param additionalPlugins Additional plugin classes
* @return metadata about the classes contained in the artifact
* @throws IOException if there was an exception opening the jar file
* @throws InvalidArtifactException if the artifact is invalid. For example, if the application main class is not
* actually an Application.
*/
@Override
public ArtifactClassesWithMetadata inspectArtifact(Id.Artifact artifactId, File artifactFile, List<ArtifactDescriptor> parentDescriptor, Set<PluginClass> additionalPlugins) throws IOException, InvalidArtifactException {
Path tmpDir = Paths.get(cConf.get(Constants.CFG_LOCAL_DATA_DIR), cConf.get(Constants.AppFabric.TEMP_DIR)).toAbsolutePath();
Files.createDirectories(tmpDir);
Location artifactLocation = Locations.toLocation(artifactFile);
EntityImpersonator entityImpersonator = new EntityImpersonator(artifactId.toEntityId(), impersonator);
Path stageDir = Files.createTempDirectory(tmpDir, artifactFile.getName());
try (ClassLoaderFolder clFolder = BundleJarUtil.prepareClassLoaderFolder(artifactLocation, () -> Files.createTempDirectory(stageDir, "unpacked-").toFile());
CloseableClassLoader parentClassLoader = createParentClassLoader(parentDescriptor, entityImpersonator);
CloseableClassLoader artifactClassLoader = artifactClassLoaderFactory.createClassLoader(clFolder.getDir());
PluginInstantiator pluginInstantiator = new PluginInstantiator(cConf, parentClassLoader == null ? artifactClassLoader : parentClassLoader, Files.createTempDirectory(stageDir, "plugins-").toFile(), false)) {
pluginInstantiator.addArtifact(artifactLocation, artifactId.toArtifactId());
ArtifactClasses.Builder builder = inspectApplications(artifactId, ArtifactClasses.builder(), artifactLocation, artifactClassLoader);
List<MetadataMutation> mutations = new ArrayList<>();
inspectPlugins(builder, artifactFile, artifactId.toEntityId(), pluginInstantiator, additionalPlugins, mutations);
return new ArtifactClassesWithMetadata(builder.build(), mutations);
} catch (EOFException | ZipException e) {
throw new InvalidArtifactException("Artifact " + artifactId + " is not a valid zip file.", e);
} finally {
try {
DirUtils.deleteDirectoryContents(stageDir.toFile());
} catch (IOException e) {
LOG.warn("Exception raised while deleting directory {}", stageDir, e);
}
}
}
use of io.cdap.cdap.common.lang.jar.ClassLoaderFolder in project cdap by cdapio.
the class AbstractProgramRuntimeService method createProgram.
/**
* Creates a {@link Program} for the given {@link ProgramRunner} from the given program jar {@link Location}.
*/
protected Program createProgram(CConfiguration cConf, ProgramRunner programRunner, ProgramDescriptor programDescriptor, ArtifactDetail artifactDetail, final File tempDir) throws IOException {
Location programJarLocation = artifactDetail.getDescriptor().getLocation();
ClassLoaderFolder classLoaderFolder;
try {
// If the program jar is not a directory, take a snapshot of the jar file to avoid mutation.
if (!programJarLocation.isDirectory()) {
File targetFile = new File(tempDir, "program.jar");
try {
programJarLocation = Locations.toLocation(Locations.linkOrCopyOverwrite(programJarLocation, targetFile));
} catch (FileAlreadyExistsException ex) {
LOG.warn("Program file {} already exists and can not be replaced.", targetFile.getAbsolutePath());
}
}
// Unpack the JAR file
classLoaderFolder = BundleJarUtil.prepareClassLoaderFolder(programJarLocation, () -> Files.createTempDirectory(tempDir.toPath(), "unpacked").toFile());
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
// should not happen
throw Throwables.propagate(e);
}
return Programs.create(cConf, programRunner, programDescriptor, programJarLocation, classLoaderFolder.getDir());
}
use of io.cdap.cdap.common.lang.jar.ClassLoaderFolder in project cdap by cdapio.
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));
}
use of io.cdap.cdap.common.lang.jar.ClassLoaderFolder in project cdap by cdapio.
the class ArtifactClassLoaderFactory method createClassLoader.
/**
* Unpack the given {@code artifactLocation} to a temporary directory and call
* {@link #createClassLoader(File)} to create the {@link ClassLoader}.
*
* @param artifactLocation the location of the artifact to create the classloader from
* @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
* @see #createClassLoader(File)
*/
CloseableClassLoader createClassLoader(Location artifactLocation, EntityImpersonator entityImpersonator) {
try {
ClassLoaderFolder classLoaderFolder = entityImpersonator.impersonate(() -> BundleJarUtil.prepareClassLoaderFolder(artifactLocation, () -> DirUtils.createTempDir(tmpDir)));
CloseableClassLoader classLoader = createClassLoader(classLoaderFolder.getDir());
return new CloseableClassLoader(classLoader, () -> {
Closeables.closeQuietly(classLoader);
Closeables.closeQuietly(classLoaderFolder);
});
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
use of io.cdap.cdap.common.lang.jar.ClassLoaderFolder 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));
}
Aggregations