Apache Tentacles 常用 CLI 命令与工具详解

逐一实测 Apache Tentacles 0.1 全部 CLI 用法(远程与本地 URI、输出目录、-Dfilter、-ea、退出码)与联动工具 Apache Rat 0.18 的核心命令,含 Rat --help 全量转录与异常行为实录。

Apache TentaclesApache TentaclesUbuntuUbuntu 22.04命令行LinuxApache2026/10/16

Apache Tentacles 常用 CLI 命令与工具详解

目标:把 Apache Tentacles 0.1 的全部命令行用法(两个位置参数、一个系统属性、一个 JVM 开关、退出码语义)逐项实测成册,并完整转录联动工具 Apache Rat 0.18 的 --help 输出、逐项实测其核心选项,作为发布合规审计流水线的命令速查手册。全部命令已在 Ubuntu 22.04.5 LTS + OpenJDK 17 环境实测通过。

一、环境信息

本文所有命令与回显均实测采集,演示统一在 /root 目录下进行:

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • Java 运行时:OpenJDK 17.0.20.1(openjdk-17-jre-headless)
  • 主工具:Apache Tentacles 0.1(apache-tentacles-0.1-jar-with-dependencies.jar)
  • 联动工具:Apache Rat 0.18(apache-rat-0.18.jar)
  • 安装目录:/root/tentacles(两个 jar 所在),演示输出目录:/root/tentacles-demo;官方站点 https://creadur.apache.org/tentacles/ 与 https://creadur.apache.org/rat/

二、工具概览

2.1 工具构成

发布合规审计流水线涉及两个同属 Apache Creadur 的单 jar 命令行工具,均无独立服务进程,按需以 java -jar 运行:

工具jar职责CLI 形态
Apache Tentacles 0.1apache-tentacles-0.1-jar-with-dependencies.jar批量下载远程仓库发行件、递归解包、生成 LICENSE/NOTICE 汇总报告无选项体系:2 个位置参数 + 1 个系统属性 + 1 个 JVM 开关
Apache Rat 0.18apache-rat-0.18.jar对本地目录/归档逐文件识别许可证头,输出审计报告传统选项体系:--help 可见 40 余个选项

2.2 命令语法总览

Tentacles 全部语法一式一条(每一项的实测见第四章):

语法要素必填作用
java -ea [-Dfilter=<正则>] -jar apache-tentacles-0.1-jar-with-dependencies.jar <URI> [输出目录名]-完整调用形态
第 1 参数 URI(https://…、http://…、file:/…)是远程仓库地址(递归爬取下载)或本地目录(复制取样)
第 2 参数 输出目录名否输出根目录名;缺省取 URI 路径末段
-Dfilter=<正则>否(file: 模式实际必改)仅本地模式生效:按绝对路径正则全匹配筛选归档,默认 org/apache/openejb
-ea否启用 Java 断言,官方 README 要求携带;退出码恒为 0,成败看日志与产出

💡 技术拓展:-ea 是 JVM 的断言启用开关(enable assertions),与 Tentacles 的参数解析无关。带断言运行的程序在内部状态异常时抛 AssertionError 便于暴露问题;实测不带 -ea 时 Tentacles 主流程同样正常(见 4.6 节),官方要求携带属于运行约定而非硬性依赖。

三、前置条件

两件准备工作:JDK 就位、两个发行件就位。安装与校验的完整流程见《Apache Tentacles 在 Ubuntu 22.04 集成使用指南》第三章,此处仅验证就位状态。

apt-get install -y openjdk-17-jre-headless && java -version

实测输出(节选):

openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)

发行件就位状态(ls -la /root/tentacles/ 实测):apache-tentacles-0.1-jar-with-dependencies.jar(9715403 字节)与 apache-rat-0.18/(含 apache-rat-0.18.jar)均已就位,且 Tentacles jar 的 sha512 校验结果与官方 .sha512 文件一致(ae6e8d8d9e55517c0d2efc8bb5a63ad1514013d57f2d90552025321cfa246bc351b5a2a72a92882e4efca324f39391b01df2caa9aaf395f1c2099031c868d301)。

四、Apache Tentacles 0.1 命令详解

4.1 无参启动:唯一的帮助形态

Tentacles 没有 --help、--version 选项(0.1 CLI 未实现选项体系),漏传参数时输出的引导提示就是它的「帮助」:

cd /root/tentacles && java -ea -jar apache-tentacles-0.1-jar-with-dependencies.jar

实测输出:

0 [main] INFO org.apache.creadur.tentacles.Main  - Launching Apache Tentacles ...
0 [main] ERROR org.apache.creadur.tentacles.Main  - Error: Input parameter missing - you did not specify any component to run Apache Tentacles on.
0 [main] ERROR org.apache.creadur.tentacles.Main  - Please launch Apache Tentacles with an URI to work on such as 'https://repository.apache.org/content/repositories/orgapachecreadur-1000/'.

要点:即便以 ERROR 提示退出,进程退出码仍为 0(4.8 节汇总)。提示中的示例 URI 指向一个 Apache staging 仓库地址。

4.2 第 1 参数:远程 HTTP 仓库 URI

核心用法。Tentacles 从给定 URL 开始递归爬取目录树,下载全部匹配 .*\.(jar|zip|war|ear|rar|tar.gz) 的文件,逐个递归解包并生成报告。以 Apache releases 仓库的 tentacles 目录为目标(5 个发行件,适合演练):

mkdir -p /root/tentacles-demo && cd /root/tentacles-demo && java -ea -jar /root/tentacles/apache-tentacles-0.1-jar-with-dependencies.jar https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/

实测输出(全程日志):

0 [main] INFO org.apache.creadur.tentacles.Main  - Launching Apache Tentacles ...
36 [main] INFO org.apache.creadur.tentacles.Main  - Remote repository: https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/
36 [main] INFO org.apache.creadur.tentacles.Main  - Local root directory: tentacles
129 [main] INFO org.apache.creadur.tentacles.NexusClient  - Crawl https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/
1372 [main] INFO org.apache.creadur.tentacles.NexusClient  - Crawl https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/apache-tentacles/
1661 [main] INFO org.apache.creadur.tentacles.NexusClient  - Crawl https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/apache-tentacles/0.1/
1980 [main] INFO org.apache.creadur.tentacles.NexusClient  - Download https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/apache-tentacles/0.1/apache-tentacles-0.1-jar-with-dependencies.jar
4518 [main] INFO org.apache.creadur.tentacles.NexusClient  - Download https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/apache-tentacles/0.1/apache-tentacles-0.1-javadoc.jar
4799 [main] INFO org.apache.creadur.tentacles.NexusClient  - Download https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/apache-tentacles/0.1/apache-tentacles-0.1-source-release.zip
5080 [main] INFO org.apache.creadur.tentacles.NexusClient  - Download https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/apache-tentacles/0.1/apache-tentacles-0.1-sources.jar
5360 [main] INFO org.apache.creadur.tentacles.NexusClient  - Download https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/apache-tentacles/0.1/apache-tentacles-0.1.jar
5642 [main] INFO org.apache.creadur.tentacles.Main  - Unpack tentacles/repo/apache-tentacles/0.1/apache-tentacles-0.1-sources.jar
5646 [main] INFO org.apache.creadur.tentacles.Main  - Unpack tentacles/repo/apache-tentacles/0.1/apache-tentacles-0.1-jar-with-dependencies.jar
6441 [main] ERROR org.apache.creadur.tentacles.Main  - Not a zip tentacles/repo/apache-tentacles/0.1/apache-tentacles-0.1-jar-with-dependencies.jar
6442 [main] INFO org.apache.creadur.tentacles.Main  - Unpack tentacles/repo/apache-tentacles/0.1/apache-tentacles-0.1.jar
6445 [main] INFO org.apache.creadur.tentacles.Main  - Unpack tentacles/repo/apache-tentacles/0.1/apache-tentacles-0.1-source-release.zip
6449 [main] INFO org.apache.creadur.tentacles.Main  - Unpack tentacles/repo/apache-tentacles/0.1/apache-tentacles-0.1-javadoc.jar

日志三类动作:Crawl 为目录爬取(本例三层)、Download 为发行件下载(本例 5 个:4 个 jar 与 1 个 zip)、Unpack 为递归解包。

⚠️ 注意:日志中的 ERROR Not a zip 是递归解包阶段对个别非标准 zip 嵌套条目的跳过提示,不中断流程(后续 Unpack 继续执行、报告齐全、退出码 0)。看到该行应人工抽查对应归档内是否遗漏 LICENSE/NOTICE。

4.3 第 1 参数:本地 file: 目录 URI

把本地目录当仓库离线取样,全程不访问网络。准备演示目录并正确运行(-Dfilter 的必要性见 4.5 节):

mkdir -p /root/local-repo/org/apache/creadur
cp /root/tentacles/apache-tentacles-0.1-source-release.zip /root/local-repo/org/apache/creadur/
cd /root/local-repo && java -ea -Dfilter='.*' -jar /root/tentacles/apache-tentacles-0.1-jar-with-dependencies.jar file:/root/local-repo/ out-b

实测输出:

0 [main] INFO org.apache.creadur.tentacles.Main  - Launching Apache Tentacles ...
39 [main] INFO org.apache.creadur.tentacles.Main  - Remote repository: file:/root/local-repo/
40 [main] INFO org.apache.creadur.tentacles.Main  - Local root directory: out-b
43 [main] INFO org.apache.creadur.tentacles.Main  - Copy file:/root/local-repo/org/apache/creadur/apache-tentacles-0.1-source-release.zip
43 [main] INFO org.apache.creadur.tentacles.Main  - Unpack out-b/repo/org/apache/creadur/apache-tentacles-0.1-source-release.zip

本地模式的动作是 Copy(而非 Download),其余流程(解包、报告)与远程模式一致,解包产物同样落在 out-b/content/ 下的 .contents/ 目录。

4.4 第 2 参数:本地输出目录名

省略第 2 参数时输出根目录名取 URI 路径末段(4.2 节实测为 tentacles/);显式传入时按传入值创建,相对与绝对路径均实测生效(如传 /root/x5 时日志为 Local root directory: /root/x5,退出码 0,目录内含 archives.html、content/、licenses.html、notices.html、repo/、style.css,与 4.7 节清单一致)。

4.5 -Dfilter 系统属性:本地模式的路径过滤器

该属性仅对 file: 本地模式生效,默认值 org/apache/openejb(源自 Tentacles 在 OpenEJB 中的出身),匹配规则是对归档文件绝对路径做正则全匹配(源码 IsArchiveInPathFilter.accept 中为 path.matches(pathNameFilter))。两个实测结论:

结论一:不覆盖默认值必然空跑。

cd /root/local-repo && rm -rf out-a && java -ea -jar /root/tentacles/apache-tentacles-0.1-jar-with-dependencies.jar file:/root/local-repo/ out-a

实测输出(仅 3 行启动信息,无 Copy/Unpack 动作;out-a/repo/ 为空目录且退出码 0):

0 [main] INFO org.apache.creadur.tentacles.Main  - Launching Apache Tentacles ...
38 [main] INFO org.apache.creadur.tentacles.Main  - Remote repository: file:/root/local-repo/
38 [main] INFO org.apache.creadur.tentacles.Main  - Local root directory: out-a

**结论二:子串写法不命中。**全匹配意味着 -Dfilter=creadur 不命中任何路径,必须写 .*creadur.* 或 .* 等正则完整形态:

cd /root/local-repo && java -ea -Dfilter='.*' -jar /root/tentacles/apache-tentacles-0.1-jar-with-dependencies.jar file:/root/local-repo/ out-b

实测输出(.* 覆盖后正常 Copy):

43 [main] INFO org.apache.creadur.tentacles.Main  - Copy file:/root/local-repo/org/apache/creadur/apache-tentacles-0.1-source-release.zip

远程 HTTP 模式不受该属性影响(远程爬取按后缀过滤,写死在源码 Main.CRAWL_PATTERN,值为 .*\.(jar|zip|war|ear|rar|tar.gz))。

4.6 -ea 开关:带与不带的实测对比

官方 README 要求 java -ea -jar 运行(断言必须启用)。实测不带 -ea 的完整下载解包流程:

cd /root && java -jar /root/tentacles/apache-tentacles-0.1-jar-with-dependencies.jar https://repository.apache.org/content/repositories/releases/org/apache/creadur/tentacles/ /root/noea-out > /tmp/noea.log 2>&1; echo "exit=$?"; grep -cE 'Download' /tmp/noea.log

实测输出(下载计数为 5,流程完整):

exit=0
5

4.7 输出物清单

一次成功运行后,输出根目录内固定生成以下内容(以 4.2 节为例):

产物说明
repo/原样归档的发行件,按仓库相对路径存放
content/<归档名>.contents/每个归档的递归解包内容,嵌套归档继续下钻 .contents
archives.html主报告:全部顶层归档及其 LICENSE/NOTICE 声明清单
<归档名>.licenses.html / <归档名>.notices.html每个归档的法定文件详情页(Declared/Undeclared 分段)
licenses.html / notices.html全部许可/声明文本的汇总页
style.css报告样式

4.8 退出码与异常输入行为

Tentacles 所有实测场景退出码均为 0,成败只能通过日志与产出判断。逐场景实测(均无管道直采 $?):

场景命令要点实测退出码行为
无参数java -ea -jar …jar0输出 2 行 ERROR 引导后退出
正常远程下载第 1 参数 https URI0下载、解包、出报告
不支持协议第 1 参数 s3://example/repo0静默生成空报告骨架
非法 URI第 1 参数 foo0静默生成空报告骨架
本地默认过滤器file: 模式不带 -Dfilter0不复制任何文件,只生成空骨架
本地正常取样file: 模式带 -Dfilter='.*'0Copy、解包、出报告

以不支持协议场景为例,实测回显中无任何 ERROR 提示、只有 3 行启动信息(Launching、Remote repository: s3://example/repo、Local root directory: out-e2),随后静默生成空报告骨架退出;非法 URI foo 的行为与之完全一致。

五、Apache Rat 0.18 命令详解(联动工具)

Tentacles 摊开发行件,Rat 逐文件判定许可头,两者组合成完整流水线。本章先全量转录 Rat 的 --help(命令全集骨架),再逐项实测核心选项。

5.1 --help 全量转录(命令全集)

java -jar /root/tentacles/apache-rat-0.18/apache-rat-0.18.jar --help

实测输出(全文转录,按终端宽度换行原样保留):

INFO: Apache Creadur RAT 0.18 (Apache Software Foundation)
usage: java -jar apache-rat/target/apache-rat-0.18.jar [options] [DIR|ARCHIVE]

====== Available Options ======
 -?,--help                                            Print help for the RAT command line interface and exit.
 -a                                                   [Deprecated for removal since 0.17: Use --edit-license instead.]
 -A,--addLicense                                      [Deprecated for removal since 0.17: Use --edit-license instead.]
                                                      Add the Apache-2.0 license header to any file with an unknown
                                                      license that is not in the exclusion list.
 -c,--copyright <arg>                                 [Deprecated for removal since 0.17: Use --edit-copyright instead.]
                                                      The copyright message to use in the license headers.
    --config <File>                                   File names for system configuration. Multiple values may be
                                                      specified. Note that '--' or a following option is required when
                                                      using this parameter.
    --configuration-no-defaults                       Ignore default configuration.
    --counter-max <CounterPattern>                    The acceptable maximum number for the specified counter. A value
                                                      of '-1' specifies an unlimited number. Multiple values may be
                                                      specified. Note that '--' or a following option is required when
                                                      using this parameter.
    --counter-min <CounterPattern>                    The minimum number for the specified counter. Multiple values may
                                                      be specified. Note that '--' or a following option is required
                                                      when using this parameter.
 -d,--dir <DirOrArchive>                              [Deprecated for removal since 0.17: Use the standard '--' to
                                                      signal the end of arguments.] Used to indicate end of list when
                                                      using options that take multiple arguments.
    --dry-run                                         If set do not update the files but generate the reports.
 -e,--exclude <Expression>                            [Deprecated for removal since 0.17: Use --input-exclude instead.]
                                                      Excludes files matching <Expression>. Multiple values may be
                                                      specified. Note that '--' or a following option is required when
                                                      using this parameter.
 -E,--exclude-file <File>                             [Deprecated for removal since 0.17: Use --input-exclude-file
                                                      instead.] Reads <Expression> entries from a file. Entries will be
                                                      excluded from processing.
    --edit-copyright <arg>                            The copyright message to use in the license headers. Usually in
                                                      the form of "Copyright 2008 Foo".  Only valid with --edit-license
    --edit-license                                    Add the Apache-2.0 license header to any file with an unknown
                                                      license that is not in the exclusion list. By default new files
                                                      will be created with the license header, to force the modification
                                                      of existing files use the --edit-overwrite option.
    --edit-overwrite                                  Forces any changes in files to be written directly to the source
                                                      files so that new files are not created. Only valid with
                                                      --edit-license.
 -f,--force                                           [Deprecated for removal since 0.17: Use --edit-overwrite instead.]
                                                      Forces any changes in files to be written directly to the source
                                                      files so that new files are not created.
    --help-licenses                                   Print information about registered licenses.
    --include <Expression>                            [Deprecated for removal since 0.17: Use --input-include instead.]
                                                      Includes files matching <Expression>. Will override excluded
                                                      files. Multiple values may be specified. Note that '--' or a
                                                      following option is required when using this parameter.
    --includes-file <File>                            [Deprecated for removal since 0.17: Use --input-include-file
                                                      instead.] Reads <Expression> entries from a file. Entries will be
                                                      excluded from processing.
    --input-exclude <Expression>                      Excludes files matching <Expression>. Multiple values may be
                                                      specified. Note that '--' or a following option is required when
                                                      using this parameter.
    --input-exclude-file <File>                       Reads <Expression> entries from a file. Entries will be excluded
                                                      from processing.
    --input-exclude-parsed-scm <StandardCollection>   Parse SCM based exclusion files to exclude specified files and
                                                      directories. This action can apply to any standard collection that
                                                      implements a file processor. Multiple values may be specified.
                                                      Note that '--' or a following option is required when using this
                                                      parameter.
    --input-exclude-size <Integer>                    Excludes files with sizes less than the number of bytes specified.
    --input-exclude-std <StandardCollection>          Excludes files defined in standard collections based on commonly
                                                      occurring groups. Excludes any path matcher actions but DOES NOT
                                                      exclude any file processor actions. Multiple values may be
                                                      specified. Note that '--' or a following option is required when
                                                      using this parameter.
    --input-include <Expression>                      Includes files matching <Expression>. Will override excluded
                                                      files. Multiple values may be specified. Note that '--' or a
                                                      following option is required when using this parameter.
    --input-include-file <File>                       Reads <Expression> entries from a file. Entries will override
                                                      excluded files.
    --input-include-std <StandardCollection>          Includes files defined in standard collections based on commonly
                                                      occurring groups. Includes any path matcher actions but DOES NOT
                                                      include any file processor actions. Multiple values may be
                                                      specified. Note that '--' or a following option is required when
                                                      using this parameter.
    --input-source <File>                             A file containing file names to process. File names must use linux
                                                      directory separator ('/') or none at all. File names that do not
                                                      start with '/' are relative to the directory where the argument is
                                                      located. Multiple values may be specified. Note that '--' or a
                                                      following option is required when using this parameter.
    --license-families-approved <FamilyID>            A comma separated list of approved license family IDs. These
                                                      license families will be added to the list of approved license
                                                      families.
    --license-families-approved-file <File>           Name of file containing comma separated lists of approved family
                                                      IDs.
    --license-families-denied <FamilyID>              A comma separated list of denied License family IDs. These license
                                                      families will be removed from the list of approved licenses. Once
                                                      license families are removed they can not be added back.
    --license-families-denied-file <File>             Name of file containing comma separated lists of denied license
                                                      IDs. These license families will be removed from the list of
                                                      approved licenses. Once license families are removed they can not
                                                      be added back.
    --licenses <File>                                 [Deprecated for removal since 0.17: Use --config instead.] File
                                                      names for system configuration. Multiple values may be specified.
                                                      Note that '--' or a following option is required when using this
                                                      parameter.
    --licenses-approved <LicenseID>                   A comma separated list of approved License IDs. These licenses
                                                      will be added to the list of approved licenses.
    --licenses-approved-file <File>                   Name of file containing comma separated lists of approved License
                                                      IDs.
    --licenses-denied <LicenseID>                     A comma separated list of denied License IDs. These licenses will
                                                      be removed from the list of approved licenses. Once licenses are
                                                      removed they can not be added back.
    --licenses-denied-file <File>                     Name of file containing comma separated lists of the denied
                                                      license IDs. These licenses will be removed from the list of
                                                      approved licenses. Once licenses are removed they can not be added
                                                      back.
    --list-families <LicenseFilter>                   [Deprecated for removal since 0.17: Use --output-families
                                                      instead.] List the defined license families. (Default value =
                                                      NONE)
    --list-licenses <LicenseFilter>                   [Deprecated for removal since 0.17: Use --output-licenses
                                                      instead.] List the defined licenses. (Default value = NONE)
    --log-level <LogLevel>                            Sets the log level. (Default value = WARN)
    --no-default-licenses                             [Deprecated for removal since 0.17: Use
                                                      --configuration-no-defaults instead.] Ignore default
                                                      configuration.
 -o,--out <File>                                      [Deprecated for removal since 0.17: Use --output-file instead.]
                                                      Define the output file where to write a report to. (Default value
                                                      = System.out)
    --output-archive <ProcessingType>                 Specifies the level of detail in ARCHIVE file reporting. (Default
                                                      value = NOTIFICATION)
    --output-families <LicenseFilter>                 List the defined license families. (Default value = NONE)
    --output-file <File>                              Define the output file where to write a report to. (Default value
                                                      = System.out)
    --output-licenses <LicenseFilter>                 List the defined licenses. (Default value = NONE)
    --output-standard <ProcessingType>                Specifies the level of detail in STANDARD file reporting. (Default
                                                      value = ABSENCE)
    --output-style <StyleSheet>                       XSLT stylesheet to use when creating the report. Either an
                                                      external xsl file may be specified or one of the internal named
                                                      sheets.
 -s,--stylesheet <StyleSheet>                         [Deprecated for removal since 0.17: Use --output-style instead.]
                                                      XSLT stylesheet to use when creating the report.
    --scan-hidden-directories                         [Deprecated for removal since 0.17: Use --input-include-std with
                                                      'HIDDEN_DIR' argument instead.] Scans hidden directories.
 -x,--xml                                             [Deprecated for removal since 0.17: Use --output-style with the
                                                      'xml' argument instead.] forces XML output rather than the textual
                                                      report.

====== Argument Types ======

<File>
     A file name.

<Integer>
     An integer value.

<DirOrArchive>
     A directory or archive file to scan.

<Expression>
     A file matching pattern usually of the form used in Ant build files and '.gitignore' files (see
         https://ant.apache.org/manual/dirtasks.html#patterns for examples). Regular expression patterns may be
         specified by surrounding the pattern with '%regex[' and ']'. For example '%regex[[A-Z].*]' would match files
         and directories that start with uppercase latin letters.

<LicenseFilter>
     A defined filter for the licenses to include. Valid values: ALL, APPROVED, NONE.

<LogLevel>
     The log level to use. Valid values DEBUG, INFO, WARN, ERROR, OFF.

<ProcessingType>
     Specifies how to process file types. Valid values are:
         NOTIFICATION: List file as present

         PRESENCE: List any licenses found

         ABSENCE: List licenses found and any unknown licences

<StyleSheet>
     Either an external xsl file or one of the internal named sheets. Internal sheets are:

         plain-rat: The default style.


         missing-headers: Produces a report of files that are missing headers.


         unapproved-licenses: Produces a report of the files with unapproved licenses.


         xml: Produces output in pretty-printed XML.

<LicenseID>
     The ID for a license.

<FamilyID>
     The ID for a license family.

<StandardCollection>
     Defines standard expression patterns (see above). Valid values are:

         ALL: All of the Standard Excludes combined.


         ARCH: The files and directories created by an ARCH source code control based tool.

--help 退出码为 0(实测)。标准集合(StandardCollection)还包含 BAZAAR、BITKEEPER 等版本控制工具的排除清单。

5.2 基本扫描:位置参数与 --output-file

对 Tentacles 解包出的源码树做文件级扫描,报告写入文件(位置参数为待扫目录,报告路径经 --output-file 指定,stdout 重定向到文件后经 grep -v SLF4J 过滤日志前缀,以下同):

cd /root/tentacles-demo && java -jar /root/tentacles/apache-rat-0.18/apache-rat-0.18.jar --output-file /root/rat-src-report.txt tentacles/content/apache-tentacles/0.1/apache-tentacles-0.1-source-release.zip.contents/apache-tentacles-0.1/src > /root/rat-src-stdout.txt 2>&1
grep -v SLF4J /root/rat-src-stdout.txt | head -14

实测输出:

INFO: Apache Creadur RAT 0.18 (Apache Software Foundation)
INFO: RAT summary:
INFO:   Approved:  39
INFO:   Archives:  0
INFO:   Binaries:  0
INFO:   Document types:  1
INFO:   Ignored:  0
INFO:   License categories:  2
INFO:   License names:  2
INFO:   Notices:  0
INFO:   Standards:  42
INFO:   Unapproved:  3
INFO:   Unknown:  3
ERROR: Unexpected count for UNAPPROVED, limit is [0,0].  Count: 3
Exception in thread "main" org.apache.rat.document.RatDocumentAnalysisException: Issues with UNAPPROVED

报告文件中未批准文件以 ! 标注:

grep -E '^!' /root/rat-src-report.txt

实测输出:

! Unapproved:         3    A count of unapproved licenses.
! /main/resources/licenses/cddl-1.0.txt
! /main/resources/licenses/cpl-1.0.txt
! /site/site.xml

扫描级别选项 --output-archive / --output-standard 均取 ProcessingType 三值:NOTIFICATION(仅列出存在)、PRESENCE(列出发现的许可)、ABSENCE(列出发现与缺失,最详尽),默认值分别为 NOTIFICATION 与 ABSENCE(见 5.1 节转录)。对归档目录(Tentacles 的 repo/)应显式加 --output-archive ABSENCE:默认级别下归档内部的许可完全不被识别(实测 Approved: 0、License categories: 0),加 ABSENCE 后识别出 4 个 jar 内的 Apache License 2.0(Approved: 4、License categories: 2,Archives: 5);对已解包源码树(content/)默认级别即可覆盖文件级审计。

💡 技术拓展:Rat 报告的计数器(Approved/Standards/Unapproved/Unknown 等)不只是统计——每个计数器带有内置阈值区间(如 UNAPPROVED 上限 0),超阈值即抛异常并以非零码退出。这让「许可审计通过与否」可直接程序化判定,但也意味着扫描失败与「审计不通过」在退出码上不可区分,见 5.5 节。

5.3 --input-exclude:多值选项与参数顺序坑

--input-exclude 可多次出现以排除匹配文件,但它是多值选项:后续一切非选项参数(含位置参数目录)都会被它吞掉,直到遇到 -- 或另一个选项。实测错误用法(目录放在最后,被吞后报错):

java -jar /root/tentacles/apache-rat-0.18/apache-rat-0.18.jar --output-file /root/rat-excl-report.txt --input-exclude **/resources/licenses/cddl-1.0.txt --input-exclude **/resources/licenses/cpl-1.0.txt --input-exclude **/site/site.xml tentacles/content/apache-tentacles/0.1/apache-tentacles-0.1-source-release.zip.contents/apache-tentacles-0.1/src > /root/rat-excl-stdout.txt 2>&1
grep -v SLF4J /root/rat-excl-stdout.txt | head -3

实测输出:

INFO: Apache Creadur RAT 0.18 (Apache Software Foundation)
ERROR: No directories or files specified for scanning. Did you forget to close a multi-argument option?
usage: java -jar apache-rat/target/apache-rat-0.18.jar [options] [DIR|ARCHIVE]

正确用法:把待扫目录作为第一个参数放在所有选项之前(或用 -- 显式分隔):

java -jar /root/tentacles/apache-rat-0.18/apache-rat-0.18.jar tentacles/content/apache-tentacles/0.1/apache-tentacles-0.1-source-release.zip.contents/apache-tentacles-0.1/src --output-file /root/rat-excl-report.txt --input-exclude **/resources/licenses/cddl-1.0.txt --input-exclude **/resources/licenses/cpl-1.0.txt --input-exclude **/site/site.xml > /root/rat-excl-stdout.txt 2>&1; echo "exit=$?"
grep -v SLF4J /root/rat-excl-stdout.txt | head -14

实测输出(3 个无许可头文件被合理排除后,审计干净通过、退出码 0):

exit=0
INFO: Apache Creadur RAT 0.18 (Apache Software Foundation)
INFO: RAT summary:
INFO:   Approved:  39
INFO:   Archives:  0
INFO:   Binaries:  0
INFO:   Document types:  2
INFO:   Ignored:  3
INFO:   License categories:  1
INFO:   License names:  1
INFO:   Notices:  0
INFO:   Standards:  39
INFO:   Unapproved:  0
INFO:   Unknown:  0

5.4 --help-licenses:查看内置许可证清单

java -jar /root/tentacles/apache-rat-0.18/apache-rat-0.18.jar --help-licenses

实测输出(节选,退出码 0):

INFO: Apache Creadur RAT 0.18 (Apache Software Foundation)
Listing of licenses for Apache Creadur RAT 0.18 (Apache Software Foundation)

====== Licenses ======

The defined licenses are:

AL1.0 (Apache License 1.0)

该清单中的许可证 ID 即 --licenses-approved / --licenses-denied 等选项接受的 <LicenseID> 取值来源。另注意 Rat 0.18 没有 --version 选项,误用会得到 ERROR: Unrecognized option: --version 与「Please use the --help option」提示(实测),版本号一律看任何命令输出首行的 INFO。

5.5 退出码与计数阈值治理

Rat 0.18 的退出码语义(全部实测):--help、--help-licenses、排除后干净的扫描为 0;存在超阈值计数时抛 RatDocumentAnalysisException、退出码 1,但报告文件仍完整生成。阈值由 --counter-min / --counter-max 调整,取值格式为 计数器名:数值(冒号分隔;实测逗号、等号写法均报 is not a valid Counter,如 'UNAPPROVED,5' is not a valid Counter)。将归档级扫描的 4 个默认阈值全部放宽后即可干净通过:

cd /root/tentacles-demo && java -jar /root/tentacles/apache-rat-0.18/apache-rat-0.18.jar --counter-max 'UNAPPROVED:5' --counter-min 'STANDARDS:0' --counter-min 'LICENSE_CATEGORIES:0' --counter-min 'LICENSE_NAMES:0' --output-file /tmp/rat-cm.txt tentacles/repo > /root/rat-cm-stdout.txt 2>&1; echo "exit=$?"

实测输出:

exit=0

默认阈值区间(由未放宽时的报错文案实测反推):UNAPPROVED [0,0]、STANDARDS [1,2147483647]、LICENSE_CATEGORIES [1,2147483647]、LICENSE_NAMES [1,2147483647]。自动化流水线可治理阈值让干净状态退出码归 0,或以报告文件生成为准、退出码仅作参考。

六、注意事项

  • Tentacles 退出码恒为 0:成败判断看日志动作(Crawl/Download/Copy/Unpack)与 repo/、content/、HTML 报告产出,不能依赖退出码(4.8 节六场景实测)。
  • 本地模式必须覆盖 -Dfilter:默认值 org/apache/openejb 几乎必然不命中,且空跑无任何警告、退出码 0(4.5 节实测);过滤器是对绝对路径的正则全匹配,子串写法无效。
  • Rat 多值选项吞位置参数:--input-exclude 等带「Multiple values may be specified」注释的选项,必须把待扫目录放在最前或用 -- 分隔(5.3 节实测)。
  • Rat 退出码 1 不等于扫描失败:报告照常生成,含义是「审计发现超阈值项」(5.5 节实测)。
  • 下载后缀写死:Tentacles 只抓 jar|zip|war|ear|rar|tar.gz,tar.gz 只下载不解包,其余格式无法通过参数扩展。

七、常见问题

Q1:Tentacles 运行完 repo/ 是空的,哪里错了? 按顺序排查:本地模式是否漏了 -Dfilter(默认过滤器不命中任何路径);URI 协议是否为 http/https/file: 之外的不识别值(静默空跑);URL 下是否有匹配后缀的文件。正常取样必有 Crawl(远程)或 Copy(本地)日志行。

Q2:Tentacles 日志出现 ERROR Not a zip 怎么处理? 该归档(或其嵌套条目)存在非标准 zip 结构,Tentacles 跳过该条目继续,整体流程与退出码不受影响;需人工抽查被跳过归档的法定文件是否齐全。

Q3:Rat 报告生成了但退出码 1,CI 流水线算失败吗? 按 5.5 节处理:报告文件完整生成即扫描成功;退出码 1 表示计数器超阈值(审计发现问题)。可调整阈值策略或在流水线中显式区分两种退出码含义;调整时 --counter-max 取值必须是 计数器名:数值 冒号格式(如 UNAPPROVED:5),逗号、等号写法均实测报 is not a valid Counter。

Q4:Rat 传了目录却报 No directories or files specified for scanning? 目录参数被前面的多值选项吞掉了,把目录移到所有选项之前(5.3 节实测对比)。

八、参考链接