All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.cdap.cdap.internal.app.runtime.plugin.PluginClassLoader Maven / Gradle / Ivy

There is a newer version: 6.10.1
Show newest version
/*
 * Copyright © 2015 Cask Data, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package io.cdap.cdap.internal.app.runtime.plugin;

import com.google.common.base.Preconditions;
import io.cdap.cdap.api.artifact.ArtifactId;
import io.cdap.cdap.app.program.ManifestFields;
import io.cdap.cdap.common.lang.CombineClassLoader;
import io.cdap.cdap.common.lang.DirectoryClassLoader;
import io.cdap.cdap.common.lang.PackageFilterClassLoader;
import io.cdap.cdap.internal.app.runtime.ProgramClassLoader;

import java.io.File;
import java.util.Set;
import java.util.jar.Manifest;

/**
 * ClassLoader for template plugin. The ClassLoader hierarchy is pretty complicated.
 * 

* First, we have the "Plugin Lib ClassLoader". * *

{@code
 *            CDAP System CL
 *                  ^
 *                  |
 *          Program Filter CL (cdap-api and hadoop classes only)
 *                  ^
 *                  |
 *             Template CL (expanded app bundle jar)
 *                  ^
 *                  |
 *       CombineCL of (Program Filter CL, Template Filter CL (Export-Package classes only))
 * }
* *

* The Plugin ClassLoader is then a URLClassLoader created by expanding the plugin bundle jar, with the parent * ClassLoader as the Combine ClassLoader. */ public class PluginClassLoader extends DirectoryClassLoader { private final ArtifactId artifactId; private final String topLevelJar; private final Set exportPackages; 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 exportPackages = ManifestFields.getExportPackages(manifest); ClassLoader filteredTemplateClassLoader = new PackageFilterClassLoader(templateClassLoader, exportPackages::contains); // The lib Classloader needs to be able to see all cdap api classes as well. // In this way, parent ClassLoader of the plugin ClassLoader will load class from the parent of the // template program class loader (which is a filtered CDAP classloader), // followed by template export-packages, then by a plugin lib jars. return new CombineClassLoader(programClassLoader.getParent(), filteredTemplateClassLoader); } PluginClassLoader(ArtifactId artifactId, File directory, String topLevelJar, ClassLoader parent) { super(directory, parent, "lib"); this.artifactId = artifactId; this.topLevelJar = topLevelJar; this.exportPackages = ManifestFields.getExportPackages(getManifest()); } /** * @return the plugin's artifact id */ public ArtifactId getArtifactId() { return artifactId; } /** * Creates a new {@link ClassLoader} that only exposes classes in packages declared by "Export-Package" * in the manifest. */ public ClassLoader getExportPackagesClassLoader() { return new PackageFilterClassLoader(this, exportPackages::contains); } /** * * @return a file name of top level plugin jar. Main plugin class should reside in this jar. */ public String getTopLevelJar() { return topLevelJar; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy