Skip to content

kordamp/jarviz

Repository files navigation

JAR file analyzer

Build Status Download SLSA 3 GitHub all releases


Jarviz is a JAR file analyzer tool. You can obtain metadata from a JAR such as its manifest, manifest entries, bytecode versions, declarative services, Java module descriptors and more.

Jarviz is a JAR file analyzer tool
Usage: jarviz [-hV] [-D=<key=value>]... [COMMAND]

Options:
  -D=<key=value>    Sets a System property. 🔁
  -h, --help        Show this help message and exit.
  -V, --version     Print version information and exit.

Commands:
  bytecode             Commands for the JAR's bytecode.
  checksum             Verify JAR checksums.
  entries              Commands for JAR entries.
  manifest             Commands for the JAR's manifest.
  module               Commands for modular JARs.
  packages             Commands for packages.
  services             Commands for declarative services.
  generate-completion  Generate bash/zsh completion script for jarviz.

Documentation found at https://github.com/kordamp/jarviz

Commands

All commands accept the following inputs

Flag Description

gav

Maven GAV coordinates i.e, com.fasterxml.jackson.core:jackson-core:2.14.1. Resolvable only from Maven Central.

url

URL to target resource i.e, https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.14.1/jackson-core-2.14.1.jar.

file

Path to a local JAR file.

classpath

Platform specific set of file paths i.e, /opt/jars/file.jar:/opt/jars/file2.jar for Linux/OSX, C:\jars\file1.jar;C:\jars\file2.jar for Windows.

directory

Path to a directory that contains JAR files. Jarviz will recursively walk the tree looking for **/*.jar.

These inputs may be mixed and defined multiple times as needed.

Bytecode

show

Show the JAR’s bytecode version(s). Will show the value of the Bytecode-Version manifest attribute if it exists; an ordered list of total unversioned classes per bytecode version; an ordered list of total versioned classes.

$ jarviz bytecode show --gav org.kordamp.maven:pomchecker-toolprovider:1.8.0
subject: pomchecker-toolprovider-1.8.0.jar
Unversioned classes. Bytecode version: 47 total: 9
Unversioned classes. Bytecode version: 48 total: 239
Unversioned classes. Bytecode version: 49 total: 314
Unversioned classes. Bytecode version: 50 total: 896
Unversioned classes. Bytecode version: 51 total: 595
Unversioned classes. Bytecode version: 52 total: 4,571
Unversioned classes. Bytecode version: 53 total: 2

Use the --details flag to list all classes per bytecode version

$ jarviz bytecode show --gav org.kordamp.maven:pomchecker-toolprovider:1.8.0 \
    --bytecode-version 47 --details
subject: pomchecker-toolprovider-1.8.0.jar
Unversioned classes. Bytecode version: 47 total: 9
org.aopalliance.aop.Advice
org.aopalliance.aop.AspectException
org.aopalliance.intercept.ConstructorInterceptor
org.aopalliance.intercept.ConstructorInvocation
org.aopalliance.intercept.Interceptor
org.aopalliance.intercept.Invocation
org.aopalliance.intercept.Joinpoint
org.aopalliance.intercept.MethodInterceptor
org.aopalliance.intercept.MethodInvocation

jackson-core is a Multi Release JAR (MR-JAR).

$ jarviz bytecode show --gav com.fasterxml.jackson.core:jackson-core:2.14.1
subject: jackson-core-2.14.1.jar
Unversioned classes. Bytecode version: 52 total: 160
Versioned classes 9. Bytecode version: 53 total: 1

$ jarviz bytecode show --gav com.fasterxml.jackson.core:jackson-core:2.14.1 \
    --bytecode-version 53 --details
subject: jackson-core-2.14.1.jar
Versioned classes 9. Bytecode version: 53 total: 1
module-info

Checksum

Verify JAR checksums.

$ jarviz checksum --gav org.jreleaser:jreleaser:1.5.0
subject: jreleaser-1.5.0.jar
jreleaser-1.5.0.jar.md5    ✅
jreleaser-1.5.0.jar.sha1   ✅
jreleaser-1.5.0.jar.sha256 ✅
jreleaser-1.5.0.jar.sha512 ✅

Entries

extract

Extract a given JAR entry or entries.

$ jarviz entries extract --gav org.slf4j:slf4j-api:2.0.6 --entry-name META-INF/MANIFEST.MF
subject: slf4j-api-2.0.6.jar
entry name: META-INF/MANIFEST.MF
META-INF/MANIFEST.MF

$ tree slf4j-api-2.0.6
slf4j-api-2.0.6
└── META-INF
    └── MANIFEST.MF

1 directory, 1 file
$ jarviz entries extract --gav org.slf4j:slf4j-api:2.0.6 --entry-pattern META-INF/maven/**/* --flatten
subject: slf4j-api-2.0.6.jar
entry pattern: glob:**/META-INF/maven/**/*
META-INF/maven/org.slf4j/slf4j-api/pom.properties
META-INF/maven/org.slf4j/slf4j-api/pom.xml

$ tree slf4j-api-2.0.6
slf4j-api-2.0.6
├── pom.properties
└── pom.xml

0 directories, 2 files

find

Find a given JAR entry or entries.

$ jarviz entries find --gav org.slf4j:slf4j-api:2.0.6 --entry-name META-INF/MANIFEST.MF
subject: slf4j-api-2.0.6.jar
entry name: META-INF/MANIFEST.MF
META-INF/MANIFEST.MF

Using glob syntax

$ jarviz entries find --gav org.slf4j:slf4j-api:2.0.6 --entry-pattern glob:/org/slf4j/spi/*.class
subject: slf4j-api-2.0.6.jar
entry pattern: org.slf4j.spi.*.class
org/slf4j/spi/CallerBoundaryAware.class
org/slf4j/spi/DefaultLoggingEventBuilder$1.class
org/slf4j/spi/DefaultLoggingEventBuilder.class
org/slf4j/spi/LocationAwareLogger.class
org/slf4j/spi/LoggerFactoryBinder.class
org/slf4j/spi/LoggingEventAware.class
org/slf4j/spi/LoggingEventBuilder.class
org/slf4j/spi/MDCAdapter.class
org/slf4j/spi/MarkerFactoryBinder.class
org/slf4j/spi/NOPLoggingEventBuilder.class
org/slf4j/spi/SLF4JServiceProvider.class

Using regex syntax

$ jarviz entries find --gav org.slf4j:slf4j-api:2.0.6 --entry-pattern regex:/org/slf4j/spi/.*.class
subject: slf4j-api-2.0.6.jar
entry pattern: org.slf4j.spi.*.class
org/slf4j/spi/CallerBoundaryAware.class
org/slf4j/spi/DefaultLoggingEventBuilder$1.class
org/slf4j/spi/DefaultLoggingEventBuilder.class
org/slf4j/spi/LocationAwareLogger.class
org/slf4j/spi/LoggerFactoryBinder.class
org/slf4j/spi/LoggingEventAware.class
org/slf4j/spi/LoggingEventBuilder.class
org/slf4j/spi/MDCAdapter.class
org/slf4j/spi/MarkerFactoryBinder.class
org/slf4j/spi/NOPLoggingEventBuilder.class
org/slf4j/spi/SLF4JServiceProvider.class

Manifest

show

Show the JAR’s manifest.

$ jarviz manifest show --gav org.kordamp.maven:pomchecker-toolprovider:1.4.0
subject: pomchecker-toolprovider-1.4.0.jar
Manifest-Version: 1.0
Created-By: Maven Jar Plugin 3.2.0
Build-Jdk-Spec: 11
Implementation-Title: pomchecker-toolprovider
Implementation-Version: 1.4.0
Implementation-Vendor: Kordamp
Automatic-Module-Name: org.kordamp.maven.pomchecker
Build-Jdk: 9 (Azul Systems, Inc. 11.0.17+8-LTS)
Build-OS: Linux amd64 5.15.0-1022-azure
Build-Revision: b252400e16942f5f944ecec68914e264f2fe37af
Build-Timestamp: 2022-10-31T18:52:24Z
Main-Class: org.kordamp.maven.checker.toolprovider.Pomchecker

query

Query manifest attributes.

$ jarviz manifest query --gav org.kordamp.maven:pomchecker-toolprovider:1.4.0 \
    --attribute-name Automatic-Module-Name
subject: pomchecker-toolprovider-1.4.0.jar
Automatic-Module-Name: org.kordamp.maven.pomchecker

Module

name

Show the module name. Will show the module name, whether it’s automatic or not, and if the name is valid.

slf4j-api:1.7.36 defines an Automatic-Module-Name in its manifest

$ jarviz module name --gav org.slf4j:slf4j-api:1.7.36
subject: slf4j-api-1.7.36.jar
name: org.slf4j
source: manifest
automatic: true
valid: true

slf4j-api:2.0.6 defines a full module descriptor

$ jarviz module name --gav org.slf4j:slf4j-api:2.0.6
subject: slf4j-api-2.0.6.jar
name: org.slf4j
source: explicit
automatic: false
valid: true

This JAR filename is invalid

$ jarviz module name --file foo-1-TAG.jar
subject: foo-1-TAG.jar
name: foo.1.TAG
source: filename
automatic: true
valid: false
reason: foo.1.TAG: Invalid module name: '1' is not a Java identifier

descriptor

Show the module descriptor in detail.

$ jarviz module descriptor --gav jakarta.activation:jakarta.activation-api:2.1.1
subject: jakarta.activation-api-2.1.1.jar
name: jakarta.activation
version: 2.1.1
open: false
automatic: false
exports:
  jakarta.activation
  jakarta.activation.spi
requires:
  java.base mandated
  java.desktop static
  java.logging
uses:
  jakarta.activation.spi.MailcapRegistryProvider
  jakarta.activation.spi.MimeTypeRegistryProvider

Packages

validate

Validate package names

$ jarviz packages validate --gav dev.gradleplugins:gradle-api:8.0.1
subject: gradle-api-8.0.1.jar
total: 72
org.gradle.internal.impldep.META-INF.versions.11.org.bouncycastle.jcajce.provider.asymmetric.edec
org.gradle.internal.impldep.META-INF.versions.15.org.bouncycastle.jcajce.provider.asymmetric.edec
org.gradle.internal.impldep.META-INF.versions.9
org.gradle.internal.impldep.META-INF.versions.9.com.sun.istack.logging
org.gradle.internal.impldep.META-INF.versions.9.jakarta.xml.bind
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.anssi
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.bc
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.cryptlib
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.cryptopro
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.gm
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.isara
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.nist
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.oiw
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.pkcs
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.rosstandart
org.gradle.internal.impldep.META-INF.versions.9.org.bouncycastle.asn1.sec
...

split

Display split packages

$ jarviz packages split --directory ~/.sdkman/candidates/maven/current/lib/
subject: maven-artifact-3.9.0.jar
org.apache.maven.artifact
org.apache.maven.artifact.handler
org.apache.maven.artifact.metadata
org.apache.maven.artifact.repository
org.apache.maven.artifact.repository.layout
org.apache.maven.artifact.repository.metadata
org.apache.maven.artifact.resolver
org.apache.maven.artifact.resolver.filter
org.apache.maven.artifact.versioning
org.apache.maven.repository
org.apache.maven.repository.legacy.metadata

subject: maven-compat-3.9.0.jar
org.apache.maven.artifact
org.apache.maven.artifact.repository
org.apache.maven.artifact.repository.layout
org.apache.maven.artifact.repository.metadata
org.apache.maven.artifact.resolver
org.apache.maven.artifact.resolver.filter
org.apache.maven.artifact.versioning
org.apache.maven.execution
org.apache.maven.project
org.apache.maven.project.path
org.apache.maven.repository

...

Services

list

Display registered services.

$ jarviz services list --gav org.kordamp.maven:pomchecker-toolprovider:1.8.0
subject: pomchecker-toolprovider-1.8.0.jar
java.util.spi.ToolProvider
javax.annotation.processing.Processor
org.apache.commons.logging.LogFactory
org.slf4j.spi.SLF4JServiceProvider

show

Display service implementations for a given service.

$ jarviz services show --gav org.kordamp.maven:pomchecker-toolprovider:1.8.0 \
    --service-name java.util.spi.ToolProvider
subject: pomchecker-toolprovider-1.8.0.jar
service: java.util.spi.ToolProvider
org.kordamp.maven.checker.toolprovider.Pomchecker

Reports

All commands accept the following settings for generating reports:

--report-format=<format>
                Report format to use. Repeatable.
--report-path=<reportPath>
                Path to report filename (without extension)

Format may be any of [txt, xml, json, yaml].

Example
$ jarviz module name --gav com.sun.mail:jakarta.mail:2.0.1 \
    --report-path jakarta.mail \
    --report-format txt \
    --report-format xml \
    --report-format json \
    --report-format yaml
subject: jakarta.mail-2.0.1.jar
name: jakarta.mail
source: explicit
automatic: false
valid: true
jakarta.mail.txt
subjects:
  subject:
    command: module name
    jar:
      file: jakarta.mail-2.0.1.jar
      size: 689294
      sha256: 8988bdbde922ee173db7179e23393dd2258f3b64f708f41082e03f0e0494cc23
    result:
      name: jakarta.mail
      source: explicit
      automatic: false
      valid: true
jakarta.mail.xml
<jarviz>
  <subjects>
    <subject>
      <command>module name</command>
      <jar>
        <file>jakarta.mail-2.0.1.jar</file>
        <size>689294</size>
        <sha256>8988bdbde922ee173db7179e23393dd2258f3b64f708f41082e03f0e0494cc23</sha256>
      </jar>
      <result>
        <name>jakarta.mail</name>
        <source>explicit</source>
        <automatic>false</automatic>
        <valid>true</valid>
      </result>
    </subject>
  </subjects>
</jarviz>
jakarta.mail.json
{
  "subjects": [
    {
      "command": "module name",
      "jar": {
        "file": "jakarta.mail-2.0.1.jar",
        "size": 689294,
        "sha256": "8988bdbde922ee173db7179e23393dd2258f3b64f708f41082e03f0e0494cc23"
      },
      "result": {
        "name": "jakarta.mail",
        "source": "explicit",
        "automatic": false,
        "valid": true
      }
    }
  ]
}
jakarta.mail.yaml
subjects:
  - command: module name
    jar:
      file: jakarta.mail-2.0.1.jar
      size: 689294
      sha256: 8988bdbde922ee173db7179e23393dd2258f3b64f708f41082e03f0e0494cc23
    result:
      name: jakarta.mail
      source: explicit
      automatic: false
      valid: true

Install

Early Access

JBang

// Download, cache, and run
jbang jarviz-snapshot@kordamp <command> [<args>]

manually

Download the pre-compiled binary matching your OS and processor from the releases page, uncompress and copy to the desired location.

Note
Be mindful that jarviz-early-access.zip requires Java 11 to be installed while jarviz-standalone-early-access-*.zip can be used without a previous installation of Java as it includes its own Java Runtime.

Stable

Sdkman

Requires Java 11

sdk install jarviz

Homebrew tap

brew install kordamp/tap/jarviz

Scoop:

Requires Java 11

scoop bucket add jarviz https://github.com/kordamp/scoop-jarviz.git
scoop install jarviz

JBang

// Download, cache, and run
jbang jarviz@kordamp <command> [<args>]

manually

Download the pre-compiled binary matching your OS and processor from the releases page, uncompress and copy to the desired location.

Note
Be mindful that jarviz-0.3.0.zip requires Java 11 to be installed while jarviz-standalone-0.3.0-*.zip can be used without a previous installation of Java as it includes its own Java Runtime.

Community

  • Ask questions on our Discussions page.

  • Twitter Follow

  • Join our contributors by reporting bugs, proposing features, sending patches, promoting the project, helping others.

Code of Conduct

This project adheres to a code of conduct. By participating, you are expected to uphold this code. We appreciate your contribution. Please refer to our contributing guidelines for further information.