Skip to content

Conversation

@mcollovati
Copy link
Collaborator

Migrates from unmaintained org.reflections library to actively maintained ClassGraph. Implements proper resource management using try-with-resources to prevent file handle leaks in large builds.

Fixes #19543

🤖 Generated with Claude Code

@github-actions
Copy link

github-actions bot commented Dec 11, 2025

Test Results

1 307 files  ±0  1 307 suites  ±0   1h 17m 2s ⏱️ + 2m 48s
9 272 tests +3  9 204 ✅ +3  68 💤 ±0  0 ❌ ±0 
9 733 runs  +6  9 657 ✅ +6  76 💤 ±0  0 ❌ ±0 

Results for commit 0c5ed92. ± Comparison against base commit 127c92c.

This pull request removes 1 and adds 4 tests. Note that renamed tests count towards both.
com.vaadin.flow.server.scanner.ReflectionsClassFinderTest ‑ reflections_notExistingDirectory_warningMessageNotLogged
com.vaadin.flow.server.scanner.ReflectionsClassFinderTest ‑ getAnnotatedClasses_findsRepeatableAnnotations
com.vaadin.flow.server.scanner.ReflectionsClassFinderTest ‑ getSubTypesOf_defaultRejectDisabled_scansAllPackages
com.vaadin.flow.server.scanner.ReflectionsClassFinderTest ‑ getSubTypesOf_rejectNotVaadinKnownPackages
com.vaadin.flow.server.scanner.ReflectionsClassFinderTest ‑ notExistingDirectory_noExceptionThrown

♻️ This comment has been updated with latest results.

@mcollovati mcollovati force-pushed the issues/19543-replace_reflections_with_classgraph branch from 434a8f1 to e04b2dc Compare December 18, 2025 07:39
@mcollovati mcollovati marked this pull request as ready for review December 18, 2025 07:39
Copy link
Member

@tltv tltv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Tested it out and it worked nice. Only I found it disappointing to see that it was actually slower when building spring-boot starter for production as seen in comparison below:

Before:
[INFO] Reflections took 816 ms to scan 122 urls, producing 5142 keys and 20763 values
[INFO] Reflections took 658 ms to scan 122 urls, producing 5142 keys and 20763 values
[INFO] Reflections took 747 ms to scan 122 urls, producing 5142 keys and 20763 values

After:
[INFO] ClassFinder initialized: 122 urls, 17398 classes scanned, 134 annotation types cached, 3944 subtype relationships cached, took 890ms
[INFO] ClassFinder initialized: 122 urls, 17398 classes scanned, 134 annotation types cached, 3944 subtype relationships cached, took 894ms
[INFO] ClassFinder initialized: 122 urls, 17398 classes scanned, 134 annotation types cached, 3944 subtype relationships cached, took 818ms

It's just a little bit slower. Not a blocker since change has other benefits.

I checked the ClassGraph API and found that it has rejectPackages mehod available. Tried it out by adding following list of packages (same as in VaadinServletContextInitializer.DEFAULT_SCAN_NEVER):

.rejectPackages(
        "antlr",
                "cglib", "ch.quos.logback", "commons-codec", "commons-fileupload",
                "commons-io", "commons-logging", "com.fasterxml", "tools.jackson",
                "com.google", "com.h2database", "com.helger",
                "com.vaadin.external.atmosphere", "com.vaadin.webjar", "junit",
                "net.bytebuddy", "org.apache", "org.aspectj", "org.bouncycastle",
                "org.dom4j", "org.easymock", "org.eclipse.persistence",
                "org.hamcrest", "org.hibernate", "org.javassist", "org.jboss",
                "org.jsoup", "org.seleniumhq", "org.slf4j", "org.atmosphere",
                "org.springframework", "org.webjars.bowergithub", "org.yaml",

                "java.*", "javax.*", "javafx.*", "com.sun.*", "oracle.deploy",
                "oracle.javafx", "oracle.jrockit", "oracle.jvm", "oracle.net",
                "oracle.nio", "oracle.tools", "oracle.util", "oracle.webservices",
                "oracle.xmlns",

                "com.intellij.*", "org.jetbrains",

                "com.vaadin.external.gwt", "javassist.*", "io.methvin",
                "com.github.javaparser", "oshi.*", "io.micrometer", "jakarta.*",
                "com.nimbusds", "elemental.util", "org.reflections",
                "org.aopalliance", "org.objectweb",

                "com.vaadin.hilla", "com.vaadin.copilot")

After this I get naturally better results. Maybe we should add these by default.

After rejectPackages:
[INFO] ClassFinder initialized: 122 urls, 3306 classes scanned, 49 annotation types cached, 697 subtype relationships cached, took 471ms
[INFO] ClassFinder initialized: 122 urls, 3306 classes scanned, 49 annotation types cached, 697 subtype relationships cached, took 411ms
[INFO] ClassFinder initialized: 122 urls, 3306 classes scanned, 49 annotation types cached, 697 subtype relationships cached, took 431ms

@mcollovati
Copy link
Collaborator Author

I noticed that initialization took a little bit longer than the previous solution, but based on my local tests, the overall build time is anyway less or comparable.
Anyway, additional package filters sound good. I'd maybe just add an option to disable them; I guess nobody would use such packages for Vaadin related components, but if the list is hard-coded, there will be no-way to workaround.
To be noted, that for filtering there's also the frontendScanner configuration for the Maven plugin.

mcollovati and others added 5 commits January 8, 2026 07:54
Migrates from unmaintained org.reflections library to actively maintained
ClassGraph. Implements proper resource management using try-with-resources
to prevent file handle leaks in large builds.

Fixes #19543

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
javassist was pinned only to avoid conflicts with project
dependencies. It's a transitive dependency of reflections
library that is now replace by classgraph, that does not
need it.
@mcollovati mcollovati force-pushed the issues/19543-replace_reflections_with_classgraph branch from e04b2dc to 0c5ed92 Compare January 8, 2026 07:55
@mcollovati
Copy link
Collaborator Author

@tltv I added the package filtering you suggested. It can be disabled using a system property.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 8, 2026

@tltv tltv merged commit b3987eb into main Jan 8, 2026
31 checks passed
@tltv tltv deleted the issues/19543-replace_reflections_with_classgraph branch January 8, 2026 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider switching from Reflections to a maintained library

3 participants