fachproject-metrics-framework

A Scala framework for calculating JVM bytecode metrics based on the OPAL project

https://github.com/sse-labs/fachproject-metrics-framework

Science Score: 52.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
    Organization sse-labs has institutional domain (sse.cs.tu-dortmund.de)
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (12.5%) to scientific vocabulary
Last synced: 10 months ago · JSON representation ·

Repository

A Scala framework for calculating JVM bytecode metrics based on the OPAL project

Basic Info
  • Host: GitHub
  • Owner: sse-labs
  • Language: Scala
  • Default Branch: develop
  • Homepage:
  • Size: 15 MB
Statistics
  • Stars: 2
  • Watchers: 2
  • Forks: 2
  • Open Issues: 2
  • Releases: 0
Created almost 5 years ago · Last pushed over 3 years ago
Metadata Files
Readme Citation

README.md

Framework for Extracting JAR File Metrics

This framework builds on top of the OPAL project and provides a simple interface for extracting program metrics from JAR files. The framework handles CLI argument processing, initialization of OPAL project instances, and the creation of result files. This allows you to focus on the actual generation of program metrics, for which you can rely directly on the OPAL interface.

Simple Analysis Example

The following code shows how a simple analysis that counts the number of methods contained in a JAR file is implemented:

``` import org.tud.sse.metrics.input.CliParser.OptionMap import org.tud.sse.metrics.analysis.SingleFileAnalysis import org.tud.sse.metrics.application.SingleFileAnalysisApplication

import org.opalj.br.analyses.Project

import java.net.URL import scala.util.Try

class NumberOfMethodsAnalysis extends SingleFileAnalysis {

override protected def buildAnalysis(): SingleFileAnalysis = this

override def analyzeProject(project: Project[URL], customOptions: OptionMap): Try[Iterable[JarFileMetricValue]] = Try { val metric = project.methodsCount

List(JarFileMetricValue("methods.count", metric))

}

override def analysisName: String = "method.count" } To execute this analysis example, you need to register it in an executable `SingleFileAnalysisApplication`, which may look like this: object MyAnalysisApplication extends SingleFileAnalysisApplication {

override protected val registeredAnalyses: Seq[SingleFileAnalysis] = Seq(new NumberOfMethodsAnalysis()) } ```

Since in the above example MyAnalysisApplication extends SingleFileAnalysisApplication, it already is a self-contained, executable analysis. You can execute it for example with the following parameters: --batch-mode --out-file out.csv /path/to/jar/folder This will execute the analysis for all JAR files contained in /path/to/jar/folder, and create a result report containing the file names, and their method count at out.csv. Executing the analysis for a single JAR file is done with the following parameters: --out-file out.csv /path/to/jar/file.jar For more information on default CLI parameters, see CLI Reference.

Complex Analyses

As seen above, a SingleFileAnalysis extracts metrics from JAR files independently. It is meant to be stateless, as it does not regard previous analysis results when processing a JAR file. However, sometimes metrics values depend on multiple JAR files (i.e. all releases of a library), or are calculated based on the differences between two JAR files (i.e. number of new methods). For these cases, the MultiFileAnalysis can be used.

A MultiFileAnalysis first calculates intermediate results of a generic type T for every JAR file, and then processes those intermediate results to calculate one or more metric values. The example below shows an analysis that calculates the average increase in the number of methods for all analyzed JAR files. The intermediate result (the absolute increase in methods) is of type Int, therefore the analysis extends MultiFileAnalysis[Int]. ``` class AverageMethodDifferenceAnalysis(jarDir: File) extends MultiFileAnalysisInt{

override def produceAnalysisResultForJAR(project: Project[URL], lastResult: Option[Int], customOptions: OptionMap): Try[Int] = { Try(project.methodsCount - lastResult.getOrElse(0)) }

override def produceMetricValues(): List[JarFileMetricsResult] = {

val allNewMethodCounts = analysisResultsPerFile.values.map(_.get).sum
val averageNewMethodCount = allNewMethodCounts.toDouble / analysisResultsPerFile.size
val averageNewMethodMetric = JarFileMetricValue("newmethodcount.average", averageNewMethodCount)

List(JarFileMetricsResult(jarDir, success = true, List(averageNewMethodMetric)))

}

override def analysisName: String = "method-difference.avg" } ```

To make this example executable, it is sufficient to create an object that extends MultiFileAnalysisApplication, as shown below: ``` object AverageMethodsDifferenceAnalysisApp extends MultiFileAnalysisApplication {

override protected def buildAnalyses(directory: File): Seq[MultiFileAnalysis] = Seq(new AverageMethodDifferenceAnalysis(directory)) } ```

CLI Reference

The general usage of all analyses is the following: analysisApplication [<options>] <inputfile> The table below lists all parameters that are available by default. Any additional parameters of the form --<option> <value> or --<switch> are passed directly to your analysis implementation via the parameter customOptions: OptionMap, so you can customize your analysis via CLI.

|Option|SingleFileAnalysis|MultiFileAnalysis|Description| ---|---|---|--- |--out-file <value>| Yes | Yes | Specifies that the analysis results should be written to the given file. The result file will be a CSV table.| |--is-library | Yes | Yes | If this switch is set, all OPAL projects will be loaded as libraries (as opposed to applications). This mainly affects analyses that depend on the entrypoints / callgraph of a project.| |--opal-logging | Yes | Yes | If set, all OPAL logging will be forwarded to the console. By default, all OPAL logging output is suppressed.| |--batch-mode| Yes | No | If set, the <inputfile> will be interpreted as a directory, and the SingleFileAnalysis will be executed for every JAR file contained in that directory.| |--exclude-analysis <name>| Yes | Yes | Excludes the analysis with name <value> from the current analysis run. May be specified multiple times to exclude multiple analyses. All non-excluded analyses will be executed. Cannot be used in combination with --include-analysis.| |--include-analysis <name>| Yes | Yes | Includes the analysis with name <value> for the current analysis run. May be specified multiple times to include multiple analyses. All non-included analyses will not be executed. If used in combination with usage of --exclude-analysis, only include specifications will apply.| |--no-jre-classes| Yes | Yes | Prevents framework from loading the JRE classes when initializing an OPAL project. In general those classes are needed to resolve the supertype hierarchy or callgraphs.| |--additional-classes-dir <path>| Yes | Yes | Can be used to specify a JAR file or a directory containing JAR files. In both cases all contained classes will be loaded as library classes when initializing the OPAL project.| |--load-additional-classes-as-interfaces | Yes | Yes | If this switch is set, all additional classes will be loaded as interfaces only, without their actual implementation. Has no affect if --additional-classes-dir is not set.|

Owner

  • Name: Secure Software Engineering Labs at TU Dortmund
  • Login: sse-labs
  • Kind: organization
  • Location: Dortmund, Germany

Citation (CITATION.cff)

# This CITATION.cff file was generated with cffinit.
# Visit https://bit.ly/cffinit to generate yours today!

cff-version: 1.2.0
title: OPAL Based Software Metrics Framework
message: >-
  If you use this software, please cite it using the
  metadata from this file.
type: software
authors:
  - given-names: Johannes
    family-names: Düsing
    email: johannes.duesing@tu-dortmund.de
    affiliation: TU Dortmund
    orcid: 'https://orcid.org/0000-0002-9367-2206'
repository-code: 'https://github.com/sse-labs/fachproject-metrics-framework'
abstract: >-
  A simple framework using OPAL to provide interfaces for
  calculating numerical software metrics.

GitHub Events

Total
Last Year