bigywater.tech
Java · 330

jdeprscan:提前发现已弃用 API

升级 JDK 之前怎么知道自己的 jar 和依赖里有多少已废弃甚至即将移除的 API?javac 的警告看不到第三方 jar,jdeprscan 可以。这篇用它扫自己的类和三个老库,并看各个 release 的废弃清单有多大。

103
JDK 21 里标记为 forRemoval 的 API 条数(JDK 8 是 10 条)
2 → 10
同一个 jar 分别用 --release 8 与 --release 21 扫描发现的条数
32 / 29 / 7
commons-lang 2.6、log4j 1.2.17、guava 18.0 里使用已废弃 API 的条数

javac 的警告

实测 · 本机执行输出
  javac 报告的警告数: 10 ;其中 removal 类警告数: 5
    行 3   [removal] Integer(int) in Integer has been deprecated and marked for removal
    行 4   [deprecation] Date(int,int,int) in Date has been deprecated
    行 5   [deprecation] getId() in Thread has been deprecated
    行 6   [removal] stop() in Thread has been deprecated and marked for removal
    行 7   [removal] runFinalization() in Runtime has been deprecated and marked for removal
    行 8   [removal] finalize() in Object has been deprecated and marked for removal
    行 9   [removal] getSecurityManager() in System has been deprecated and marked for removal
    行 10  [deprecation] URL(String) in URL has been deprecated
    行 11  [deprecation] Observable in java.util has been deprecated
    行 11  [deprecation] Observable in java.util has been deprecated

jdeprscan 扫描

实测 · 本机执行输出
  默认(全部废弃 API):
    Jar file old.jar:
    class Old uses deprecated class java/util/Observable 
    class Old uses deprecated method java/lang/Integer::<init>(I)V (forRemoval=true)
    class Old uses deprecated method java/util/Date::<init>(III)V 
    class Old uses deprecated method java/lang/Thread::getId()J 
    class Old uses deprecated method java/lang/Thread::stop()V (forRemoval=true)
    class Old uses deprecated method java/lang/Runtime::runFinalization()V (forRemoval=true)
    class Old uses deprecated method java/lang/System::getSecurityManager()Ljava/lang/SecurityManager; (forRemoval=true)
    class Old uses deprecated method java/net/URL::<init>(Ljava/lang/String;)V 
    class Old has field named ob of deprecated type java/util/Observable 
    class Old overrides deprecated method java/lang/Object::finalize()V (forRemoval=true)
  --for-removal:
    Jar file old.jar:
    class Old uses deprecated method java/lang/Integer::<init>(I)V (forRemoval=true)
    class Old uses deprecated method java/lang/Thread::stop()V (forRemoval=true)
    class Old uses deprecated method java/lang/Runtime::runFinalization()V (forRemoval=true)
    class Old uses deprecated method java/lang/System::getSecurityManager()Ljava/lang/SecurityManager; (forRemoval=true)
    class Old overrides deprecated method java/lang/Object::finalize()V (forRemoval=true)

不同 release

实测 · 本机执行输出
  --release 8  发现 2 条;前几条: ['deprecated method java/util/Date::<init>(III)V ', 'deprecated method java/lang/Thread::stop()V ']
  --release 11 发现 6 条;前几条: ['deprecated class java/util/Observable ', 'deprecated method java/lang/Integer::<init>(I)V ', 'deprecated method java/util/Date::<init>(III)V ', 'deprecated method java/lang/Thread::stop()V ']
  --release 17 发现 7 条;前几条: ['deprecated class java/util/Observable ', 'deprecated method java/lang/Integer::<init>(I)V (forRemoval=true)', 'deprecated method java/util/Date::<init>(III)V ', 'deprecated method java/lang/Thread::stop()V ']
  --release 21 发现 10 条;前几条: ['deprecated class java/util/Observable ', 'deprecated method java/lang/Integer::<init>(I)V (forRemoval=true)', 'deprecated method java/util/Date::<init>(III)V ', 'deprecated method java/lang/Thread::getId()J ']

废弃清单规模

实测 · 本机执行输出
  release 8  废弃 API 471 条,其中 for removal 10 条
  release 11 废弃 API 583 条,其中 for removal 25 条
  release 17 废弃 API 656 条,其中 for removal 76 条
  release 21 废弃 API 681 条,其中 for removal 103 条
  --list --for-removal --release 21 的前 12 条:
    @Deprecated(since="17", forRemoval=true) void java.util.logging.LogManager.checkAccess()
    @Deprecated(since="9", forRemoval=true) void javax.imageio.stream.FileCacheImageInputStream.finalize()
    @Deprecated(since="9", forRemoval=true) void javax.imageio.stream.FileImageInputStream.finalize()
    @Deprecated(since="9", forRemoval=true) void javax.imageio.stream.FileImageOutputStream.finalize()
    @Deprecated(since="9", forRemoval=true) void javax.imageio.stream.ImageInputStreamImpl.finalize()
    @Deprecated(since="9", forRemoval=true) void javax.imageio.stream.MemoryCacheImageInputStream.finalize()
    @Deprecated(since="9", forRemoval=true) class java.applet.Applet
    @Deprecated(since="9", forRemoval=true) interface java.applet.AppletContext
    @Deprecated(since="9", forRemoval=true) interface java.applet.AppletStub
    @Deprecated(since="9", forRemoval=true) interface java.applet.AudioClip
    @Deprecated(since="20", forRemoval=true) class javax.management.loading.MLet
    @Deprecated(since="20", forRemoval=true) class javax.management.loading.MLetContent

第三方旧库

实测 · 本机执行输出
  commons-lang-2.6.jar   发现 32 条使用已废弃 API(其中 for removal 28 条),耗时 3.3 秒;最多的类:[('method java/lang/Integer', 7), ('method java/lang/Long', 4), ('method java/lang/Double', 4)]
      for removal 示例:class org/apache/commons/lang/ArrayUtils uses deprecated method java/lang/Character::<init>(C)V (forRemoval=true)
      for removal 示例:class org/apache/commons/lang/ArrayUtils uses deprecated method java/lang/Long::<init>(J)V (forRemoval=true)
  log4j-1.2.17.jar       发现 29 条使用已废弃 API(其中 for removal 17 条),耗时 3.6 秒;最多的类:[('method java/lang/Integer', 6), ('method java/awt/Dialog', 6), ('method java/net/URL', 3)]
      for removal 示例:class org/apache/log4j/AppenderSkeleton overrides deprecated method java/lang/Object::finalize()V (forRemoval=true)
      for removal 示例:class org/apache/log4j/AsyncAppender$DiscardSummary uses deprecated method java/lang/Integer::<init>(I)V (forRemoval=true)
  guava-18.0.jar         发现 7 条使用已废弃 API(其中 for removal 2 条),耗时 6.6 秒;最多的类:[('method java/lang/reflect/AccessibleObject', 2), ('method java/net/URL', 1), ('class java/security/AccessController (forRemoval=true)', 1)]
      for removal 示例:class com/google/common/cache/Striped64 uses deprecated class java/security/AccessController (forRemoval=true)
      for removal 示例:class com/google/common/io/FileBackedOutputStream$1 overrides deprecated method java/lang/Object::finalize()V (forRemoval=true)

分步演示

jdeprscan
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12 的 jdeprscan(--release 8 / 11 / 17 / 21);commons-lang 2.6、log4j 1.2.17、guava 18.0 来自 Maven Central
    • 没有验证:jdeprscan 对模块化 jar、多版本 jar(META-INF/versions)的处理、--class-path 对依赖解析的影响、对反射 / 动态调用的废弃 API 的检测能力(静态扫描看不到)、JDK 27 的 jdeprscan、与 jdeps --jdk-internals 的组合
    京ICP备2026067502号-1京公网安备11010502063487号