Skip to content

Commit

Permalink
enable plugin for override
Browse files Browse the repository at this point in the history
  • Loading branch information
lvjing2 committed Nov 27, 2023
1 parent 9ec2836 commit fd45e48
Show file tree
Hide file tree
Showing 15 changed files with 258 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -241,20 +241,20 @@ private static String parseArtifactIdFromJarInJar(String jarLocation) throws IOE

private static String parseArtifactIdFromJarInJarInJarMore(String jarLocation)
throws IOException {
com.alipay.sofa.ark.loader.jar.JarFile jarFile = getTemporaryRootJarFromJarLocation(jarLocation);
com.alipay.sofa.ark.loader.jar.JarFile jarFile = getNestedRootJarFromJarLocation(jarLocation);
JarFileArchive jarFileArchive = new JarFileArchive(jarFile);
return jarFileArchive.getPomProperties().getProperty(JAR_ARTIFACT_ID);
}

public static com.alipay.sofa.ark.loader.jar.JarFile getTemporaryRootJarFromJarLocation(String jarLocation)
throws IOException {
public static com.alipay.sofa.ark.loader.jar.JarFile getNestedRootJarFromJarLocation(String jarLocation)
throws IOException {
// /xxx/xxx/xxx-starter-1.0.0-SNAPSHOT.jar!/BOOT-INF/lib/xxx2-starter-1.1.4-SNAPSHOT-ark-biz.jar!/lib/xxx3-230605-sofa.jar
String[] js = jarLocation.split(JAR_SEPARATOR, -1);
com.alipay.sofa.ark.loader.jar.JarFile rJarFile = new com.alipay.sofa.ark.loader.jar.JarFile(
new File(js[0]));
for (int i = 1; i < js.length; i++) {
String jPath = js[i];
if (jPath == null || jPath.isEmpty()) {
if (StringUtils.isEmpty(jPath) || !jPath.endsWith(".jar")) {
break;
}
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,53 +43,62 @@
*/
public class PluginModel implements Plugin {

private String pluginName;
private String pluginName;

private String groupId;
private String groupId;

private String artifactId;
private String artifactId;

private String version;
private String version;

private int priority = DEFAULT_PRECEDENCE;
private int priority = DEFAULT_PRECEDENCE;

private Set<String> exportPackages;
/**
* 0. default as 'classLoader' for load those classes in plugin classLoader
* 1. 'override' for load those classes only as files, and those will be reload in other classLoaders.
*/
public static final String EXPORTMODE_CLASSLOADER = "classLoader";
public static final String EXPORTMODE_OVERRIDE = "override";
public static final String EXPORTMODE_UNKNOWN = "unknown";
private String exportMode = EXPORTMODE_CLASSLOADER;

private Set<String> exportPackageNodes = new HashSet<>();
private Set<String> exportPackages;

private Set<String> exportPackageStems = new HashSet<>();
private Set<String> exportPackageNodes = new HashSet<>();

private Set<String> exportClasses;
private Set<String> exportPackageStems = new HashSet<>();

private Set<String> importPackages;
private Set<String> exportClasses;

private Set<String> importPackageNodes = new HashSet<>();
private Set<String> importPackages;

private Set<String> importPackageStems = new HashSet<>();
private Set<String> importPackageNodes = new HashSet<>();

private Set<String> importClasses;
private Set<String> importPackageStems = new HashSet<>();

private Set<String> importResources = new HashSet<>();
private Set<String> importClasses;

private Set<String> importPrefixResourceStems = new HashSet<>();
private Set<String> importSuffixResourceStems = new HashSet<>();
private Set<String> importResources = new HashSet<>();

private Set<String> exportResources = new HashSet<>();
private Set<String> importPrefixResourceStems = new HashSet<>();
private Set<String> importSuffixResourceStems = new HashSet<>();

private Set<String> exportPrefixResourceStems = new HashSet<>();
private Set<String> exportSuffixResourceStems = new HashSet<>();
private Set<String> exportResources = new HashSet<>();

private String activator;
private Set<String> exportPrefixResourceStems = new HashSet<>();
private Set<String> exportSuffixResourceStems = new HashSet<>();

private URL[] urls;
private String activator;

private URL pluginUrl;
private URL[] urls;

private ClassLoader pluginClassLoader;
private URL pluginUrl;

private PluginContext pluginContext;
private ClassLoader pluginClassLoader;

private PluginActivator pluginActivator;
private PluginContext pluginContext;

private PluginActivator pluginActivator;

public PluginModel setPluginName(String pluginName) {
this.pluginName = pluginName;
Expand Down Expand Up @@ -126,6 +135,11 @@ public PluginModel setClassPath(URL[] urls) {
return this;
}

public PluginModel setExportMode(String exportMode) {
this.exportMode = exportMode;
return this;
}

public PluginModel setExportPackages(String exportPackages) {
this.exportPackages = StringUtils.strToSet(exportPackages, Constants.MANIFEST_VALUE_SPLIT);
ParseUtils.parsePackageNodeAndStem(this.exportPackages, this.exportPackageStems,
Expand Down Expand Up @@ -232,6 +246,14 @@ public PluginContext getPluginContext() {
return this.pluginContext;
}

@Override
public String getExportMode() {
if (StringUtils.isEmpty(this.exportMode)) {
return EXPORTMODE_CLASSLOADER;
}
return this.exportMode;
}

@Override
public Set<String> getExportPackages() {
return this.exportPackages;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,23 @@
import com.alipay.sofa.ark.common.log.ArkLoggerFactory;
import com.alipay.sofa.ark.common.util.StringUtils;
import com.alipay.sofa.ark.container.model.BizModel;
import com.alipay.sofa.ark.container.model.PluginModel;
import com.alipay.sofa.ark.container.service.ArkServiceContainerHolder;
import com.alipay.sofa.ark.exception.ArkLoaderException;
import com.alipay.sofa.ark.loader.archive.JarFileArchive;
import com.alipay.sofa.ark.loader.jar.Handler;
import com.alipay.sofa.ark.loader.jar.JarUtils;
import com.alipay.sofa.ark.spi.constant.Constants;
import com.alipay.sofa.ark.spi.model.Plugin;
import com.alipay.sofa.ark.spi.service.classloader.ClassLoaderService;
import com.google.common.cache.Cache;
import javafx.util.Pair;
import org.apache.commons.io.FileUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
Expand All @@ -38,7 +46,9 @@
import java.security.PrivilegedExceptionAction;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import static com.google.common.cache.CacheBuilder.newBuilder;
import static java.util.concurrent.TimeUnit.SECONDS;
Expand Down Expand Up @@ -217,7 +227,9 @@ protected Class<?> loadClassWithCache(String name, boolean resolve) throws ArkLo

return resultInCache.getClazz();
} catch (ExecutionException e) {
throw new ArkLoaderException(String.format("[Ark Loader] unexpected exception when load class: %s", name), e.getCause());
throw new ArkLoaderException(
String.format("[Ark Loader] unexpected exception when load class: %s", name),
e.getCause());
}
}

Expand Down Expand Up @@ -398,6 +410,47 @@ protected Class<?> resolveJDKClass(String name) {
* @return
*/
protected Class<?> resolveExportClass(String name) {
if (!PluginModel.EXPORTMODE_OVERRIDE.equals(classloaderService.getExportMode(name))) {
return doResolveExportClass(name);
} else {
ClassLoader classLoader = classloaderService.findExportClassLoader(name);
URL url = classLoader.getResource(name.replace('.', '/') + ".class");
if (url != null) {
String filePath = url.getFile().replaceFirst("file:", "");
try {
byte[] bytes = getClassBytesFromJar(filePath, name.replace('.', '/') + ".class");
return defineClass(name, bytes, 0, bytes.length);
} catch (Exception e) {
ArkLoggerFactory.getDefaultLogger().warn(
String.format("can't convert class to reLoad by bizClassLoader: %s",
e.getMessage()));
throw new RuntimeException(e);
}
} else {
return null;
}
}
}

private byte[] getClassBytesFromJar(String jarFilePath, String className) throws IOException {

com.alipay.sofa.ark.loader.jar.JarFile jarFile = JarUtils
.getNestedRootJarFromJarLocation(jarFilePath);
try (InputStream inputStream = jarFile.getInputStream(jarFile.getJarEntry(className))) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesRead;

while ((bytesRead = inputStream.read(buffer, 0, bufferSize)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}

return byteArrayOutputStream.toByteArray();
}
}

private Class<?> doResolveExportClass(String name) {
if (shouldFindExportedClass(name)) {
ClassLoader importClassLoader = classloaderService.findExportClassLoader(name);
if (importClassLoader != null) {
Expand Down Expand Up @@ -430,7 +483,7 @@ protected Class<?> resolveExportClass(String name) {
} else {
return clazz;
}
} catch (ClassNotFoundException | IOException e) {
} catch (ClassNotFoundException | NoClassDefFoundError | IOException e) {
// just log when debug level
if (ArkLoggerFactory.getDefaultLogger().isDebugEnabled()) {
// log debug message
Expand Down
Loading

0 comments on commit fd45e48

Please sign in to comment.