This is an automated email from the ASF dual-hosted git repository. mivanac pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push: new de7834a03f GEODE-10407: check if class allready loaded (#7832) de7834a03f is described below commit de7834a03fb638401ce1f7c95a14e42febae8d9b Author: Mario Ivanac <48509724+miva...@users.noreply.github.com> AuthorDate: Wed Aug 24 10:14:18 2022 +0200 GEODE-10407: check if class allready loaded (#7832) * GEODE-10407: check if class allready loaded --- .../internal/classloader/ClassPathLoader.java | 6 +++ .../internal/classloader/ClasspathService.java | 3 ++ .../DeployJarChildFirstClassLoader.java | 7 +++ .../deployment/JarDeployerIntegrationTest.java | 54 ++++++++++++++++++++++ .../internal/LegacyClasspathServiceImpl.java | 4 ++ 5 files changed, 74 insertions(+) diff --git a/geode-core/src/main/java/org/apache/geode/internal/classloader/ClassPathLoader.java b/geode-core/src/main/java/org/apache/geode/internal/classloader/ClassPathLoader.java index 3059cc3f15..2d503c02f4 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/classloader/ClassPathLoader.java +++ b/geode-core/src/main/java/org/apache/geode/internal/classloader/ClassPathLoader.java @@ -196,4 +196,10 @@ public class ClassPathLoader { public JarDeploymentService getJarDeploymentService() { return jarDeploymentService; } + + public ClassLoader getClassloaderForArtifact(String artifactId) { + return classPathService.getClassloaderForArtifact(artifactId); + } + + } diff --git a/geode-core/src/main/java/org/apache/geode/internal/classloader/ClasspathService.java b/geode-core/src/main/java/org/apache/geode/internal/classloader/ClasspathService.java index 047b20980b..de10cfd845 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/classloader/ClasspathService.java +++ b/geode-core/src/main/java/org/apache/geode/internal/classloader/ClasspathService.java @@ -55,4 +55,7 @@ public interface ClasspathService { InputStream getResourceAsStream(final String name); Enumeration<URL> getResources(final String name) throws IOException; + + ClassLoader getClassloaderForArtifact(String artifactId); + } diff --git a/geode-core/src/main/java/org/apache/geode/internal/classloader/DeployJarChildFirstClassLoader.java b/geode-core/src/main/java/org/apache/geode/internal/classloader/DeployJarChildFirstClassLoader.java index 457df4287a..f10974a5f2 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/classloader/DeployJarChildFirstClassLoader.java +++ b/geode-core/src/main/java/org/apache/geode/internal/classloader/DeployJarChildFirstClassLoader.java @@ -70,6 +70,13 @@ public class DeployJarChildFirstClassLoader extends ChildFirstClassLoader { for (DeployJarChildFirstClassLoader sibling : artifactIdsToClassLoader.values().stream() .filter(Objects::nonNull).collect(Collectors.toList())) { try { + if (sibling.thisIsOld()) { + continue; + } + c = sibling.findLoadedClass(name); + if (c != null) { + break; + } c = sibling.findClass(name); if (c != null) { break; diff --git a/geode-deployment/geode-deployment-legacy/src/integrationTest/java/org/apache/geode/internal/deployment/JarDeployerIntegrationTest.java b/geode-deployment/geode-deployment-legacy/src/integrationTest/java/org/apache/geode/internal/deployment/JarDeployerIntegrationTest.java index c4154db798..044fa9efa1 100644 --- a/geode-deployment/geode-deployment-legacy/src/integrationTest/java/org/apache/geode/internal/deployment/JarDeployerIntegrationTest.java +++ b/geode-deployment/geode-deployment-legacy/src/integrationTest/java/org/apache/geode/internal/deployment/JarDeployerIntegrationTest.java @@ -52,6 +52,8 @@ public class JarDeployerIntegrationTest { private static File plainJarVersion1, plainJarVersion1b, plainJarVersion2, semanticJarVersion1, semanticJarVersion2, semanticJarVersion1b, semanticJarVersion1c; + private static File baseJar; + private File deployedDir; @BeforeClass @@ -74,6 +76,10 @@ public class JarDeployerIntegrationTest { jarBuilder.buildJar(semanticJarVersion1b, createClassContent("version1b", "Def")); semanticJarVersion1c = new File(stagedTempDir.newFolder("v1c"), "def.jar"); jarBuilder.buildJar(semanticJarVersion1c, createClassContent("version1c", "Def")); + + baseJar = new File(stagedDir, "base.jar"); + jarBuilder.buildJar(baseJar, create1ClassContent("ExceptionA"), + create2ClassContent("ExceptionB", "ExceptionA")); } @Before @@ -202,6 +208,31 @@ public class JarDeployerIntegrationTest { .isInstanceOf(ClassNotFoundException.class); } + @Test + public void deploy2JarsSetCurrentClassloaderTo1stAndLoadClassFrom2nd() throws Exception { + + // deploy def-1.0.jar + jarDeployer.deploy(semanticJarVersion1); + + // deploy base.jar + DeployedJar deployedJar = jarDeployer.deploy(baseJar); + + assertThat(deployedJar).isNotNull(); + + ClassPathLoader oldLoader = ClassPathLoader.getLatest(); + + // set current classloader to 1st + ClassLoader cl = oldLoader.getClassloaderForArtifact("def"); + + // load extended class and base class + cl.loadClass("jddunit.function2.ExceptionB"); + + // load base class + cl.loadClass("jddunit.function1.ExceptionA"); + + } + + private String getVersion(String classname) throws Exception { Class<?> def = ClassPathLoader.getLatest().forName(classname); assertThat(def).isNotNull(); @@ -216,4 +247,27 @@ public class JarDeployerIntegrationTest { + "public void execute(FunctionContext context) {context.getResultSender().lastResult(\"" + version + "\");}}"; } + + private static String create1ClassContent(String className1) { + return "package jddunit.function1;" + + "public class " + + className1 + " extends Exception {" + + "private static final long serialVersionUID = 1L;" + + "public " + className1 + "(String message) {" + + " super(message);" + + "}" + + "}"; + } + + private static String create2ClassContent(String className1, String className2) { + return "package jddunit.function2;" + "import jddunit.function1." + className2 + ";" + + "public class " + + className1 + " extends " + className2 + " {" + + "private static final long serialVersionUID = 1L;" + + "public " + className1 + "(String message) {" + + " super(message);" + + "}" + + "}"; + } + } diff --git a/geode-deployment/geode-deployment-legacy/src/main/java/org/apache/geode/classloader/internal/LegacyClasspathServiceImpl.java b/geode-deployment/geode-deployment-legacy/src/main/java/org/apache/geode/classloader/internal/LegacyClasspathServiceImpl.java index b09f85e3ba..8bb116dbc3 100644 --- a/geode-deployment/geode-deployment-legacy/src/main/java/org/apache/geode/classloader/internal/LegacyClasspathServiceImpl.java +++ b/geode-deployment/geode-deployment-legacy/src/main/java/org/apache/geode/classloader/internal/LegacyClasspathServiceImpl.java @@ -247,6 +247,10 @@ public class LegacyClasspathServiceImpl implements ClasspathService { return null; } + public ClassLoader getClassloaderForArtifact(String artifactId) { + return artifactIdsToClassLoader.get(artifactId); + } + private synchronized void rebuildClassLoaderForDeployedJars() { leafLoader = null; List<Deployment> deployments = jarDeploymentService.listDeployed();