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.
Evaluation: Advanced 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 jarsare 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-dependenciesto 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 toInnerSource Insightfor 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 and, 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.
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.
Although pom.xml files are ignored if they are inside a META-INFdirectory by default, this can now be changed if needed by configuring thescan-pom-files-in-meta-inf-directoryfeature using theFeature Configuration REST API - v2.
Sonatype IQ Scanner configuration option “excludeMavenDependencyManagement"
Value type: Boolean
Default value: False
Change to existing behavior: None
Purpose: Improves project dependency detection accuracy. When enabled and the scanner is processing a manifest (Maven POM), then dependencies that are ONLY declared in the dependencyManagement section are excluded. If a component's version was declared in the dependency management section and not in the project dependency version then the component version declared in the dependency management section will be used.
By default for backwards compatibility, all unique dependencies that can be fully resolved from both the project dependencies and dependencyManagement sections are included.
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): sbtmakePom
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>