diff --git a/test/src/main/java/com/navercorp/pinpoint/test/plugin/AbstractPinpointPluginTestSuite.java b/test/src/main/java/com/navercorp/pinpoint/test/plugin/AbstractPinpointPluginTestSuite.java index 8d4a0e448116..f4edd1111323 100644 --- a/test/src/main/java/com/navercorp/pinpoint/test/plugin/AbstractPinpointPluginTestSuite.java +++ b/test/src/main/java/com/navercorp/pinpoint/test/plugin/AbstractPinpointPluginTestSuite.java @@ -16,12 +16,13 @@ package com.navercorp.pinpoint.test.plugin; +import com.navercorp.pinpoint.common.annotations.VisibleForTesting; +import com.navercorp.pinpoint.common.util.SystemProperty; import com.navercorp.pinpoint.test.plugin.util.ArrayUtils; import com.navercorp.pinpoint.test.plugin.util.CodeSourceUtils; import com.navercorp.pinpoint.test.plugin.util.StringUtils; import com.navercorp.pinpoint.test.plugin.util.TestLogger; import com.navercorp.pinpoint.test.plugin.util.TestPluginVersion; - import org.junit.internal.runners.statements.RunAfters; import org.junit.internal.runners.statements.RunBefores; import org.junit.runner.Runner; @@ -35,11 +36,11 @@ import java.lang.management.ManagementFactory; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -92,21 +93,13 @@ public AbstractPinpointPluginTestSuite(Class testClass) throws Initialization Repository repository = testClass.getAnnotation(Repository.class); this.repositoryUrls = getRepository(repository); - List classLoaderLibs = collectLib(getClass().getClassLoader()); - if (logger.isDebugEnabled()) { - for (ClassLoaderLib classLoaderLib : classLoaderLibs) { - logger.debug("classLoader:{}", classLoaderLib.getClassLoader()); - for (URL lib : classLoaderLib.getLibs()) { - logger.debug("-> {}", classLoaderLib.getClassLoader(), lib); - } - } - } + List libs = collectLibs(getClass().getClassLoader()); final LibraryFilter requiredLibraryFilter = new LibraryFilter( LibraryFilter.createContainsMatcher(PluginClassLoading.getContainsCheckClassPath()), LibraryFilter.createGlobMatcher(PluginClassLoading.getGlobMatchesCheckClassPath())); - this.requiredLibraries = filterLib(classLoaderLibs, requiredLibraryFilter); + this.requiredLibraries = filterLibs(libs, requiredLibraryFilter); if (logger.isDebugEnabled()) { for (String requiredLibrary : requiredLibraries) { logger.debug("requiredLibraries :{}", requiredLibrary); @@ -116,10 +109,10 @@ public AbstractPinpointPluginTestSuite(Class testClass) throws Initialization final LibraryFilter mavenDependencyLibraryFilter = new LibraryFilter( LibraryFilter.createContainsMatcher(PluginClassLoading.MAVEN_DEPENDENCY_CLASS_PATHS)); - this.mavenDependencyLibraries = filterLib(classLoaderLibs, mavenDependencyLibraryFilter); + this.mavenDependencyLibraries = filterLibs(libs, mavenDependencyLibraryFilter); if (logger.isDebugEnabled()) { for (String mavenDependencyLibrary : mavenDependencyLibraries) { - logger.debug("mavenDependencyLibraries :{}", mavenDependencyLibrary); + logger.debug("mavenDependencyLibraries: {}", mavenDependencyLibrary); } } this.testClassLocation = resolveTestClassLocation(testClass); @@ -187,54 +180,86 @@ private String resolveTestClassLocation(Class testClass) { return toPathString(testClassLocation); } - private static class ClassLoaderLib { - private final ClassLoader cl; - private final List libs; + private List filterLibs(List classPaths, LibraryFilter classPathFilter) { + final Set result = new LinkedHashSet<>(); + for (String classPath: classPaths) { + if (classPathFilter.filter(classPath)) { + result.add(classPath); + } + } + return new ArrayList<>(result); + } + + private List collectLibs(ClassLoader sourceCl) { + List result = new ArrayList<>(); + final ClassLoader termCl = ClassLoader.getSystemClassLoader().getParent(); + for (ClassLoader cl : iterateClassLoaderChain(sourceCl, termCl)) { + final List libs = extractLibrariesFromClassLoader(cl); + if (libs != null) { + result.addAll(libs); + if (logger.isDebugEnabled()) { + logger.debug("classLoader: {}", cl); + for (String lib : libs) { + logger.debug(" -> {}", lib); + } + } + } + } + return result; + } - public ClassLoaderLib(ClassLoader cl, List libs) { - this.cl = cl; - this.libs = libs; + private static Iterable iterateClassLoaderChain(ClassLoader src, ClassLoader term) { + final List classLoaders = new ArrayList<>(8); + ClassLoader cl = src; + while (cl != term) { + classLoaders.add(cl); + if (cl == Object.class.getClassLoader()) { + break; + } + cl = cl.getParent(); } + return classLoaders; + } - public ClassLoader getClassLoader() { - return cl; + private static List extractLibrariesFromClassLoader(ClassLoader cl) { + if (cl instanceof URLClassLoader) { + return extractLibrariesFromURLClassLoader((URLClassLoader) cl); } + if (cl == ClassLoader.getSystemClassLoader()) { + return extractLibrariesFromSystemClassLoader(); + } + return null; + } - public List getLibs() { - return libs; + private static List extractLibrariesFromURLClassLoader(URLClassLoader cl) { + final URL[] urls = cl.getURLs(); + final List paths = new ArrayList<>(urls.length); + for (URL url: urls) { + paths.add(normalizePath(toPathString(url))); } + return paths; } - private List filterLib(List classLoaderLibs, LibraryFilter classPathFilter) { - Set result = new HashSet<>(); - for (ClassLoaderLib classLoaderLib : classLoaderLibs) { - List libs = classLoaderLib.getLibs(); - for (URL lib : libs) { - if (classPathFilter.filter(lib)) { - final String filterLibs = toPathString(lib); - if (filterLibs != null) { - result.add(filterLibs); - } - } - } + private static List extractLibrariesFromSystemClassLoader() { + final String classPath = SystemProperty.INSTANCE.getProperty("java.class.path"); + if (StringUtils.isEmpty(classPath)) { + return Collections.emptyList(); } - List libs = new ArrayList<>(result); - libs.sort(Comparator.naturalOrder()); - return libs; + final List paths = Arrays.asList(classPath.split(":")); + return normalizePaths(paths); } - private List collectLib(ClassLoader cl) { - List libs = new ArrayList<>(); - while (cl != null) { - if (cl instanceof URLClassLoader) { - URLClassLoader ucl = ((URLClassLoader) cl); - URL[] urLs = ucl.getURLs(); - libs.add(new ClassLoaderLib(cl, Arrays.asList(urLs))); - } + @VisibleForTesting + static String normalizePath(String classPath) { + return Paths.get(classPath).toAbsolutePath().normalize().toString(); + } - cl = cl.getParent(); + private static List normalizePaths(List classPaths) { + final List result = new ArrayList<>(classPaths.size()); + for (String cp: classPaths) { + result.add(normalizePath(cp)); } - return libs; + return result; } private static String toPathString(URL url) { diff --git a/test/src/main/java/com/navercorp/pinpoint/test/plugin/LibraryFilter.java b/test/src/main/java/com/navercorp/pinpoint/test/plugin/LibraryFilter.java index 8c0a570b82e6..383f8b07efc4 100644 --- a/test/src/main/java/com/navercorp/pinpoint/test/plugin/LibraryFilter.java +++ b/test/src/main/java/com/navercorp/pinpoint/test/plugin/LibraryFilter.java @@ -32,15 +32,19 @@ public LibraryFilter(LibraryMatcher... matchers) { this.matchers = Objects.requireNonNull(matchers, "matchers"); } - public boolean filter(URL url) { + public boolean filter(String cp) { for (LibraryMatcher matcher : matchers) { - if (matcher.include(url.getFile())) { + if (matcher.include(cp)) { return true; } } return false; } + public boolean filter(URL url) { + return filter(url.getFile()); + } + interface LibraryMatcher { boolean include(String filePath); } diff --git a/test/src/test/java/com/navercorp/pinpoint/test/plugin/AbstractPinpointPluginTestSuiteTest.java b/test/src/test/java/com/navercorp/pinpoint/test/plugin/AbstractPinpointPluginTestSuiteTest.java new file mode 100644 index 000000000000..7b38a2fd0d00 --- /dev/null +++ b/test/src/test/java/com/navercorp/pinpoint/test/plugin/AbstractPinpointPluginTestSuiteTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2022 NAVER Corp. + * + * 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 com.navercorp.pinpoint.test.plugin; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author youngjin.kim2 + */ +@ExtendWith(MockitoExtension.class) +public class AbstractPinpointPluginTestSuiteTest { + + @Test + public void normalizeShouldWork() { + final String result = AbstractPinpointPluginTestSuite.normalizePath("./foo/bar/../zoo"); + final String expect = System.getProperty("user.dir") + "/foo/zoo"; + assertThat(result).isEqualTo(expect); + } + +}