Java Application Analysis
JVM Ecosystems
IQ server Java application analysis supports most JVM-based languages and is not limited to Java only. These include the most popular languages in use by the developer community, e.g., Kotlin, Scala, Groovy, Clojure, Fantom, Ceylon, JRuby, Golo, etc.
On this page
Evaluation: Advance Binary Fingerprinting
- Uber/Shaded Archives
- Alternate Methods
- Android
- SBT Assembly
- Similar Matching
- InnerSource
- Direct and Transitive Dependencies
- Gradle Community Plugin
- SBOMs
Evaluation: Source code and manifest analysis
Evaluation: Advance Binary Fingerprinting
Java scanning supports packaged archives including (.ear/.war/.jar/.zip/.tar.gz) files. For the best results, we recommend using the post-build artifact as the scan target (what you are planning to deploy) as it will contain all the direct and transitive dependencies required by the project. After a normal CI build, add a post-build step to do the analysis using the CI Plugins or the CLI Scanner . A Lifecycle evaluation will pick up any dependencies packaged into the archive or included in the target directory.
Uber/Shaded Archives
Uber jars are a way to include dependencies by copying in their contents when the jar is built. The Lifecycle algorithms will not identify them as separate dependencies, as these jars could be similarly matched to modified open-source components. This will lead to confusing results for development teams. For more accurate results, you will need to call the index goal of the Maven plugin at the time of building the uber/shaded jar. This will generate a dependency index (module.xml file) of direct and transitive dependencies found in the shaded jar's POM file. Any module.xml files found in the scan path by the CI Scanners will be included in the results.
Alternate Methods
Custom jar files typically do not include their dependencies in the scan context so scanning them will not produce results. The maven copy dependencies command can be used: mvn dependency:copy-dependencies to include the dependencies into a separate directory. This directory can be scanned via the CLI scanner or similar tools.Android
The Lifecycle scanner does not support scanning a `.apk` directly due to the compilers converting the open-source code into a DEX (Dalvik Executable) file: a minified/modified version of the code. For this reason, scanning prior to the assembling of the `.apk` is required. We suggest embedding the native Maven or Gradle scanners instead.SBT Assembly
To perform an analysis of a sbt assembly, a temporary pom.xml file will need to be created using the sbt makePom command. We recommend using the Maven plugin for the best results. See the example steps below.Similar Matching
Evaluation of modified dependencies is supported for Java. The inner contents of components are analyzed along with their fingerprints to determine the best match of the original source component. Components that have been changed from their published source are susceptible to additional risk.InnerSource
When using the Maven plugin or Grade plugin , Java components created by insider teams will be labeled in the application scan report. Any dependencies only brought in by the Innersource component will be considered direct dependencies of those components. Innersource components will need to be scanned before the current project in order to determine if a component is Innersource or not. Refer to Innersource for more details.Direct and Transitive Dependencies
The project's manifest is used to determine if a dependency is directly called by the project or not. Any dependencies not found in the manifest are considered transitive dependencies. The Transitive Solver provides remediation recommendations based on the direct dependency of transitive dependency violations.Gradle Community Plugin
This plugin can be used to natively scan Gradle projects using Lifecycle.Software Bill of Materials (SBOMs)
The Lifecycle scanner can scan SBOMs generated from CycloneDX for Java. See the CycloneDX pages for details.
Evaluation: Source code and manifest analysis
A Java project's source code could be analyzed for direct dependencies using just the coordinates provided in the manifest files. When any binaries are detected in the scan path, the manifest files are not used for identifying components. Pointing directly to the path of the manifest is recommended to force a manifest analysis.
- The transitive dependencies are not automatically resolved, therefore not included during this analysis. The Maven plugin 'evaluate' goal should be used to resolve transitive dependencies.
- Dependencies with a group, artifact id, and exact version number are required.
- The extension and classifier fields are optional.
- 142
pom.xml files are ignored if they are inside a META-INF directory. This is because these files do not necessarily represent the application, particularly in the case of uber/shaded archives. 149
Although pom.xml files are ignored if they are inside a META-INF directory by default, this can now be changed if needed by configuring the scan-pom-files-in-meta-inf-directory feature using the Feature Configuration REST API - v2.
Maven
- Target the primary pom.xml file.
- The 'test' and 'provided' scoped dependencies are not evaluated
<dependency> <groupId>org.example</groupId> <artifactId>ACME-business</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
Gradle
- Target the primary build.gradle file.
- Only build.gradle files written in Groovy are supported
- Supported scopes: "api", "apiElements", "compileClasspath", "implementation", "compileOnly", "compileOnlyApi", "compile"
- Other dependency scopes are not evaluated.
dependencies { compile 'org.example:ACME-business:1.0-SNAPSHOT' }
SBT Assembly
- Create a pom file (case sensitive): sbt makePom
- Copy the generated pom file to the root directory and rename it.
- cp target/scala-2.13/real-world-example-project_2.13-1.0.pom pom.xml
- or manually copy and rename it
- Run the maven plugin evaluate goal. Example:
mvn com.sonatype.clm:clm-maven-plugin:evaluate -Dclm.serverUrl=http://localhost:8070 -Dclm.username=admin -Dclm.password=admin123 -Dclm.applicationId=scala-play -Dclm.stage=build
Example: pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>ACME-Consumer</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>Consumer-Service</module> <module>Consumer-Data</module> </modules> <properties> <commons.version>2.6</commons.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons.version}</version> </dependency> <dependency> <groupId>org.example</groupId> <artifactId>ACME-data</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </dependencyManagement> </project>
Using the Jenkins CI Plugin to scan manifests
The Jenkins plugin will not evaluate manifest files by default so a custom scan pattern is required. See the documentation for details.
nexusPolicyEvaluation iqApplication: 'SampApp' , iqScanPatterns: [[scanPattern: '**/pom.xml' ], [scanPattern: '**/build.gradle']], iqStage: 'build'