Skip to content

Commit

Permalink
enable override for plugin (#790)
Browse files Browse the repository at this point in the history
* support .* for exclude

* support .* for exclude

* enable override for plugin

* optimize static import

* enable classpath for plugin

* add test for override

* remove unused import

* format

* update 2.2.5-SNAPSHOT
  • Loading branch information
lvjing2 committed Dec 5, 2023
1 parent 9c37315 commit 7de1384
Show file tree
Hide file tree
Showing 15 changed files with 282 additions and 72 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</modules>

<properties>
<sofa.ark.version>2.2.5</sofa.ark.version>
<sofa.ark.version>2.2.5-SNAPSHOT</sofa.ark.version>
<project.encoding>UTF-8</project.encoding>
<java.version>1.8</java.version>
<license.maven.plugin>3.0</license.maven.plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,20 +242,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(
FileUtils.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,22 +21,33 @@
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.jar.Handler;
import com.alipay.sofa.ark.loader.jar.JarUtils;
import com.alipay.sofa.ark.spi.constant.Constants;
import com.alipay.sofa.ark.spi.service.classloader.ClassLoaderService;
import com.google.common.cache.Cache;
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;
import java.net.URLConnection;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.jar.JarFile;

Expand Down Expand Up @@ -217,7 +228,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 +411,51 @@ 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;
if (filePath.contains(".jar")) {
bytes = getClassBytesFromJar(filePath, name.replace('.', '/') + ".class");
} else {
bytes = FileUtils.readFileToByteArray(new File(filePath));
}
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 +488,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

0 comments on commit 7de1384

Please sign in to comment.