diff --git a/.asf.yaml b/.asf.yaml new file mode 100644 index 00000000000..4dc8f59efac --- /dev/null +++ b/.asf.yaml @@ -0,0 +1,28 @@ +# https://cwiki.apache.org/confluence/display/INFRA/.asf.yaml+features+for+git+repositories + +github: + description: "Apache JMeter open-source load testing tool for analyzing and measuring the performance of a variety of services" + homepage: https://jmeter.apache.org/ + labels: + - performance + - test + - java + + dependabot_alerts: true + dependabot_updates: false + + enabled_merge_buttons: + squash: true + merge: false + rebase: true + + features: + wiki: false + issues: true + projects: false + +notifications: + commits: commits@jmeter.apache.org + issues: dev@jmeter.apache.org + pullrequests: dev@jmeter.apache.org + jira_options: link label diff --git a/.editorconfig b/.editorconfig index 018a717cc91..5f44ca2b086 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,6 +5,12 @@ trim_trailing_whitespace = true insert_final_newline = true charset = utf-8 indent_style = space +max_line_length = 120 +ij_any_align_multiline_parameters = false +ij_any_do_while_brace_force = always +ij_any_for_brace_force = always +ij_any_if_brace_force = always +ij_any_while_brace_force = always [{*.sh,gradlew}] end_of_line = lf @@ -16,9 +22,17 @@ end_of_line = crlf ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL ij_kotlin_name_count_to_use_star_import = 999 ij_kotlin_name_count_to_use_star_import_for_members = 999 +# Kotlin code style does not use double-continuation indents +# Revise this when the following issues are resolved: +# https://youtrack.jetbrains.com/issue/KTIJ-17907 +# https://github.com/pinterest/ktlint/issues/805 +ij_kotlin_continuation_indent_size = 4 [*.java] # Doc: https://youtrack.jetbrains.com/issue/IDEA-170643#focus=streamItem-27-3708697.0-0 #"static ", "java.", "javax", "org", "net", "com", "" ij_java_imports_layout = $*,|,java.**,|,javax.**,|,org.**,|,net.**,|,com.**,|,* ij_java_use_single_class_imports = true + +[*.xml] +indent_size = 2 diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 00000000000..502aadfbe82 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,59 @@ +name: Bug report +description: Create a report and help us improve +labels: + - defect + - to-triage +body: + - type: markdown + attributes: + value: | + Please fill in all required fields with as many details as possible. + Read the [User manual](https://jmeter.apache.org/usermanual/index.html) and/or [Reference documentation](https://jmeter.apache.org/usermanual/component_reference.html) + - type: textarea + id: expected + attributes: + label: Expected behavior + description: | + Describe what you were expecting JMeter to do + placeholder: | + Here you can also attach log files, screenshots or a video + - type: textarea + id: actual + attributes: + label: Actual behavior + description: | + Describe what you observed JMeter did instead + placeholder: | + Here you can also attach log files (e.g. jmeter.log), screenshots or a video + - type: textarea + id: steps + attributes: + label: Steps to reproduce the problem + description: | + - If the problem relates to a third-party plugin, consider removing them first + placeholder: | + Here you can also attach log files, screenshots or a video + validations: + required: true + - type: input + id: jmeter-version + attributes: + label: JMeter Version + description: | + What JMeter version and edition did you use? + Note: While you can obviously continue using older versions of JMeter, it may well be that your bug is already fixed. If you're using an older version, please also try to reproduce the bug in the latest version of JMeter before reporting it. + placeholder: ex. 5.6 + validations: + required: true + - type: input + id: java-version + attributes: + label: Java Version + description: What JDK version and distribution did you use (use `java -version`) + placeholder: ex. openjdk version "17" 2021-09-14 + - type: input + id: os-version + attributes: + label: OS Version + description: What operating system version and distribution did you use (use e.g. `ver` on Windows) + placeholder: ex. Microsoft Windows [Version 10.0.22000.856] diff --git a/.github/ISSUE_TEMPLATE/config.yaml b/.github/ISSUE_TEMPLATE/config.yaml new file mode 100644 index 00000000000..04a0fb026db --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yaml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: JMeter users mailing list + url: https://jmeter.apache.org/mail2.html + about: Please ask questions on JMeter usage on users mailing list (note that you need to subscribe first) diff --git a/.github/ISSUE_TEMPLATE/documentation.yaml b/.github/ISSUE_TEMPLATE/documentation.yaml new file mode 100644 index 00000000000..66192ff73e6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.yaml @@ -0,0 +1,27 @@ +name: Feedback about the manual +description: Found an issue with the documentation? +labels: + - documentation + - to-triage +body: + - type: markdown + attributes: + value: | + Please fill in all required fields with as many details as possible. + - type: input + id: url + attributes: + label: The documentation URL + placeholder: ex. https://jmeter.apache.org/usermanual/best-practices.html + validations: + required: true + - type: textarea + id: feedback + attributes: + label: Feedback + description: | + Describe what issue with the documentation you've found + placeholder: | + Here you can also attach log files, screenshots or a video + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 00000000000..85fc221b752 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,58 @@ +name: Feature Request +description: Suggest an idea +labels: + - enhancement + - to-triage +body: + - type: markdown + attributes: + value: | + Please describe the use-case you have. This will better help us understand the context in which you're looking for a new feature. + - type: textarea + id: use-case + attributes: + label: Use case + description: | + Please describe the use-case you have. This will better help us understand the context in which you're looking for a new feature. + placeholder: Describe the use-case here + validations: + required: true + - type: textarea + id: solution + attributes: + label: Possible solution + description: | + Please describe a possible solution you'd like to see in JMeter, ideally with example code. + Please note, it's not always easy to describe a good solution. Describing the use-case above is much more important to us. + placeholder: Describe the possible solution here. + validations: + required: false + - type: textarea + id: workarounds + attributes: + label: Possible workarounds + description: | + Please describe the possible workarounds you've implemented to work around the lacking functionality. + placeholder: Describe the possible workarounds here. + validations: + required: false + - type: input + id: jmeter-version + attributes: + label: JMeter Version + description: What JMeter version and edition did you use? + placeholder: ex. 5.6 + validations: + required: true + - type: input + id: java-version + attributes: + label: Java Version + description: What JDK version and distribution did you use (use `java -version`) + placeholder: ex. openjdk version "17" 2021-09-14 + - type: input + id: os-version + attributes: + label: OS Version + description: What operating system version and distribution did you use (use e.g. `ver` on Windows) + placeholder: ex. Microsoft Windows [Version 10.0.22000.856] diff --git a/.github/ISSUE_TEMPLATE/regression.yaml b/.github/ISSUE_TEMPLATE/regression.yaml new file mode 100644 index 00000000000..d27609c5810 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/regression.yaml @@ -0,0 +1,59 @@ +name: Regression +description: Report a problem about something that used to work +labels: + - regression + - to-triage +body: + - type: markdown + attributes: + value: | + Please fill in all required fields with as many details as possible. + Read the [User manual](https://jmeter.apache.org/usermanual/index.html) and/or [Reference documentation](https://jmeter.apache.org/usermanual/component_reference.html) + - type: textarea + id: expected + attributes: + label: Expected behavior + description: | + Describe what you were expecting JMeter to do + placeholder: | + Here you can also attach log files, screenshots or a video + - type: textarea + id: actual + attributes: + label: Actual behavior + description: | + Describe what you observed JMeter did instead + placeholder: | + Here you can also attach log files (e.g. jmeter.log), screenshots or a video + - type: textarea + id: steps + attributes: + label: Steps to reproduce the problem + description: | + - If the problem relates to a third-party plugin, consider removing them first + placeholder: | + Here you can also attach log files, screenshots or a video + validations: + required: true + - type: input + id: jmeter-version + attributes: + label: JMeter Version + description: | + What JMeter version and edition did you use? + Note: While you can obviously continue using older versions of JMeter, it may well be that your bug is already fixed. If you're using an older version, please also try to reproduce the bug in the latest version of JMeter before reporting it. + placeholder: ex. 5.6 + validations: + required: true + - type: input + id: java-version + attributes: + label: Java Version + description: What JDK version and distribution did you use (use `java -version`) + placeholder: ex. openjdk version "17" 2021-09-14 + - type: input + id: os-version + attributes: + label: OS Version + description: What operating system version and distribution did you use (use e.g. `ver` on Windows) + placeholder: ex. Microsoft Windows [Version 10.0.22000.856] diff --git a/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 00000000000..0a09f1b3941 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,72 @@ +# See https://github.com/release-drafter/release-drafter#configuration-options +name-template: 'v$RESOLVED_VERSION' +tag-template: 'rel/v$RESOLVED_VERSION' +exclude-labels: + - 'skip-changelog' +categories: + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - 'defect' + - title: '📝 Documentation' + labels: + - 'documentation' + - title: '🧰 Maintenance' + label: 'chore' + - title: '⬆️ Dependencies' + collapse-after: 8 + labels: + - 'dependencies' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'minor' + patch: + labels: + - 'patch' + default: patch +template: | + ## Changes + + $CHANGES +# See https://github.com/release-drafter/release-drafter#autolabeler +# This is more like a reference, since auto-labelling PRs seems to require too much privileges +autolabeler: + - label: 'dependencies' + files: + - 'gradle-wrapper.properties' + title: + - '/^fix\(deps\)/i' + - '/^chore:\s*bump/i' + - label: 'chore' + files: + - '*gradle*' + branch: + - '/docs{0,1}\/.+/' + title: + - '/^chore/i' + - label: 'documentation' + files: + - '*.md' + - 'docs/**' + - label: 'bug' + branch: + - '/fix\/.+/' + title: + - '/^fix/i' + - label: 'enhancement' + branch: + - '/feature\/.+/' + title: + - '/^feat/i' diff --git a/.github/workflows/gradle-dependency-submit.yaml b/.github/workflows/gradle-dependency-submit.yaml new file mode 100644 index 00000000000..45ff462e8bd --- /dev/null +++ b/.github/workflows/gradle-dependency-submit.yaml @@ -0,0 +1,31 @@ +name: Dependency Submission + +# See https://github.com/gradle/actions/blob/768a17f3488dc3fe0155ff431553e1f53d57e22e/dependency-submission/README.md#the-dependency-submission-action +# The action allows GitHub to alert about reported vulnerabilities in the project +on: + push: + branches: + - master + +# Declare default permissions as read-only. +permissions: read-all + +jobs: + dependency-submission: + name: Submit dependencies + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Set up JDK 21 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 + with: + distribution: zulu + java-version: 21 + server-id: central + - name: Generate and submit dependency graph + uses: gradle/actions/dependency-submission@0723195856401067f7a2779048b490ace7a47d7c # v5 diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 405a2b30659..78ee9d201e9 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -6,5 +6,5 @@ jobs: name: "Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: gradle/wrapper-validation-action@v1 + - uses: actions/checkout@v6 + - uses: gradle/actions/wrapper-validation@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4bc32698f00..4a44114626c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,58 +10,100 @@ on: # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/software-installed-on-github-hosted-runners +concurrency: + # On master/release, we don't want any jobs cancelled so the sha is used to name the group + # On PR branches, we cancel the job if new commits are pushed + # More info: https://stackoverflow.com/a/68422069/253468 + group: ${{ (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/release' ) && format('ci-main-{0}', github.sha) || format('ci-main-{0}', github.ref) }} + cancel-in-progress: true + jobs: - windows: - name: 'Windows (JDK 14)' - runs-on: windows-latest + matrix_prep: + name: Matrix Preparation + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + env: + # Number of jobs to generate in matrix.js + MATRIX_JOBS: 4 steps: - - uses: actions/checkout@v1.1.0 - with: - fetch-depth: 50 - - name: 'Set up JDK 14' - uses: actions/setup-java@v1 - with: - java-version: 14 - - uses: burrunan/gradle-cache-action@v1 - name: Test - with: - job-id: jdk14 - multi-cache-enabled: false - # An explicit skip for Sha512 tasks is required due to https://github.com/gradle/gradle/issues/16789 - arguments: --scan --no-parallel build -x distTar -x distTarSource -x distTarSha512 -x distTarSourceSha512 + - uses: actions/checkout@v6 + - id: set-matrix + run: | + npm ci --prefix .github/workflows + node .github/workflows/matrix.mjs - mac: - name: 'macOS (JDK 14)' - runs-on: macos-latest + test: + needs: matrix_prep + name: '${{ matrix.name }}' + runs-on: ${{ matrix.os }} + env: + TZ: ${{ matrix.tz }} + strategy: + matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}} + fail-fast: false + # max-parallel: 4 steps: - - uses: actions/checkout@v1.1.0 + - uses: actions/checkout@v6 with: fetch-depth: 50 - - name: 'Set up JDK 14' - uses: actions/setup-java@v1 + - name: Set up Java ${{ matrix.java_version }}, oracle + if: ${{ matrix.oracle_java_website != '' }} + uses: oracle-actions/setup-java@fff43251af9936a0e6a4d5d0946e14f1680e9b6b # v1.5.0 + with: + website: ${{ matrix.oracle_java_website }} + release: ${{ matrix.java_version }} + - name: Set up Java 21 and ${{ matrix.non_ea_java_version }}, ${{ matrix.java_distribution }} + uses: actions/setup-java@v5 + with: + # The latest one will be the default, so we use Java 21 for launching Gradle + java-version: | + ${{ matrix.non_ea_java_version }} + 21 + distribution: ${{ matrix.java_distribution }} + architecture: x64 + - name: Steps to reproduce + uses: actions/github-script@v8 with: - java-version: 14 - - uses: burrunan/gradle-cache-action@v1 + script: | + console.log('The following command might help reproducing CI results, use Java ${{ matrix.java_version }}') + console.log('TZ="${{ matrix.tz }}" _JAVA_OPTIONS="${{ matrix.extraJvmArgs }}" ./gradlew build -x distTar -x distTarSource -x distTarSha512 -x distTarSourceSha512 ${{ matrix.extraGradleArgs }} -PtestExtraJvmArgs="${{ matrix.testExtraJvmArgs }}" -PtestDisableCaching="${{ matrix.testDisableCaching }}"') + - uses: burrunan/gradle-cache-action@v3 name: Test with: - job-id: jdk14 + job-id: jdk${{ matrix.java_version }} multi-cache-enabled: false - arguments: --scan --no-parallel build -x distTar -x distTarSource -x distTarSha512 -x distTarSourceSha512 -Dskip.test_TestDNSCacheManager.testWithCustomResolverAnd1Server=true + # An explicit skip for Sha512 tasks is required due to https://github.com/gradle/gradle/issues/16789 + arguments: --scan --no-parallel build -x distTar -x distTarSource -x distTarSha512 -x distTarSourceSha512 ${{ matrix.extraGradleArgs }} + properties: | + testExtraJvmArgs=${{ matrix.testExtraJvmArgs }} + testDisableCaching=${{ matrix.testDisableCaching }} + jdkBuildVersion=21 + jdkTestVersion=${{ matrix.java_version }} + jdkTestVendor=${{ matrix.java_vendor }} + # We have a separate job with Errorprone verifications, so avoid duplicate warnings + enableErrorprone=false + # We provision JDKs with GitHub Actions for caching purposes, so Gradle should rather fail in case JDK is not found + org.gradle.java.installations.auto-download=false + env: + _JAVA_OPTIONS: ${{ matrix.extraJvmArgs }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} errorprone: - name: 'Error Prone (JDK 11)' + name: 'Error Prone (JDK 21)' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 50 - - name: 'Set up JDK 11' - uses: actions/setup-java@v1 + - uses: actions/checkout@v6 + - name: 'Set up JDK 21' + uses: actions/setup-java@v5 with: - java-version: 11 - - uses: burrunan/gradle-cache-action@v1 + java-version: 21 + distribution: 'zulu' + - uses: burrunan/gradle-cache-action@v3 name: Test with: job-id: errprone multi-cache-enabled: false - arguments: --scan --no-parallel --no-daemon -PenableErrorprone classes + arguments: --scan --no-parallel --no-daemon classes + env: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} diff --git a/.github/workflows/matrix.mjs b/.github/workflows/matrix.mjs new file mode 100644 index 00000000000..fa4f79ca9db --- /dev/null +++ b/.github/workflows/matrix.mjs @@ -0,0 +1,170 @@ +// The script generates a random subset of valid jdk, os, timezone, and other axes. +// You can preview the results by running "node matrix.mjs" +// See https://github.com/vlsi/github-actions-random-matrix +import { appendFileSync } from 'fs'; +import { EOL } from 'os'; +import { createGitHubMatrixBuilder } from '@vlsi/github-actions-random-matrix/github'; +const { matrix, random } = createGitHubMatrixBuilder(); +matrix.addAxis({ + name: 'java_distribution', + values: [ + {value: 'corretto', vendor: 'amazon', weight: 1}, + {value: 'liberica', vendor: 'bellsoft', weight: 1}, + {value: 'microsoft', vendor: 'microsoft', weight: 1}, + {value: 'oracle', vendor: 'oracle', weight: 1}, + // There are issues running Semeru JDK with Gradle 8.5 + // See https://github.com/gradle/gradle/issues/27273 + // {value: 'semeru', vendor: 'ibm', weight: 4}, + {value: 'temurin', vendor: 'eclipse', weight: 1}, + {value: 'zulu', vendor: 'azul', weight: 1}, + ] +}); + +const eaJava = '22'; + +matrix.addAxis({ + name: 'java_version', + // Strings allow versions like 18-ea + values: [ + '17', + '21', + '25', + eaJava, + ] +}); + +matrix.addAxis({ + name: 'tz', + values: [ + 'America/New_York', + 'Pacific/Chatham', + 'UTC' + ] +}); + +matrix.addAxis({ + name: 'os', + title: x => x.replace('-latest', ''), + values: [ + // TODO: X11 is not available. Un-comment when https://github.com/burrunan/gradle-cache-action/issues/48 is resolved + // 'ubuntu-latest', + 'windows-latest', + 'macos-latest' + ] +}); + +// Test cases when Object#hashCode produces the same results +// It allows capturing cases when the code uses hashCode as a unique identifier +matrix.addAxis({ + name: 'hash', + values: [ + {value: 'regular', title: '', weight: 42}, + {value: 'same', title: 'same hashcode', weight: 1} + ] +}); +matrix.addAxis({ + name: 'locale', + title: x => x.language + '_' + x.country, + values: [ + {language: 'de', country: 'DE'}, + {language: 'fr', country: 'FR'}, + // TODO: fix :src:dist-check:batchBUG_62847 + // Fails with "ERROR o.a.j.u.JMeterUtils: Could not find resources for 'ru_EN'" + // {language: 'ru', country: 'RU'}, + {language: 'tr', country: 'TR'}, + ] +}); + +matrix.setNamePattern(['java_version', 'java_distribution', 'hash', 'os', 'tz', 'locale']); + +// Semeru uses OpenJ9 jit which has no option for making hash codes the same +matrix.exclude({java_distribution: {value: 'semeru'}, hash: {value: 'same'}}); +// MacOS and Oracle Java does not work currently. No JAVA_HOME_${VERSION}_x64 set and thus no java found +matrix.exclude({os: 'macos-latest', java_distribution: {value: 'oracle'}}) +// Ignore builds with JAVA EA for now, see https://github.com/apache/jmeter/issues/6114 +matrix.exclude({java_version: eaJava}) +matrix.imply({java_version: eaJava}, {java_distribution: {value: 'oracle'}}) +// Oracle JDK is only supported for JDK 21 and later +matrix.imply({java_distribution: {value: 'oracle'}}, {java_version: v => v === eaJava || v >= 21}); +// TODO: Semeru does not ship Java 21 builds yet +matrix.exclude({java_distribution: {value: 'semeru'}, java_version: '21'}); +// Ensure at least one job with "same" hashcode exists +matrix.generateRow({hash: {value: 'same'}}); +// Ensure at least one Windows and at least one Linux job is present (macOS is almost the same as Linux) +matrix.generateRow({os: 'windows-latest'}); +// TODO: un-comment when xvfb will be possible +// matrix.generateRow({os: 'ubuntu-latest'}); +// Ensure there will be at least one job with Java 17 +matrix.generateRow({java_version: "17"}); +// Ensure there will be at least one job with Java 25 +matrix.generateRow({java_version: "25"}); +// Ensure there will be at least one job with Java EA +// matrix.generateRow({java_version: eaJava}); +const include = matrix.generateRows(process.env.MATRIX_JOBS || 5); +if (include.length === 0) { + throw new Error('Matrix list is empty'); +} +include.sort((a, b) => a.name.localeCompare(b.name, undefined, {numeric: true})); +include.forEach(v => { + // Pass locale via Gradle arguments in case it won't be inherited from _JAVA_OPTIONS + // In fact, _JAVA_OPTIONS is non-standard and might be ignored by some JVMs + let gradleArgs = [ + `-Duser.country=${v.locale.country}`, + `-Duser.language=${v.locale.language}`, + ]; + v.extraGradleArgs = gradleArgs.join(' '); +}); +include.forEach(v => { + let jvmArgs = []; + // Extra JVM arguments passed to test execution + let testJvmArgs = []; + if (v.hash.value === 'same') { + testJvmArgs.push('-XX:+UnlockExperimentalVMOptions', '-XX:hashCode=2'); + } + // Gradle does not work in tr_TR locale, so pass locale to test only: https://github.com/gradle/gradle/issues/17361 + jvmArgs.push(`-Duser.country=${v.locale.country}`); + jvmArgs.push(`-Duser.language=${v.locale.language}`); + v.java_distribution = v.java_distribution.value; + v.java_vendor = v.java_distribution.vendor; + if (v.java_distribution === 'oracle') { + v.oracle_java_website = v.java_version === eaJava ? 'jdk.java.net' : 'oracle.com'; + } + v.non_ea_java_version = v.java_version === eaJava ? '' : v.java_version; + if (v.java_distribution !== 'semeru' && random() > 0.5) { + // The following options randomize instruction selection in JIT compiler + // so it might reveal missing synchronization + v.name += ', stress JIT'; + v.testDisableCaching = 'JIT randomization should not be cached'; + jvmArgs.push('-XX:+UnlockDiagnosticVMOptions'); + if (v.java_version >= 8) { + // Randomize instruction scheduling in GCM + // share/opto/c2_globals.hpp + jvmArgs.push('-XX:+StressGCM'); + // Randomize instruction scheduling in LCM + // share/opto/c2_globals.hpp + jvmArgs.push('-XX:+StressLCM'); + } + if (v.java_version >= 16) { + // Randomize worklist traversal in IGVN + // share/opto/c2_globals.hpp + jvmArgs.push('-XX:+StressIGVN'); + } + if (v.java_version >= 17) { + // Randomize worklist traversal in CCP + // share/opto/c2_globals.hpp + jvmArgs.push('-XX:+StressCCP'); + } + } + v.extraJvmArgs = jvmArgs.join(' '); + v.testExtraJvmArgs = testJvmArgs.join(' ::: '); + delete v.hash; +}); + +console.log(include); + +let filePath = process.env['GITHUB_OUTPUT'] || ''; +if (filePath) { + appendFileSync(filePath, `matrix<=16" + } + } + } +} diff --git a/.github/workflows/package.json b/.github/workflows/package.json new file mode 100644 index 00000000000..a66b1aa6f43 --- /dev/null +++ b/.github/workflows/package.json @@ -0,0 +1,7 @@ +{ + "private": true, + "type": "module", + "dependencies": { + "@vlsi/github-actions-random-matrix": "2.0.0" + } +} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 00000000000..0ffcc9b1bdd --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,53 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + - 'release/**' + # pull_request_target allows PR from forks to access secrets, so please NEVER add pull_request_target + +# Declare default permissions as read-only. +permissions: read-all + +jobs: + update_release_draft: + # Skip release drafts in forks + if: vars.RUN_RELEASE_DRAFTER == 'true' + name: Update Release Draft + runs-on: ubuntu-latest + permissions: + # write permission is required to create a github release + contents: write + steps: + - name: Get the current version + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + id: current_version + with: + # language=javascript + script: | + const response = await github.rest.repos.getContent({ + owner: context.repo.owner, + repo: context.repo.repo, + path: 'gradle.properties', + ref: context.sha + }); + const content = Buffer.from(response.data.content, 'base64').toString(); + const version = content.match(/^jmeter\.version=(.+)$/m)[1]; + console.log(`Version is ${version}`); + return version; + + # Drafts your next Release notes as Pull Requests are merged into "master" + - name: Update release body draft + uses: release-drafter/release-drafter@6a93d829887aa2e0748befe2e808c66c0ec6e4c7 # v6 + id: prepare_release + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + with: + # config-name: my-config.yml + disable-autolabeler: true + publish: false + latest: ${{ github.ref_name == github.event.repository.default_branch }} + version: ${{ steps.current_version.outputs.result }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 21abad60e4b..31dc34b4b3d 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,13 @@ /src/protocol/*/build/ /src/protocol/*/bin/ /src/protocol/*/out/ +# This folder is generated by running one of the tests (HTML report?), so ignore it for now +# See https://github.com/apache/jmeter/issues/5762 +/src/dist-check/temp/ /dist/ /docs/ /local/ +# We no longer use printable_docs folder, however, keep it here so everybody else do not acidentally commit it /printable_docs/ /reports/ /site/ @@ -29,6 +33,9 @@ # Ignore Gradle project-specific cache directory .gradle +# burrunan/gradle-cache-action creates this folder, so ignore it until the folder moved to another location +/.cache-proxy + # macOS .DS_Store @@ -77,6 +84,10 @@ jmeter-fb.* *.iml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +node_modules hs_err_pid* # other jvm related files .attach_* + +# npm/node dependencies and generated web assets +/xdocs/node_modules/ diff --git a/.ratignore b/.ratignore index 4f0ca3e960a..cb5de4b3768 100644 --- a/.ratignore +++ b/.ratignore @@ -1,7 +1,7 @@ -checksum.xml -buildSrc/checksum.xml gradle/wrapper/gradle-wrapper.jar -.* +gradle/verification-keyring.keys +gradle/verification-metadata.xml +**/.* .*/** CODE_OF_CONDUCT.md CONTRIBUTING.md @@ -10,6 +10,7 @@ gradle.md ISSUE_TEMPLATE.md PULL_REQUEST_TEMPLATE.md README.md +renovate.json **/*.jmx bin/examples/** bin/report-output/** @@ -25,7 +26,6 @@ lib/aareadme.txt lib/opt/README.txt src/licenses/licenses/*/CC0-1.0.txt #local/** -#printable_docs/** #reports/** src/launcher/src/main/resources/org/apache/jmeter/jmeter_as_ascii_art.txt src/core/src/main/resources/org/apache/jmeter/help.txt @@ -35,6 +35,10 @@ test/resources/** #**/*.log **/download_jmeter.cgi xdocs/extending/HTML_REPORT_README.TXT +xdocs/node_modules/** +xdocs/package.json +xdocs/package-lock.json +xdocs/yarn.lock # Rat should automatically detect below files as binary, however it fails **/*.sxi **/*.sxw diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a299afa596d..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,99 +0,0 @@ -language: java - -# skip default "install" command -install: true - -# We can clean the caches via web at https://travis-ci.org/apache/jmeter/caches -before_cache: - - F=CleanupGradleCache sh -x -c 'curl -O https://raw.githubusercontent.com/vlsi/cleanup-gradle-cache/v1.x/$F.java && javac -J-Xmx128m $F.java && java -Xmx128m $F' - - rm -rf $HOME/.m2/repository/org/apache/jmeter - -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ - - $HOME/.m2/repository - -env: - global: - - SKIP_TAR="-x distTar -x distTarSource -x distTarSha512 -x distTarSourceSha512" - - ORG_GRADLE_PROJECT_checksumFailOn=build_finish - - ORG_GRADLE_PROJECT_checksumPrint=true - -matrix: - allow_failures: - # j-m-p does not seem to download all the dependencies: https://github.com/jmeter-maven-plugin/jmeter-maven-plugin/issues/187 - - name: jmeter-maven-plugin tests - - name: jmeter-maven-plugin tests on s390x - - name: Tests with OpenJDK 11 on s390x - include: - - name: Tests with OpenJDK 8 + code coverage - jdk: openjdk8 - script: - - xvfb-run ./gradlew build jacocoReport $SKIP_TAR - after_success: - - bash <(curl -s https://codecov.io/bash) - - name: Tests with OpenJDK 11 - jdk: openjdk11 - addons: - apt: - packages: - - language-pack-fr - env: - - TZ=Pacific/Chatham # flips between +12:45 and +13:45 - - LANG=fr_FR.UTF-8 - - LC_ALL=fr_FR.UTF-8 - script: - # This job verifies headless mode to ensure Apache JMeter is workable in headless as well - # Spotless and Checkstyle are skipped here to save some time. They are verified anyway in Java 8 and Java 13 builds, so skipping them for Java 11 does not harm - - ./gradlew build -Djava.awt.headless=true -Duser.language=fr -Duser.country=FR -PskipCheckstyle -PskipSpotless $SKIP_TAR - - name: Tests with OpenJDK 11 on s390x - os: linux - arch: s390x - dist: bionic - jdk: openjdk11 - addons: - apt: - packages: - - language-pack-fr - script: - - sudo apt-get install -y openjdk-11-jdk - - export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-s390x/ - - export PATH=$JAVA_HOME/bin:$PATH - - ./gradlew build -Djava.awt.headless=true -PskipCheckstyle -PskipSpotless $SKIP_TAR - # Java 12 is not here because it has been superceeded by Java 13 - # Tests with Java 12 do not surface much new, so Java 11 (LTS) and Java 13 (non-LTS) are enough for "post Java 9" testing - - name: Tests with OpenJDK 14 - jdk: openjdk14 - addons: - apt: - packages: - - language-pack-fr - env: - - TZ=America/New_York # flips between −05:00 and −04:00 - - LANG=fr_FR.UTF-8 - - LC_ALL=fr_FR.UTF-8 - script: - # Spotless, Checkstyle, and JaCoCo are verified here to ensure they all work with the latest supported Java - - xvfb-run ./gradlew build jacocoReport -Duser.language=fr -Duser.country=FR $SKIP_TAR - - name: jmeter-maven-plugin tests - jdk: openjdk8 - script: - - ./gradlew -PskipJavadoc publishToMavenLocal -Pjmeter.version=42.0 -PchecksumIgnore - - cd .. - - git clone --depth 100 https://github.com/jmeter-maven-plugin/jmeter-maven-plugin.git - - cd jmeter-maven-plugin - - mvn verify -Djmeter.version=42.0-SNAPSHOT - - name: jmeter-maven-plugin tests on s390x - os: linux - arch: s390x - jdk: openjdk11 - script: - - wget http://www.eu.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz - - tar -xvzf apache-maven-3.6.3-bin.tar.gz - - export PATH=`pwd`/apache-maven-3.6.3/bin/:$PATH - - ./gradlew -PskipJavadoc publishToMavenLocal -Pjmeter.version=42.0 -PchecksumIgnore - - cd .. - - git clone --depth 100 https://github.com/jmeter-maven-plugin/jmeter-maven-plugin.git - - cd jmeter-maven-plugin - - mvn verify -Djmeter.version=42.0-SNAPSHOT diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 14a1c8ce40e..94ac90745a9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,16 +4,17 @@ Want to show Apache JMeter some love? Help out by contributing! ## :beetle: Found a bug -Log it in our bugzilla: +Log it in GitHub issues: + +* https://github.com/apache/jmeter/issues +* or send a note to the [user mailing list](https://jmeter.apache.org/mail2.html#JMeterUser). -* ** -* or send a note to the *user mailing list*. Be sure to include all relevant information, like the versions of JMeter you’re using as long as Java version. A Test plan that caused the issue as well as any error messages are also very helpful. ## :question: Need help -Simply contact: +Contact: * [Our users mailing list](https://jmeter.apache.org/mail2.html#JMeterUser) * or ask question on [stackoverflow](https://stackoverflow.com/questions/tagged/jmeter). @@ -22,8 +23,8 @@ Simply contact: See: -* [Open bug entries for JMeter](https://bz.apache.org/bugzilla/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=NEEDINFO&bug_severity=Blocker&bug_severity=Critical&bug_severity=Major&bug_severity=Normal&bug_severity=Regression&bug_severity=Minor&bug_severity=Trivial&product=JMeter&order=Bug%20Number&list_id=164231) -* [Enhancement requests for JMeter](https://bz.apache.org/bugzilla/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=NEEDINFO&bug_severity=Enhancement&product=JMeter&order=Bug%20Number&list_id=164232) +* [Open issues for JMeter](https://github.com/apache/jmeter/issues) +* [Enhancement requests for JMeter](https://github.com/apache/jmeter/issues?q=is%3Aopen+label%3Aenhancement) ## Development setup @@ -52,9 +53,8 @@ Optionally you can generate an Eclipse project by running The steps to import the sources (based on Eclipse 2019-06) into Eclipse are as follows: 1. Install `Eclipse IDE for Java Developers` -1. Install the Groovy Eclipse plugin and select Groovy Compiler 2.4 (some tests are written in Groovy) -1. Install `Kotlin for Eclipse` plugin (builds scripts are written in Kotlin) -1. Make sure you have a Java 8 compatible JDK configured in your workspace +1. Install `Kotlin for Eclipse` plugin (JMeter code uses Java and Kotlin) +1. Make sure you have a Java 17 compatible JDK configured in your workspace 1. Open `File->Import...` 1. Select `Existing Gradle Project` and click `Next` 1. Read `How to experience the best Gradle integration` and click `Next` @@ -66,7 +66,7 @@ The best way to make sure your issue or feature is addressed is to submit a patc We accept patches through: * pull requests -* patch attached to bugzilla. +* patch attached to [JMeter developers mailing list](https://jmeter.apache.org/mail2.html#JMeterDev). However, before sending a patch, please make sure that the following applies: diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index d24c0af1d5f..00000000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,15 +0,0 @@ -# Reporting an issue: - -- Mention JVM implementation (OpenJDK, Oracle JDK, ...), versions of Java, Apache JMeter -- Provide anonymized and as simple as possible test plan helping reproduce the issue -- Provide jmeter.log -- If it's a bug, explain clearly how to reproduce: - - What should happen (OK Case) - - What happens (KO Case) -- If it's an enhancement request, explain what you want, why you need it and the clear use case -- Answer to questions of the person who handles your case - -Issue are related to bug or enhancements, it is not the right place to ask questions about usage, for the latter: - -- Read the [User manual](https://jmeter.apache.org/usermanual/index.html) and/or [Reference documentation](https://jmeter.apache.org/usermanual/component_reference.html) -- Ask questions on the [user mailing list](https://jmeter.apache.org/mail2.html). *Note you need to subscribe first* diff --git a/NOTICE b/NOTICE index 0f5314e48c8..75b927c8e74 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Apache JMeter -Copyright 1998-2021 The Apache Software Foundation +Copyright 1998-2024 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/README.md b/README.md index a5703ea1cce..f844e232837 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ By The Apache Software Foundation [![codecov](https://codecov.io/gh/apache/jmeter/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/jmeter) [![License](https://img.shields.io/:license-apache-brightgreen.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![Stack Overflow](https://img.shields.io/:stack%20overflow-jmeter-brightgreen.svg)](https://stackoverflow.com/questions/tagged/jmeter) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.jmeter/ApacheJMeter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.jmeter/ApacheJMeter) +[![Maven Central](https://img.shields.io/maven-central/v/org.apache.jmeter/ApacheJMeter.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.apache.jmeter/ApacheJMeter) [![Javadocs](https://www.javadoc.io/badge/org.apache.jmeter/ApacheJMeter_core.svg)](https://www.javadoc.io/doc/org.apache.jmeter/ApacheJMeter_core) [![Twitter](https://img.shields.io/twitter/url/https/github.com/apache/jmeter.svg?style=social)](https://twitter.com/intent/tweet?text=Powerful%20load%20testing%20with%20Apache%20JMeter:&url=https://jmeter.apache.org) @@ -92,7 +92,7 @@ The following requirements exist for running Apache JMeter: - Java Interpreter: - A fully compliant Java 8 Runtime Environment is required + A fully compliant Java 17 Runtime Environment is required for Apache JMeter to execute. A JDK with `keytool` utility is better suited for Recording HTTPS websites. @@ -136,8 +136,8 @@ a JMX file onto: ## Documentation The documentation available as of the date of this release is -also included, in HTML format, in the [printable_docs](printable_docs) directory, -and it may be browsed starting from the file called [index.html](printable_docs/index.html). +also included, in HTML format, in the [docs](docs) directory, +and it may be browsed starting from the file called [index.html](docs/index.html). ## Reporting a bug/enhancement @@ -175,7 +175,12 @@ systemProp.https.proxyPassword=your_password ### Test builds -JMeter is built using Gradle. +JMeter is built using Gradle, and it uses [Gradle's Toolchains for JVM projects](https://docs.gradle.org/current/userguide/toolchains.html) +for provisioning JDKs. It means the code would search for the needed JDKs locally, or download them +if they are not found. + +By default, the code would use JDK 17 for build purposes, however it would set the target release to 8, +so the resulting artifacts would be compatible with Java 8. The following command builds and tests JMeter: @@ -183,6 +188,15 @@ The following command builds and tests JMeter: ./gradlew build ``` +If you want to use a custom JDK for building you can set `-PjdkBuildVersion=11`, +and you can select `-PjdkTestVersion=21` if you want to use a different JDK for testing. + +You can list the available build parameters by executing + +```sh +./gradlew parameters +``` + If the system does not have a GUI display then: ```sh @@ -196,7 +210,7 @@ The following command would compile the application and enable you to run `jmete from the `bin` directory. > **Note** that it completely refreshes `lib/` contents, -so it would remove custom plugins should you have them installed. +so it would remove custom plugins should you have them installed to `lib/`. However, it would keep `lib/ext/` plugins intact. ```sh ./gradlew createDist @@ -266,3 +280,11 @@ Apache JMeter does not include any implementation of JSSE or JCE. ## Thanks **Thank you for using Apache JMeter.** + +### Third party notices + +* Notice for mxparser: + + > This product includes software developed by the Indiana + > University Extreme! Lab. For further information please visit + > http://www.extreme.indiana.edu/ diff --git a/bin/jmeter b/bin/jmeter index 055b2bafcbe..56550598ec8 100755 --- a/bin/jmeter +++ b/bin/jmeter @@ -115,18 +115,19 @@ if [ -z "$JAVA_HOME" ]; then JAVA_HOME="$JRE_HOME" fi -#--add-opens if JAVA 9 -JAVA9_OPTS= +# Module access for modern Java versions (required for JMeter components) +JAVA_OPTS="--add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens java.desktop/sun.swing=ALL-UNNAMED --add-opens java.desktop/javax.swing.text.html=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED --add-opens=java.desktop/sun.awt.shell=ALL-UNNAMED" # Minimal version to run JMeter -MINIMAL_VERSION=8 +MINIMAL_VERSION=17 -# Check if version is from OpenJDK or Oracle Hotspot JVM prior to 9 containing 1.${version}.x +# Check if version meets the minimal requirement CURRENT_VERSION=`"${JAVA_HOME}/bin/java" -version 2>&1 | awk -F'"' '/version/ {gsub("^1[.]", "", $2); gsub("[^0-9].*$", "", $2); print $2}'` -# Check if Java is present and the minimal version requirement -if [ "$CURRENT_VERSION" -gt "$MINIMAL_VERSION" ]; then - JAVA9_OPTS="--add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens java.desktop/sun.swing=ALL-UNNAMED --add-opens java.desktop/javax.swing.text.html=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED --add-opens=java.desktop/sun.awt.shell=ALL-UNNAMED" +# Check if Java is present and meets the minimal version requirement +if [ "$CURRENT_VERSION" -lt "$MINIMAL_VERSION" ]; then + echo "ERROR: Java version $CURRENT_VERSION is too low. JMeter requires Java $MINIMAL_VERSION or higher." + exit 1 fi : "${JMETER_OPTS:=""}" @@ -169,15 +170,19 @@ esac # Default to en_EN : "${JMETER_LANGUAGE:="-Duser.language=en -Duser.region=EN"}" -# Uncomment this to generate GC verbose file with Java prior to 9 -# VERBOSE_GC="-verbose:gc -Xloggc:gc_jmeter_%p.log -XX:+PrintGCDetails -XX:+PrintGCCause -XX:+PrintTenuringDistribution -XX:+PrintHeapAtGC -XX:+PrintGCApplicationConcurrentTime -XX:+PrintAdaptiveSizePolicy -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps" +# Legacy GC verbose options removed (Java 8/9 support discontinued) + +# Optimized GC logging for Java 17 with structured output and performance analysis +# Uncomment to enable comprehensive GC logging with rotation and detailed metrics +# VERBOSE_GC="-Xlog:gc,gc+heap,gc+regions,gc+refine,gc+phases:gc_jmeter_%p_%t.log:time,level,tags:filecount=5,filesize=50M" + +# Alternative: Minimal GC logging for production (uncomment if needed) +# VERBOSE_GC="-Xlog:gc:gc_jmeter_%p.log:time" -# Uncomment this to generate GC verbose file with Java 9 and above -# VERBOSE_GC="-Xlog:gc*,gc+age=trace,gc+heap=debug:file=gc_jmeter_%p.log" +# Docker support for Java 17+ +# Modern container memory detection is automatic in Java 17+ +# RUN_IN_DOCKER="-XX:+UseContainerSupport" -# Uncomment this if you run JMeter in DOCKER (need Java SE 8u131 or JDK 9) -# see https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits -# RUN_IN_DOCKER="-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap" # Finally, some tracing to help in case things go astray: # You may want to add those settings: @@ -191,7 +196,7 @@ SYSTEM_PROPS="-Djava.security.egd=file:/dev/urandom" SERVER="-server" if [ -z "${JMETER_COMPLETE_ARGS}" ]; then - ARGS="$JAVA9_OPTS $SERVER $DUMP $HEAP $VERBOSE_GC $GC_ALGO $SYSTEM_PROPS $JMETER_LANGUAGE $RUN_IN_DOCKER" + ARGS="$JAVA_OPTS $SERVER $DUMP $HEAP $VERBOSE_GC $GC_ALGO $SYSTEM_PROPS $JMETER_LANGUAGE $RUN_IN_DOCKER" else ARGS="" fi diff --git a/bin/jmeter.bat b/bin/jmeter.bat index e39153dab5b..7a6dae72b3c 100644 --- a/bin/jmeter.bat +++ b/bin/jmeter.bat @@ -78,12 +78,19 @@ if not defined JMETER_LANGUAGE ( ) rem Minimal version to run JMeter -set MINIMAL_VERSION=1.8.0 +set MINIMAL_VERSION=17.0.0 -rem --add-opens if JAVA 9 -set JAVA9_OPTS= +rem Optimized GC logging for Java 17 with structured output and performance analysis +rem Uncomment to enable comprehensive GC logging with rotation and detailed metrics +rem set VERBOSE_GC=-Xlog:gc,gc+heap,gc+regions,gc+refine,gc+phases:gc_jmeter_%%p_%%t.log:time,level,tags:filecount=5,filesize=50M +rem Alternative: Minimal GC logging for production (uncomment if needed) +rem set VERBOSE_GC=-Xlog:gc:gc_jmeter_%%p.log:time + + +rem Module access for modern Java versions (required for JMeter components) +set JAVA_OPTS=--add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens java.desktop/sun.swing=ALL-UNNAMED --add-opens java.desktop/javax.swing.text.html=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/sun.awt.shell=ALL-UNNAMED for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do ( rem @echo Debug Output: %%g @@ -95,36 +102,24 @@ if not defined JAVAVER ( goto pause ) - - -rem Check if version is from OpenJDK or Oracle Hotspot JVM prior to 9 containing 1.${version}.x -rem JAVAVER will be equal to "9.0.4" (quotes are part of the value) for Oracle Java 9 -rem JAVAVER will be equal to "1.8.0_161" (quotes are part of the value) for Oracle Java 8 -rem so we extract 2 chars starting from index 1 -IF "%JAVAVER:~1,2%"=="1." ( - set JAVAVER=%JAVAVER:"=% - for /f "delims=. tokens=1-3" %%v in ("%JAVAVER%") do ( - set current_minor=%%w +rem Extract major version number from Java version string +for /f "delims=. tokens=1" %%v in ("%JAVAVER:~1,-1%") do ( + set current_major=%%v ) -) else ( - rem Java 9 at least - set current_minor=9 - set JAVA9_OPTS=--add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens java.desktop/sun.swing=ALL-UNNAMED --add-opens java.desktop/javax.swing.text.html=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/sun.awt.shell=ALL-UNNAMED -) - -for /f "delims=. tokens=1-3" %%v in ("%MINIMAL_VERSION%") do ( - set minimal_minor=%%w +rem Extract minimal major version +for /f "delims=. tokens=1" %%v in ("%MINIMAL_VERSION%") do ( + set minimal_major=%%v ) -if not defined current_minor ( +if not defined current_major ( @echo Not able to find Java executable or version. Please check your Java installation. set ERRORLEVEL=2 goto pause ) -rem @echo Debug: CURRENT=%current_minor% - MINIMAL=%minimal_minor% -if %current_minor% LSS %minimal_minor% ( - @echo Error: Java version -- %JAVAVER% -- is too low to run JMeter. Needs a Java version greater than or equal to %MINIMAL_VERSION% + +if %current_major% LSS %minimal_major% ( + @echo Error: Java version -- %JAVAVER% -- is too low to run JMeter. Needs Java %MINIMAL_VERSION% or higher. set ERRORLEVEL=3 goto pause ) @@ -151,13 +146,7 @@ if not defined HEAP ( set HEAP=-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m ) -rem Uncomment this to generate GC verbose file with Java prior to 9 -rem set VERBOSE_GC=-verbose:gc -Xloggc:gc_jmeter_%%p.log -XX:+PrintGCDetails -XX:+PrintGCCause -XX:+PrintTenuringDistribution -XX:+PrintHeapAtGC -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintAdaptiveSizePolicy - -rem Uncomment this to generate GC verbose file with Java 9 and above -rem set VERBOSE_GC=-Xlog:gc*,gc+age=trace,gc+heap=debug:file=gc_jmeter_%%p.log -rem You may want to add those settings -rem -XX:+ParallelRefProcEnabled -XX:+PerfDisableSharedMem +rem Legacy GC verbose options removed (Java 8/9 support discontinued) if not defined GC_ALGO ( set GC_ALGO=-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1ReservePercent=20 ) @@ -167,9 +156,9 @@ set SYSTEM_PROPS=-Djava.security.egd=file:/dev/urandom rem Always dump on OOM (does not cost anything unless triggered) set DUMP=-XX:+HeapDumpOnOutOfMemoryError -rem Uncomment this if you run JMeter in DOCKER (need Java SE 8u131 or JDK 9) -rem see https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits -rem set RUN_IN_DOCKER=-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap +rem Docker support for Java 17+ +rem Modern container memory detection is automatic in Java 17+ +rem set RUN_IN_DOCKER=-XX:+UseContainerSupport rem Additional settings that might help improve GUI performance on some platforms rem See: http://www.oracle.com/technetwork/java/perf-graphics-135933.html @@ -188,7 +177,7 @@ if not defined DDRAW ( rem Collect the settings defined above if not defined JMETER_COMPLETE_ARGS ( - set ARGS=%JAVA9_OPTS% %DUMP% %HEAP% %VERBOSE_GC% %GC_ALGO% %DDRAW% %SYSTEM_PROPS% %JMETER_LANGUAGE% %RUN_IN_DOCKER% + set ARGS=%JAVA_OPTS% %DUMP% %HEAP% %VERBOSE_GC% %GC_ALGO% %DDRAW% %SYSTEM_PROPS% %JMETER_LANGUAGE% %RUN_IN_DOCKER% ) else ( set ARGS= ) diff --git a/bin/jmeter.properties b/bin/jmeter.properties index 4953cbd9ad8..dd4dd7eaacd 100644 --- a/bin/jmeter.properties +++ b/bin/jmeter.properties @@ -33,7 +33,7 @@ # JMeter properties are described in the file # http://jmeter.apache.org/usermanual/properties_reference.html # A local copy can be found in -# printable_docs/usermanual/properties_reference.html +# docs/usermanual/properties_reference.html #Preferred GUI language. Comment out to use the JVM default locale's language. #language=en @@ -202,9 +202,9 @@ #Components to not display in JMeter GUI (GUI class name or static label) # These elements are deprecated and will be removed in next version: -# MongoDB Script, MongoDB Source Config, Monitor Results +# Monitor Results # BSF Elements -not_in_menu=org.apache.jmeter.protocol.mongodb.sampler.MongoScriptSampler,org.apache.jmeter.protocol.mongodb.config.MongoSourceElement,\ +not_in_menu=\ org.apache.jmeter.timers.BSFTimer,org.apache.jmeter.modifiers.BSFPreProcessor,org.apache.jmeter.extractor.BSFPostProcessor,org.apache.jmeter.assertions.BSFAssertion,\ org.apache.jmeter.visualizers.BSFListener,org.apache.jmeter.protocol.java.sampler.BSFSampler,\ org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui @@ -403,6 +403,10 @@ remote_hosts=127.0.0.1 # for SPNEGO authentication #kerberos.spnego.strip_port=true +# Should the host name for constructing SPN be canonicalized +# for SPNEGO authentication +#kerberos.spnego.use_canonical_host_name=true + # Should credentials be delegated to webservers when using # SPNEGO authentication #kerberos.spnego.delegate_cred=false @@ -803,7 +807,7 @@ wmlParser.types=text/vnd.wap.wml # Database validation query # based in https://stackoverflow.com/questions/10684244/dbcp-validationquery-for-different-databases list jdbc.config.check.query=select 1 from INFORMATION_SCHEMA.SYSTEM_USERS|select 1 from dual|select 1 from sysibm.sysdummy1|select 1|select 1 from rdb$database -jdbc.config.jdbc.driver.class=com.mysql.jdbc.Driver|org.postgresql.Driver|oracle.jdbc.OracleDriver|com.ingres.jdbc.IngresDriver|com.microsoft.sqlserver.jdbc.SQLServerDriver|com.microsoft.jdbc.sqlserver.SQLServerDriver|org.apache.derby.jdbc.ClientDriver|org.hsqldb.jdbc.JDBCDriver|com.ibm.db2.jcc.DB2Driver|org.apache.derby.jdbc.ClientDriver|org.h2.Driver|org.firebirdsql.jdbc.FBDriver|org.mariadb.jdbc.Driver|org.sqlite.JDBC|net.sourceforge.jtds.jdbc.Driver|com.exasol.jdbc.EXADriver +jdbc.config.jdbc.driver.class=com.mysql.cj.jdbc.Driver|com.mysql.jdbc.Driver|org.postgresql.Driver|oracle.jdbc.OracleDriver|com.ingres.jdbc.IngresDriver|com.microsoft.sqlserver.jdbc.SQLServerDriver|com.microsoft.jdbc.sqlserver.SQLServerDriver|org.apache.derby.jdbc.ClientDriver|org.hsqldb.jdbc.JDBCDriver|com.ibm.db2.jcc.DB2Driver|org.apache.derby.jdbc.ClientDriver|org.h2.Driver|org.firebirdsql.jdbc.FBDriver|org.mariadb.jdbc.Driver|org.sqlite.JDBC|net.sourceforge.jtds.jdbc.Driver|com.exasol.jdbc.EXADriver #--------------------------------------------------------------------------- # OS Process Sampler configuration @@ -1051,6 +1055,13 @@ csvdataset.file.encoding_list=UTF-8|UTF-16|ISO-8859-15|US-ASCII # ORO PatternCacheLRU size #oro.patterncache.size=1000 +# Cache function execution during test execution +# By default, JMeter caches function properties, however, it might cause unexpected results +# when the component is shared across threads and the expression depends on the thread variables. +# The caching behaviour would likely change in the upcoming versions +# Deprecation notice: the setting will likely disappear, so if you need it, consider raising an issue with the use-case. +#function.cache.per.iteration=false + #TestBeanGui # #propertyEditorSearchPath=null @@ -1090,8 +1101,8 @@ csvdataset.file.encoding_list=UTF-8|UTF-16|ISO-8859-15|US-ASCII # List of extra HTTP methods that should be available in select box #httpsampler.user_defined_methods=VERSION-CONTROL,REPORT,CHECKOUT,CHECKIN,UNCHECKOUT,MKWORKSPACE,UPDATE,LABEL,MERGE,BASELINE-CONTROL,MKACTIVITY -# The encoding to be used if none is provided (default ISO-8859-1) -#sampleresult.default.encoding=ISO-8859-1 +# The encoding to be used if none is provided (default UTF-8 since JMeter 5.6.1) +#sampleresult.default.encoding=UTF-8 # CookieManager behaviour - should cookies with null/empty values be deleted? # Default is true. Use false to revert to original behaviour @@ -1123,6 +1134,14 @@ cookies=cookies # If you want to use Rhino on JDK8, set this property to true #javascript.use_rhino=false +# Ability to switch out the old Oro Regex implementation with the JDK built-in implementation +# Any value different to 'oro' will disable the Oro implementation and enable the JDK based. +#jmeter.regex.engine=oro + +# We assist the JDK based Regex implementation by caching Pattern objects. The size of the +# cache can be set with this setting. It can be disabled by setting it to '0'. +#jmeter.regex.patterncache.size=1000 + # Number of milliseconds to wait for a thread to stop #jmeterengine.threadstop.wait=5000 @@ -1142,7 +1161,7 @@ cookies=cookies # How long to pause (in ms) in the daemon thread before reporting that the JVM has failed to exit. # If the value is <= 0, the JMeter does not start the daemon thread -#jmeter.exit.check.pause=2000 +#jmeter.exit.check.pause=0 # If running non-GUI, then JMeter listens on the following port for a shutdown message. # To disable, set the port to 1000 or less. @@ -1176,6 +1195,18 @@ cookies=cookies # Set to 0 to disable the size check and display the whole response #view.results.tree.max_size=10485760 +# UI gets unresponsive when response contains very long lines, +# So we break lines by adding artificial line breaks +# The break is introduced somewhere in between soft_wrap_line_size..max_line_size +# We try to break on word boundaries first +#view.results.tree.max_line_size=110000 +#view.results.tree.soft_wrap_line_size=100000 + +# Even with the above setting the UI can be unresponsive on large contents in the text view, +# so we allow to switch to a simpler view mode, that is faster, but does not break lines. +# Can be switched off by setting it to -1 +#view.results.tree.simple_view_limit=10000 + # Order of Renderers in View Results Tree # Note full class names should be used for non JMeter core renderers # For JMeter core renderers, class names start with '.' and are automatically @@ -1190,6 +1221,9 @@ view.results.tree.renderers_order=.RenderAsText,.RenderAsRegexp,.RenderAsBoundar # Set to 0 to disable the size check #document.max_size=0 +# Configures the maximum document length for rendering with kerning enabled +#text.kerning.max_document_size=10000 + #JMS options # Enable the following property to stop JMS Point-to-Point Sampler from using # the properties java.naming.security.[principal|credentials] when creating the queue connection diff --git a/bin/jmeter.sh b/bin/jmeter.sh index e5cf8a7e0c9..94843d2915c 100755 --- a/bin/jmeter.sh +++ b/bin/jmeter.sh @@ -90,14 +90,17 @@ fi JAVA9_OPTS= # Minimal version to run JMeter -MINIMAL_VERSION=8 +MINIMAL_VERSION=17 # Check if version is from OpenJDK or Oracle Hotspot JVM prior to 9 containing 1.${version}.x CURRENT_VERSION=`"${JAVA_HOME}/bin/java" -version 2>&1 | awk -F'"' '/version/ {gsub("^1[.]", "", $2); gsub("[^0-9].*$", "", $2); print $2}'` # Check if Java is present and the minimal version requirement -if [ "$CURRENT_VERSION" -gt "$MINIMAL_VERSION" ]; then +if [ "$CURRENT_VERSION" -ge "$MINIMAL_VERSION" ]; then JAVA9_OPTS="--add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens java.desktop/sun.swing=ALL-UNNAMED --add-opens java.desktop/javax.swing.text.html=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED --add-opens=java.desktop/sun.awt.shell=ALL-UNNAMED" +else + echo "JMeter requires Java $MINIMAL_VERSION or later. Current Java version is $CURRENT_VERSION" + exit 1 fi # Don't add additional arguments to the JVM start, except those needed for Java 9 diff --git a/bin/log4j2.xml b/bin/log4j2.xml index 47b012f2cf4..feb8954d56a 100644 --- a/bin/log4j2.xml +++ b/bin/log4j2.xml @@ -16,7 +16,7 @@ ~ limitations under the License. --> - + diff --git a/bin/mirror-server.cmd b/bin/mirror-server.cmd index 6f76adf5951..1f86cff1ef1 100644 --- a/bin/mirror-server.cmd +++ b/bin/mirror-server.cmd @@ -27,8 +27,8 @@ set JMETER_CMD_LINE_ARGS=%* cd /D %~dp0 set CP=..\lib\ext\ApacheJMeter_http.jar;..\lib\ext\ApacheJMeter_core.jar;..\lib\jorphan.jar;..\lib\oro-2.0.8.jar -set CP=%CP%;..\lib\slf4j-api-1.7.25.jar;..\lib\jcl-over-slf4j-1.7.25.jar;..\lib\log4j-slf4j-impl-2.11.1.jar -set CP=%CP%;..\lib\log4j-api-2.11.1.jar;..\lib\log4j-core-2.11.1.jar;..\lib\log4j-1.2-api-2.11.1.jar +set CP=%CP%;..\lib\slf4j-api-1.7.36.jar;..\lib\jcl-over-slf4j-1.7.36.jar;..\lib\log4j-slf4j-impl-2.22.1.jar +set CP=%CP%;..\lib\log4j-api-2.22.1.jar;..\lib\log4j-core-2.22.1.jar;..\lib\log4j-1.2-api-2.22.1.jar java -cp %CP% org.apache.jmeter.protocol.http.control.HttpMirrorServer %JMETER_CMD_LINE_ARGS% diff --git a/bin/mirror-server.sh b/bin/mirror-server.sh index 7e969626258..1da2f9d0349 100755 --- a/bin/mirror-server.sh +++ b/bin/mirror-server.sh @@ -22,7 +22,7 @@ cd "$(dirname "$0")" || exit 1 CP=../lib/ext/ApacheJMeter_http.jar:../lib/ext/ApacheJMeter_core.jar:../lib/jorphan.jar:../lib/oro-2.0.8.jar -CP=${CP}:../lib/slf4j-api-1.7.25.jar:../lib/jcl-over-slf4j-1.7.25.jar:../lib/log4j-slf4j-impl-2.11.0.jar -CP=${CP}:../lib/log4j-api-2.11.1.jar:../lib/log4j-core-2.11.1.jar:../lib/log4j-1.2-api-2.11.1.jar +CP=${CP}:../lib/slf4j-api-1.7.36.jar:../lib/jcl-over-slf4j-1.7.36.jar:../lib/log4j-slf4j-impl-2.22.1.jar +CP=${CP}:../lib/log4j-api-2.22.1.jar:../lib/log4j-core-2.22.1.jar:../lib/log4j-1.2-api-2.22.1.jar java -cp $CP org.apache.jmeter.protocol.http.control.HttpMirrorServer "$@" diff --git a/bin/report-template/content/pages/ResponseTimes.html.fmkr b/bin/report-template/content/pages/ResponseTimes.html.fmkr index 9b59d484b74..e3fc05542bb 100644 --- a/bin/report-template/content/pages/ResponseTimes.html.fmkr +++ b/bin/report-template/content/pages/ResponseTimes.html.fmkr @@ -217,7 +217,7 @@
  • Hide all samples
  • -
  • Save as PNG
  • +
  • Save as PNG