From a566ac6d69008b16296d623c490d5a8b6179f96f Mon Sep 17 00:00:00 2001 From: ronmamo <2588829+ronmamo@users.noreply.github.com> Date: Fri, 16 Jun 2023 00:14:12 +0700 Subject: [PATCH] ref-0.10.3 (#418) * Bump maven-bundle-plugin from 5.1.2 to 5.1.8 (#408) Bumps maven-bundle-plugin from 5.1.2 to 5.1.8. --- updated-dependencies: - dependency-name: org.apache.felix:maven-bundle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump gson from 2.8.8 to 2.9.1 (#417) Bumps [gson](https://github.com/google/gson) from 2.8.8 to 2.9.1. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.8.8...gson-parent-2.9.1) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump slf4j-simple from 1.7.32 to 1.7.36 (#416) Bumps [slf4j-simple](https://github.com/qos-ch/slf4j) from 1.7.32 to 1.7.36. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.32...v_1.7.36) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump slf4j-api from 1.7.32 to 1.7.36 (#415) Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.32 to 1.7.36. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.32...v_1.7.36) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump junit-jupiter-engine from 5.8.1 to 5.9.0 (#406) Bumps [junit-jupiter-engine](https://github.com/junit-team/junit5) from 5.8.1 to 5.9.0. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.8.1...r5.9.0) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump jboss-vfs from 3.2.15.Final to 3.2.17.Final (#399) Bumps [jboss-vfs](https://github.com/jbossas/jboss-vfs) from 3.2.15.Final to 3.2.17.Final. - [Release notes](https://github.com/jbossas/jboss-vfs/releases) - [Commits](https://github.com/jbossas/jboss-vfs/compare/3.2.15.Final...3.2.17.Final) --- updated-dependencies: - dependency-name: org.jboss:jboss-vfs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Issue with new releases of OpenJDK and Zulu. fix #395 (#396) * fix #395 * Refactor to use VirtualJarInputStream.root instead of JarInputDir which is much slower. fix #395 Co-authored-by: Dominik Kessler * Bump maven-jar-plugin from 3.2.0 to 3.2.2 (#381) Bumps [maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.2.0 to 3.2.2. - [Release notes](https://github.com/apache/maven-jar-plugin/releases) - [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.2.0...maven-jar-plugin-3.2.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-jar-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Make URL more accurate (#302) * rev * null check params, update jdk tests, auto close dir * remove jdk tests * Improve MAVEN build Performance (#363) Co-authored-by: fdse Co-authored-by: ronmamo <2588829+ronmamo@users.noreply.github.com> * synthetic/lambda cherry-picked from PR #290 by @ziqin --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: kesslerd Co-authored-by: Dominik Kessler Co-authored-by: Chen Co-authored-by: ronma Co-authored-by: ChenZhangg <32891042+ChenZhangg@users.noreply.github.com> Co-authored-by: fdse --- pom.xml | 17 +- .../java/org/reflections/Reflections.java | 8 +- .../org/reflections/util/ClasspathHelper.java | 3 +- .../util/ConfigurationBuilder.java | 8 +- .../java/org/reflections/util/NameHelper.java | 2 +- .../java/org/reflections/vfs/JbossDir.java | 12 +- src/main/java/org/reflections/vfs/Vfs.java | 6 +- src/test/java/org/reflections/JdkTests.java | 258 ------------------ src/test/java/org/reflections/MoreTests.java | 25 ++ .../java/org/reflections/NameHelperTest.java | 19 +- .../java/org/reflections/ReflectionsTest.java | 9 +- .../java/org/reflections/UsageTestModel.java | 25 ++ 12 files changed, 102 insertions(+), 290 deletions(-) delete mode 100644 src/test/java/org/reflections/JdkTests.java diff --git a/pom.xml b/pom.xml index 0a5fb790..cae54e22 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ org.slf4j slf4j-api - 1.7.32 + 1.7.36 @@ -94,17 +94,10 @@ true - - org.slf4j - slf4j-simple - 1.7.32 - true - - org.jboss jboss-vfs - 3.2.15.Final + 3.2.17.Final provided true @@ -112,7 +105,7 @@ org.junit.jupiter junit-jupiter-engine - 5.8.1 + 5.9.0 test @@ -204,7 +197,7 @@ org.apache.felix maven-bundle-plugin - 5.1.2 + 5.1.8 bundle-manifest @@ -228,7 +221,7 @@ maven-jar-plugin - 3.2.0 + 3.2.2 ${project.build.outputDirectory}/META-INF/MANIFEST.MF diff --git a/src/main/java/org/reflections/Reflections.java b/src/main/java/org/reflections/Reflections.java index 6454497f..a939c7bb 100644 --- a/src/main/java/org/reflections/Reflections.java +++ b/src/main/java/org/reflections/Reflections.java @@ -171,9 +171,7 @@ protected Map>> scan() { Set urls = configuration.getUrls(); (configuration.isParallel() ? urls.stream().parallel() : urls.stream()).forEach(url -> { - Vfs.Dir dir = null; - try { - dir = Vfs.fromURL(url); + try (Vfs.Dir dir = Vfs.fromURL(url)) { for (Vfs.File file : dir.getFiles()) { if (doFilter(file, configuration.getInputsFilter())) { ClassFile classFile = null; @@ -188,15 +186,13 @@ protected Map>> scan() { if (entries != null) collect.get(scanner.index()).addAll(entries); } } catch (Exception e) { - if (log != null) log.trace("could not scan file {} with scanner {}", file.getRelativePath(), scanner.getClass().getSimpleName(), e); + if (log != null) log.debug("could not scan file {} with scanner {}", file.getRelativePath(), scanner.getClass().getSimpleName(), e); } } } } } catch (Exception e) { if (log != null) log.warn("could not create Vfs.Dir from url. ignoring the exception and continuing", e); - } finally { - if (dir != null) dir.close(); } }); diff --git a/src/main/java/org/reflections/util/ClasspathHelper.java b/src/main/java/org/reflections/util/ClasspathHelper.java index ecbd5d79..01d348a5 100644 --- a/src/main/java/org/reflections/util/ClasspathHelper.java +++ b/src/main/java/org/reflections/util/ClasspathHelper.java @@ -110,7 +110,7 @@ public static Collection forResource(String resourceName, ClassLoader... cl final URL url = urls.nextElement(); int index = url.toExternalForm().lastIndexOf(resourceName); if (index != -1) { - // Add old url as contextUrl to support exotic url handlers + // Add old url as contextUrl to support exotic url handlers result.add(new URL(url, url.toExternalForm().substring(0, index))); } else { result.add(url); @@ -186,6 +186,7 @@ public static Collection forClassLoader(ClassLoader... classLoaders) { final ClassLoader[] loaders = classLoaders(classLoaders); for (ClassLoader classLoader : loaders) { while (classLoader != null) { + if (classLoader instanceof URLClassLoader) { URL[] urls = ((URLClassLoader) classLoader).getURLs(); if (urls != null) { diff --git a/src/main/java/org/reflections/util/ConfigurationBuilder.java b/src/main/java/org/reflections/util/ConfigurationBuilder.java index 2b455a28..7bf5f9cd 100644 --- a/src/main/java/org/reflections/util/ConfigurationBuilder.java +++ b/src/main/java/org/reflections/util/ConfigurationBuilder.java @@ -70,9 +70,11 @@ public static ConfigurationBuilder build(Object... params) { // flatten List parameters = new ArrayList<>(); for (Object param : params) { - if (param.getClass().isArray()) { for (Object p : (Object[]) param) parameters.add(p); } - else if (param instanceof Iterable) { for (Object p : (Iterable) param) parameters.add(p); } - else parameters.add(param); + if (param != null) { + if (param.getClass().isArray()) { for (Object p : (Object[]) param) parameters.add(p); } + else if (param instanceof Iterable) { for (Object p : (Iterable) param) parameters.add(p); } + else parameters.add(param); + } } ClassLoader[] loaders = Stream.of(params).filter(p -> p instanceof ClassLoader).distinct().toArray(ClassLoader[]::new); diff --git a/src/main/java/org/reflections/util/NameHelper.java b/src/main/java/org/reflections/util/NameHelper.java index ef30289e..6888de02 100644 --- a/src/main/java/org/reflections/util/NameHelper.java +++ b/src/main/java/org/reflections/util/NameHelper.java @@ -108,7 +108,7 @@ default Member forMember(String descriptor, ClassLoader... loaders) throws Refle String memberKey = p0 != -1 ? descriptor.substring(0, p0) : descriptor; String methodParameters = p0 != -1 ? descriptor.substring(p0 + 1, descriptor.lastIndexOf(')')) : ""; - int p1 = Math.max(memberKey.lastIndexOf('.'), memberKey.lastIndexOf("$")); + int p1 = memberKey.lastIndexOf('.'); String className = memberKey.substring(0, p1); String memberName = memberKey.substring(p1 + 1); diff --git a/src/main/java/org/reflections/vfs/JbossDir.java b/src/main/java/org/reflections/vfs/JbossDir.java index a777003f..43d8715e 100644 --- a/src/main/java/org/reflections/vfs/JbossDir.java +++ b/src/main/java/org/reflections/vfs/JbossDir.java @@ -1,7 +1,9 @@ package org.reflections.vfs; import org.jboss.vfs.VirtualFile; +import org.jboss.vfs.VirtualJarInputStream; +import java.lang.reflect.Field; import java.net.URL; import java.util.Iterator; import java.util.Stack; @@ -16,8 +18,14 @@ private JbossDir(VirtualFile virtualFile) { } public static Vfs.Dir createDir(URL url) throws Exception { - VirtualFile virtualFile = (VirtualFile) url.openConnection().getContent(); - if(virtualFile.isFile()) { + Object content = url.openConnection().getContent(); + if (content instanceof VirtualJarInputStream) { + Field root = content.getClass().getDeclaredField("root"); + root.setAccessible(true); + content = root.get(content); + } + VirtualFile virtualFile = (VirtualFile) content; + if (virtualFile.isFile()) { return new ZipDir(new JarFile(virtualFile.getPhysicalFile())); } return new JbossDir(virtualFile); diff --git a/src/main/java/org/reflections/vfs/Vfs.java b/src/main/java/org/reflections/vfs/Vfs.java index a153ec17..100ff99a 100644 --- a/src/main/java/org/reflections/vfs/Vfs.java +++ b/src/main/java/org/reflections/vfs/Vfs.java @@ -56,7 +56,7 @@ public abstract class Vfs { private static List defaultUrlTypes = new ArrayList<>(Arrays.asList(DefaultUrlTypes.values())); /** an abstract vfs dir */ - public interface Dir { + public interface Dir extends AutoCloseable { String getPath(); Iterable getFiles(); default void close() {} @@ -124,8 +124,8 @@ public static Dir fromURL(final URL url, final UrlType... urlTypes) { /** return an iterable of all {@link org.reflections.vfs.Vfs.File} in given urls, starting with given packagePrefix and matching nameFilter */ public static Iterable findFiles(final Collection inUrls, final String packagePrefix, final Predicate nameFilter) { Predicate fileNamePredicate = file -> { - String path = file.getRelativePath(); - if (path.startsWith(packagePrefix)) { + String path = file.toString().replace('\\','/'); + if (path.contains(packagePrefix)) { String filename = path.substring(path.indexOf(packagePrefix) + packagePrefix.length()); return !filename.isEmpty() && nameFilter.test(filename.substring(1)); } else { diff --git a/src/test/java/org/reflections/JdkTests.java b/src/test/java/org/reflections/JdkTests.java deleted file mode 100644 index 630c5361..00000000 --- a/src/test/java/org/reflections/JdkTests.java +++ /dev/null @@ -1,258 +0,0 @@ -package org.reflections; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.reflections.scanners.Scanner; -import org.reflections.scanners.Scanners; -import org.reflections.util.ClasspathHelper; -import org.reflections.util.ConfigurationBuilder; -import org.reflections.util.UtilQueryBuilder; -import org.reflections.vfs.Vfs; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URI; -import java.net.URL; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.reflections.ReflectionUtils.get; - -/** - * test reflection symmetry between jrt scanned metadata (Scanners) and java reflection accessibility (ReflectionUtils functions). - *

except for known differences per jdk version, these pairs should access similar metadata: - * SubTypes/SuperTypes, TypesAnnotated/AnnotatedTypes, MethodsAnnotated/AnnotatedTypes, Resources etc... - *

tested with AdoptOpenJDK - */ -@SuppressWarnings({"ArraysAsListWithZeroOrOneArgument"}) -public class JdkTests { - - private static Reflections reflections; - - @BeforeAll - static void init() { - if (!Vfs.getDefaultUrlTypes().get(0).getClass().equals(JrtUrlType.class)) { - Vfs.addDefaultURLTypes(new JrtUrlType()); - } - URL urls = ClasspathHelper.forClass(Object.class); - measure("before"); - - reflections = new Reflections( - new ConfigurationBuilder() - .addUrls(urls) - .setScanners(Scanners.values())); - - measure("scan"); - } - - @AfterAll - static void cleanup() { - if (Vfs.getDefaultUrlTypes().get(0).getClass().equals(JrtUrlType.class)) { - Vfs.getDefaultUrlTypes().remove(0); - } - reflections.getStore().clear(); - measure("cleanup"); - } - - @Test - public void checkSubTypes() { - Map> diff = reflect( - Scanners.SubTypes, - ReflectionUtils.SuperTypes, - Class.class); - - assertEquals(diff, Collections.emptyMap()); - } - - @Test - public void checkTypesAnnotated() { - Map> diff = reflect( - Scanners.TypesAnnotated, - ReflectionUtils.AnnotationTypes, - Class.class); - - Arrays.asList("jdk.internal.PreviewFeature", // jdk 15 - "jdk.internal.javac.PreviewFeature") // jdk 17 - .forEach(diff::remove); - assertEquals(diff, Collections.emptyMap()); - } - - @Test - public void checkMethodsAnnotated() { - Map> diff = reflect( - Scanners.MethodsAnnotated, - ReflectionUtils.AnnotationTypes, - Method.class); - - // todo fix differences @A2 such as - @A1 public @A2 result method(...) - Arrays.asList("com.sun.istack.internal.NotNull", // jdk 8 - "com.sun.istack.internal.Nullable", - "sun.reflect.CallerSensitive", - "java.lang.invoke.LambdaForm$Hidden", - "jdk.internal.reflect.CallerSensitive", // jdk 11, 13, 15 - "jdk.internal.PreviewFeature") // jdk 15 - .forEach(diff::remove); - assertEquals(diff, Collections.emptyMap()); - } - - @Test - public void checkConstructorsAnnotated() { - Map> diff = reflect( - Scanners.ConstructorsAnnotated, - ReflectionUtils.AnnotationTypes, - Constructor.class); - - assertEquals(diff, Collections.emptyMap()); - } - - @Test - public void checkFieldsAnnotated() { - Map> diff = reflect( - Scanners.FieldsAnnotated, - ReflectionUtils.AnnotationTypes, - Field.class); - - Arrays.asList("com.sun.istack.internal.NotNull", // jdk 8 - "com.sun.istack.internal.Nullable", - "jdk.internal.PreviewFeature", // jdk 15 - "jdk.internal.vm.annotation.Stable") // jdk 17 - .forEach(diff::remove); - assertEquals(diff, Collections.emptyMap()); - } - - @Test - public void checkResources() { - Set diff = new HashSet<>(); - Map> mmap = reflections.getStore().get(Scanners.Resources.index()); - mmap.values().forEach(resources -> - resources.forEach(resource -> { - Set urls = get(ReflectionUtils.Resources.get(resource)); -// if (urls == null || urls.isEmpty()) diff.add(resource); - for (URL url : urls) { - try { if (!Files.exists(JrtUrlType.getJrtRealPath(url))) diff.add(resource); } - catch (Exception e) { diff.add(resource); } - } - })); - System.out.println(Scanners.Resources.index() + ": " + mmap.values().stream().mapToInt(Set::size).sum() + ", missing: " + diff.size()); - - Arrays.asList("META-INF/MANIFEST.MF") // jdk 8 - .forEach(diff::remove); - assertEquals(diff, Collections.emptySet()); - } - - @Test - public void checkMethodsSignature() { -// Map> diffMethodSignature = -// findDiff(reflections, Scanners.MethodsSignature, ReflectionUtils.MethodSignature, Field.class); -// assertEquals(diffMethodSignature, Collections.emptyMap()); } - } - - private Map> reflect( - Scanner scanner, UtilQueryBuilder utilQueryBuilder, Class resultType) { - Map> mmap = reflections.getStore().get(scanner.index()); - Map> missing = new HashMap<>(); - mmap.forEach((key, strings) -> - strings.forEach(string -> { - //noinspection unchecked - F element = (F) reflections.forName(string, resultType); - if (element == null || !reflections.toNames(get(utilQueryBuilder.get(element))).contains(key)) { - missing.computeIfAbsent(key, k -> new HashSet<>()).add(string); - } - })); - System.out.println(scanner.index() + ": " + mmap.values().stream().mapToInt(Set::size).sum() + ", missing: " + missing.values().stream().mapToInt(Set::size).sum()); - return missing; - } - - private static void measure(String s) { - System.out.printf("-> %s %s ", s, mb(mem())); - gc(); - System.out.printf("(gc -> %s)%n", mb(mem())); - } - - private static void gc() { - for (int i = 0; i < 3; i++) { - Runtime.getRuntime().gc(); - System.runFinalization(); - try { - Thread.sleep(100); - } catch (InterruptedException e) { /*java sucks*/ } - } - } - - private static long mem() { - return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); - } - - private static String mb(long mem2) { - return (mem2 / 1024 / 1024) + "mb"; - } - - public static class JrtUrlType implements Vfs.UrlType { - @Override - public boolean matches(URL url) throws Exception { - return url.getProtocol().equals("jrt"); - } - - @Override - public Vfs.Dir createDir(URL url) throws Exception { - final Path realPath = getJrtRealPath(url); - return new Vfs.Dir() { - @Override - public String getPath() { - return url.getPath(); - } - - @Override - public Iterable getFiles() { - return () -> { - try { - return Files.walk(realPath) - .filter(Files::isRegularFile) - .map(p -> (Vfs.File) new Vfs.File() { - @Override - public String getName() { - return p.toString(); - } - - @Override - public String getRelativePath() { - return p.startsWith(realPath) ? p.toString().substring(realPath.toString().length()) : p.toString(); - } - - @Override - public InputStream openInputStream() throws IOException { - return Files.newInputStream(p); - } - }) - .iterator(); - } catch (Exception e) { - throw new ReflectionsException(e); - } - }; - } - }; - } - - /** - * jdk 11 workaround for {@code Paths.get().toRealPath()} - */ - public static Path getJrtRealPath(URL url) throws IOException { - // jdk 11 workaround - return FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules", url.getPath()) - .toRealPath(); - } - } -} diff --git a/src/test/java/org/reflections/MoreTests.java b/src/test/java/org/reflections/MoreTests.java index 733fcd47..7cccbdaa 100644 --- a/src/test/java/org/reflections/MoreTests.java +++ b/src/test/java/org/reflections/MoreTests.java @@ -10,7 +10,9 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.util.Arrays; import java.util.Collection; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -130,4 +132,27 @@ public void test_method_param_names_not_local_vars() throws NoSuchMethodExceptio "[testParam]"); } + + @Test + public void test_scan_all_classes_from_package() throws MalformedURLException { + URL url = new URL("jar:file:" + ReflectionsTest.getUserDir() + "/src/test/resources/another-project.jar!/"); + final URLClassLoader classLoader = new URLClassLoader(new URL[]{url}, Thread.currentThread().getContextClassLoader()); + Reflections reflections = new Reflections(new ConfigurationBuilder() + .setUrls(url) + .setScanners(SubTypes.filterResultsBy(c -> true)) + .addClassLoaders(classLoader)); + Set> allClass = reflections.getSubTypesOf(Object.class); + assertEquals(34, allClass.size()); + + Set classNames = allClass.stream() + .map(classType -> {return classType.getSimpleName();}) + .collect(Collectors.toSet()); + Set expectedClassNames = new LinkedHashSet<>(Arrays.asList("Meta", "A", "B", + "AM1", "TestAnnotation", "I1", "AI1", "I2", "AI2", "I3", "TestModel", "C1", + "AC1", "C2", "A1", "AC2", "C3", "A2", "AC3", "C4", "C5", "C6", "C7", + "AnotherTestModel", "Thing", "AC1n", "Usage", "ActualFunctionalityClass", + "AF1", "B1", "CyclicAnnotation", "MAI1")); + assertTrue(classNames.containsAll(expectedClassNames)); + + } } diff --git a/src/test/java/org/reflections/NameHelperTest.java b/src/test/java/org/reflections/NameHelperTest.java index 901ec04d..9b703d38 100644 --- a/src/test/java/org/reflections/NameHelperTest.java +++ b/src/test/java/org/reflections/NameHelperTest.java @@ -14,8 +14,8 @@ import java.util.Set; import java.util.function.Function; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.*; @SuppressWarnings({"unchecked"}) public class NameHelperTest implements NameHelper { @@ -63,6 +63,21 @@ public void testToForNames() throws NoSuchFieldException, NoSuchMethodException assertEquals(set(CONST, METHOD, FIELD), forNames(names, Member.class)); } + @Test + // cherry-picked from PR #290 by @ziqin + public void testMethodExt() throws NoSuchMethodException { + // synthetic method for lambda expression + Member lambda = forMember("org.reflections.UsageTestModel$C2.lambda$useLambda$0(org.reflections.UsageTestModel$C2)"); + assertEquals(lambda.getName(), "lambda$useLambda$0"); + assertEquals(lambda.getDeclaringClass(), UsageTestModel.C2.class); + assertTrue(lambda.isSynthetic()); + + // method of anonymous inner class + Member anonymous = forMember("org.reflections.UsageTestModel$C2$1.applyAsDouble(org.reflections.UsageTestModel$C2)"); + assertEquals(anonymous.getName(), "applyAsDouble"); + assertEquals(anonymous.getDeclaringClass(), forClass(UsageTestModel.C2.class.getName() + "$1")); + } + void assertToFor(T type, Function toName, Function forName) { assertEquals(forName.apply(toName.apply(type)), type); } diff --git a/src/test/java/org/reflections/ReflectionsTest.java b/src/test/java/org/reflections/ReflectionsTest.java index dbfb3dbb..52ba91e3 100644 --- a/src/test/java/org/reflections/ReflectionsTest.java +++ b/src/test/java/org/reflections/ReflectionsTest.java @@ -154,8 +154,8 @@ public void testMethodParameter() throws NoSuchMethodException { assertThat(reflections.getMethodsWithSignature(), are(C4.class.getDeclaredMethod("m1"), C4.class.getDeclaredMethod("m3"), AC2.class.getMethod("value"), AF1.class.getMethod("value"), AM1.class.getMethod("value"), - UsageTestModel.C1.class.getDeclaredMethod("method"), UsageTestModel.C2.class.getDeclaredMethod("method"))); - + UsageTestModel.C1.class.getDeclaredMethod("method"), UsageTestModel.C2.class.getDeclaredMethod("method"), + UsageTestModel.C2.class.getDeclaredMethod("zero"))); assertThat(reflections.getMethodsWithSignature(int[][].class, String[][].class), are(C4.class.getDeclaredMethod("m1", int[][].class, String[][].class))); @@ -246,6 +246,11 @@ public void testMemberUsageScanner() throws NoSuchFieldException, NoSuchMethodEx assertThat(reflections.getMemberUsage(UsageTestModel.C1.class.getDeclaredConstructor(UsageTestModel.C2.class)), are(UsageTestModel.C2.class.getDeclaredMethod("method"))); + + // synthetic method for lambda expression + assertThat(reflections.getMemberUsage(UsageTestModel.C2.class.getDeclaredMethod("zero")), + are(reflections.forMember("org.reflections.UsageTestModel$C2.lambda$useLambda$0(org.reflections.UsageTestModel$C2)"), + reflections.forMember("org.reflections.UsageTestModel$C2$1.applyAsDouble(org.reflections.UsageTestModel$C2)"))); } @Test diff --git a/src/test/java/org/reflections/UsageTestModel.java b/src/test/java/org/reflections/UsageTestModel.java index ec2d439f..b4cab83d 100644 --- a/src/test/java/org/reflections/UsageTestModel.java +++ b/src/test/java/org/reflections/UsageTestModel.java @@ -1,5 +1,8 @@ package org.reflections; +import java.util.function.ToDoubleFunction; +import java.util.stream.Stream; + public interface UsageTestModel { class C1 { C2 c2 = new C2(); @@ -17,5 +20,27 @@ public void method() { c1.method(); c1.method(""); } + + public double useAnonymousClass(C2... objects) { + return Stream.of(objects) + .mapToDouble(new ToDoubleFunction() { + @Override + public double applyAsDouble(C2 c1) { + return c1.zero(); + } + }) + .sum(); + } + public double useLambda(C2... objects) { + return Stream.of(objects) + .mapToDouble(it -> it.zero()) + .sum(); + } + public double useMethodReference(C2... objects) { + return Stream.of(objects) + .mapToDouble(C2::zero) + .sum(); + } + double zero() { return 0; } } }