Skip to content

Bump io.github.classgraph:classgraph in / - #636

Open
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/gradle/gradle-8f57000ec4
Open

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/gradle/gradle-8f57000ec4

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 15, 2026

Copy link
Copy Markdown
Contributor

Bumps io.github.classgraph:classgraph in / from 4.8.196 to 4.8.198.

Updates io.github.classgraph:classgraph from 4.8.196 to 4.8.198

Release notes

Sourced from io.github.classgraph:classgraph's releases.

ClassGraph 4.8.198

ClassGraph 5.0.0 is coming shortly, and requires JDK 17 or newer. 4.8.198 is a bugfix release on the 4.x maintenance branch. As before, most of the bugs listed here were found by Claude through careful code analysis, and were fixed on the v5 branch and backported to v4.

Behavior changes

  • The worker timeout now stops a scan that has stopped making progress, instead of letting it hang. In 4.8.197 the timeout was applied only once every work unit had finished or one had failed, so a worker stuck on a hung network mount, or a thread waiting for another thread to open the same classpath element or jarfile, hung the scan forever. The timeout set by setWorkerTimeout() (1 minute by default) now counts from the last progress: a work unit finishing, bytes downloaded from a URL or inflated from a nested jar, bytes written to a temporary file, or an entry listed in a directory. So a slow download that keeps delivering bytes does not time out. When the timeout runs out the scan fails with ClassGraphException; reading a local jarfile or classfile does not count as progress, so a read that blocks for longer than the timeout also fails the scan. The wait is made in slices of a tenth of the timeout or 1 second, whichever is shorter, and a pause of the whole JVM, such as SIGSTOP or a debugger breakpoint that suspends all threads, counts as at most one slice. A breakpoint that suspends only one worker thread is not such a pause: set a longer timeout, or 0, while debugging a scan.

  • A scan that fails no longer leaves the calling thread interrupted. In 4.8.197 a failure such as a worker timeout set the interrupt status of the thread that called scan(), so the next blocking call on that thread threw InterruptedException, a retry of the scan failed with "Scan interrupted", and a FailureHandler ran with its thread interrupted. The thread is now interrupted only when the scan itself was interrupted.

  • An interrupted thread no longer breaks a jarfile for every other thread. Unless enableMemoryMapping() is set, all reads of a jarfile share one FileChannel, and the JDK closes the channel when an interrupted thread reads from it, so in 4.8.197 every later read of that jarfile failed with ClosedChannelException until the ScanResult was closed. Now an interrupted thread gets an InterruptedIOException before it reads, and a channel closed this way is reopened for the other threads.

  • On Tomcat, the classpath now holds only what the webapp classloader loads from. The webapp classloader loads a class or resource x from the webapp resource /WEB-INF/classes/x, but 4.8.197 also reported the webapp root, its static content, index.jsp, WEB-INF/web.xml, the resource jars, and the whole of a packed WAR file. Now a resource set mounted at /WEB-INF/classes (such as the jars in WEB-INF/lib) is on the classpath as a whole, the webapp directory or WAR file only from its WEB-INF/classes directory, and a static-only or other resource set not at all.

  • A classloader handler that throws is now logged and skipped, instead of failing the scan. ClassGraph reads the internals of container classloaders by reflection, and in 4.8.197 a RuntimeException or LinkageError from any handler failed the scan with "Uncaught exception during scan" (#651, #891). The classpath entries found by the other handlers are now kept. The Tomcat handler also reads the delegation order through getDelegate() when a subclass hides Catalina's delegate field, which caused a ClassCastException before.

  • Running out of memory or stack while opening a jarfile now stops the scan. In 4.8.197 an OutOfMemoryError or StackOverflowError thrown while opening a jarfile, for example while inflating a nested jar into memory, only skipped that jarfile, so the scan returned normally with its classes missing and only the verbose log said why. These errors now fail the scan.

  • When scanning is extended to an external superclass, interface or annotation, ClassGraph now reads the copy of its classfile that the JVM would load. 4.8.197 looked first in the classpath element of the class that referred to it, so an application jar holding its own copy of a class that is earlier on the classpath gave that copy's superclass and interfaces, and with two such copies the result could change from run to run. The classfile is now looked up strictly in classpath order. During a scan, each directory classpath element remembers which package directories it does not have, so a long list of directories before the jar that holds the external classes does not slow the scan down; the memory is released once the classfiles have been scanned.

  • An annotation array value whose type has changed is now kept as Object[], instead of throwing. When an annotation class was recompiled after the class that uses it, with an element changed between an array type and another type, 4.8.197 threw IllegalArgumentException or NullPointerException when any element of that annotation was read, or returned an array of nulls, and a changed @Repeatable container made the whole scan fail. Now only the changed element is affected: it is returned as the Object[] array read from the classfile, and reading it from an annotation proxy throws ClassCastException.

  • A repeated annotation on a private field, a private method or a parameter of a private method no longer makes getClassesWithFieldAnnotation(), getClassesWithMethodAnnotation() or getClassesWithMethodParameterAnnotation() return the subclasses of its class. A private member is not inherited, and these methods already left out the subclasses for an annotation that is not repeated.

  • A method type signature that does not parse is now treated as absent. In 4.8.197 MethodInfo#getParameterInfo() and MethodInfo#toString() threw IllegalArgumentException for such a method, which made a scan with enableInterClassDependencies() fail, TypeSignature#resolveTypeVariables threw too, and getTypeDescriptor() threw on the first call for a method with type annotations. These methods now use the type descriptor instead. getTypeSignature() still throws IllegalArgumentException for a signature that does not parse.

  • A classfile is now scanned as a class only when its path is a class name the JVM accepts. In 4.8.197 a stray file x.Y.class was also taken to be class x.Y, so with x/Y.class present as well the whole scan failed with "Class x.Y should not have been scheduled more than once". A classfile whose path below its package root has an empty segment, or a segment containing ., ; or [, is now listed only as a resource. A package such as my-pkg, which is not a Java identifier but which the JVM loads, is still scanned.

  • A classfile that names its superclass, an interface, or an inner, outer or enclosing class illegally is now skipped, instead of failing the scan. In 4.8.197 a name such as p/S;, or an array class whose element name contains <, failed the whole scan with "Uncaught exception during scan", and a name such as p//S created a class that no JVM can load. Such a classfile, which the JVM refuses to load, is now logged and skipped, while an array class named only as an inner class or as an EnclosingMethod class, which the JVM accepts, is ignored and the class is kept.

  • An illegal class name that a classfile refers to only as a dependency no longer costs the class. With enableInterClassDependencies(), 4.8.197 failed the scan for a constant pool class name such as Q;, and it skipped the whole class for an array class such as [Lp/A<x>;, which the JVM accepts. The class is now kept: the illegal name is logged and left out of the dependencies, and an array class adds its element class.

  • An annotation whose type name is illegal or missing is now skipped, and the class that carries it is kept. In 4.8.197 such an annotation could fail the whole scan, create a class whose name is empty, or give an AnnotationInfo whose name is null. The JVM does not check annotation type names and loads such a class, so ClassGraph now leaves out only that annotation, and any annotation whose element values hold one.

  • Limits on nesting now keep a crafted classfile from overflowing the stack. In 4.8.197 a classfile with type arguments nested thousands deep, annotation values nested thousands deep, or an array type with thousands of dimensions made the scan fail with StackOverflowError. A type signature whose type arguments nest more than 100 deep is now treated as a signature that does not parse, a classfile whose annotation values nest more than 255 deep is skipped, and an array type with more than 255 dimensions, which the JVM never allows, is rejected in the same ways.

  • A classfile longer than 64 MB is now skipped. 4.8.197 buffered a classfile up to the length it declared for each attribute to skip, up to 2 GB, so a jar of about 1 MB could make a scan allocate about 800 MB, and a larger one could fail the scan with OutOfMemoryError. Reading past 64 MB now throws an IOException, and the classfile is logged and skipped; the largest of 1.28 million classfiles in a large Maven repository is 1.1 MB.

  • The jarfiles nested in a jarfile may now inflate to at most 100 times the size of that jarfile, or 256 MB, whichever is larger, in all. 4.8.197 had no limit, so a jar of under 100 KB could make a scan inflate a nested jar of any size into memory or into a temporary file. A nested jar that would go past the limit is skipped, as any jar that cannot be opened is. Real nested jars inflate to between 1 and 3 times their compressed size.

  • Temporary files are now readable only by their owner. ClassGraph writes a nested jar too large to buffer in memory, or a jar downloaded from a URL, to a temporary file. In 4.8.197 that file got the default permissions, which usually let every local user read it in a shared /tmp (the same flaw as CVE-2020-15250); it is now mode 0600 on POSIX systems, and on Windows it takes the access control list of the temporary directory, as before.

  • A temporary directory that cannot be used no longer breaks temporary files for the rest of the JVM. The JDK sets up its temporary directory once, the first time a temporary file is created in the JVM, and if that fails, every later attempt in the JVM fails with NoClassDefFoundError. In 4.8.197, when the application had cleared java.io.tmpdir, ClassGraph's temporary file for a nested jar could be that first attempt, which broke File.createTempFile for the application too, on JDK 8 and on JDK 17. On JDK 8 to 15, where the JDK reads the property as it is at that moment, ClassGraph now checks the property first, and throws an IOException without touching the JDK's setup when it is unset or names a directory that cannot be represented in the encoding used for filenames (such as a non-ASCII name under the C locale on Linux). From JDK 16 the JDK uses the value it read at startup, and ClassGraph leaves the choice to the JDK. Any ExceptionInInitializerError or NoClassDefFoundError from the JDK's setup is reported as an IOException. In every case ClassGraph skips only the jarfile it was writing, as before. One case is stricter than before, on JDK 8 to 15 only: if the property is cleared after the JDK has already created a temporary file, the JDK could still create one, but ClassGraph now gives an IOException.

Bug fixes: annotations

  • Reading the values of the same annotation from two threads at once no longer throws NullPointerException or stores a partly filled array. An array value is converted to its element type when it is first read, and two threads could do this at the same time, so a value such as [1, 2, 3] could be left as [1, 0, 0] for good. The conversion is now done once, under a lock.

  • Hashing or comparing an AnnotationInfo while another thread first reads its values no longer gives a wrong hash code or NullPointerException. hashCode(), equals() and compareTo() now convert the values before they read them. A wrong hash code left an annotation in the wrong bucket of a HashSet for good.

Bug fixes: paths in jarfiles

... (truncated)

Commits
  • 4dd6f73 [maven-release-plugin] prepare release classgraph-4.8.198
  • 0a85055 Make two tests pass on Windows and macOS, and tighten two others
  • 80e68eb Say which breakpoints pause the whole JVM
  • 44260d2 Test that scanning a directory reports progress for each entry
  • 0f2a185 Report progress for a byte read on its own while reading a jarfile
  • 907fa69 Say what skipping the java.io.tmpdir check can break
  • 496bfb2 Test the worker timeout's untested paths, and fix what it says of pauses
  • 0e0eba7 Rewrap the comments that 3e0d65dbd left too long
  • 3e0d65d Say which JDK calls read java.io.tmpdir before JDK 16
  • 8e14607 Forget the package directories a scan looked up once it is done
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore <dependency name> major version will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
  • @dependabot ignore <dependency name> minor version will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
  • @dependabot ignore <dependency name> will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
  • @dependabot unignore <dependency name> will remove all of the ignore conditions of the specified dependency
  • @dependabot unignore <dependency name> <ignore condition> will remove the ignore condition of the specified dependency and ignore conditions

Bumps [io.github.classgraph:classgraph](https://github.com/classgraph/classgraph) in `/` from 4.8.196 to 4.8.198.


Updates `io.github.classgraph:classgraph` from 4.8.196 to 4.8.198
- [Release notes](https://github.com/classgraph/classgraph/releases)
- [Commits](classgraph/classgraph@classgraph-4.8.196...classgraph-4.8.198)

---
updated-dependencies:
- dependency-name: io.github.classgraph:classgraph
  dependency-version: 4.8.198
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gradle
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot
dependabot Bot requested a review from a team as a code owner October 15, 2026 08:13
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file java Pull requests that update Java code labels Oct 15, 2026
@sonarqubecloud

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file java Pull requests that update Java code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants