diff --git a/.github/workflows/artifactory-milestone-release.yml b/.github/workflows/artifactory-milestone-release.yml deleted file mode 100644 index 4c368a39a4..0000000000 --- a/.github/workflows/artifactory-milestone-release.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Artifactory Milestone Release - -on: - workflow_dispatch: - inputs: - releaseVersion: - description: "Milestone release version" - required: true - -jobs: - build: - name: Release milestone to Artifactory - runs-on: ubuntu-latest - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - - - name: Capture release version - run: echo RELEASE_VERSION=${{ github.event.inputs.releaseVersion }} >> $GITHUB_ENV - - - name: Update release version - run: mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$RELEASE_VERSION - - - name: Enforce release rules - run: mvn org.apache.maven.plugins:maven-enforcer-plugin:enforce -Drules=requireReleaseDeps - - - name: Build with Maven and deploy to Artifactory's milestone repository - env: - ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} - ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} - run: mvn -P artifactory-milestone -s settings.xml --batch-mode -Dmaven.test.skip=true deploy diff --git a/.github/workflows/artifactory-staging.yml b/.github/workflows/artifactory-staging.yml index ae8a04859c..00d80b927d 100644 --- a/.github/workflows/artifactory-staging.yml +++ b/.github/workflows/artifactory-staging.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: releaseVersion: - description: "Release version" + description: "Release version (5.0.x)" required: true jobs: @@ -14,6 +14,8 @@ jobs: steps: - name: Checkout source code uses: actions/checkout@v3 + with: + ref: '5.0.x' - name: Set up JDK 17 uses: actions/setup-java@v3 diff --git a/.github/workflows/continuous-inspection.yml b/.github/workflows/continuous-inspection.yml deleted file mode 100644 index f496eba5c9..0000000000 --- a/.github/workflows/continuous-inspection.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Continuous inspection build - -on: - schedule: - - cron: '0 10 * * *' # Once per day at 10am UTC - workflow_dispatch: - -jobs: - code-quality-analysis: - name: code quality analysis report - runs-on: ubuntu-latest - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - - - name: Analyse test coverage with Jacoco - run: mvn -P test-coverage verify - - - name: Analyse code quality with Sonar - if: github.repository == 'spring-projects/spring-batch' - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_URL }} - run: mvn sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_TOKEN - diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration-50x.yml similarity index 78% rename from .github/workflows/continuous-integration.yml rename to .github/workflows/continuous-integration-50x.yml index 08e9d43564..9744e02581 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration-50x.yml @@ -1,16 +1,18 @@ -name: CI/CD build +name: CI/CD build for 5.0.x on: push: - branches: [ "main" ] + branches: [ "5.0.x" ] jobs: build: - name: Build Main branch + name: Build 5.0.x branch runs-on: ubuntu-latest steps: - name: Checkout source code uses: actions/checkout@v3 + with: + ref: '5.0.x' - name: Set up JDK 17 uses: actions/setup-java@v3 @@ -50,8 +52,10 @@ jobs: DOCS_HOST: ${{ secrets.DOCS_HOST }} DOCS_PATH: ${{ secrets.DOCS_PATH }} DOCS_USERNAME: ${{ secrets.DOCS_USERNAME }} - working-directory: spring-batch-docs + working-directory: spring-batch-docs/target run: | - cd target && unzip spring-batch-$PROJECT_VERSION-docs.zip + unzip spring-batch-$PROJECT_VERSION-docs.zip + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $PROJECT_VERSION" scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && rm 5.0.x-SNAPSHOT && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT" diff --git a/.github/workflows/documentation-upload.yml b/.github/workflows/documentation-upload.yml index ecbbb01246..9ec72c93ed 100644 --- a/.github/workflows/documentation-upload.yml +++ b/.github/workflows/documentation-upload.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: releaseVersion: - description: "Release version" + description: "Release version (5.0.x)" required: true jobs: @@ -17,6 +17,8 @@ jobs: - name: Checkout source code uses: actions/checkout@v3 + with: + ref: '5.0.x' - name: Set up JDK 17 uses: actions/setup-java@v3 @@ -25,6 +27,9 @@ jobs: distribution: 'temurin' cache: 'maven' + - name: Update release version + run: mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$RELEASE_VERSION + - name: Generate Java docs run: mvn javadoc:aggregate @@ -52,9 +57,10 @@ jobs: working-directory: spring-batch-docs/target run: | unzip spring-batch-$RELEASE_VERSION-docs.zip - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir $RELEASE_VERSION - scp -i $HOME/.ssh/key -r api reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST rm current && ln -s $RELEASE_VERSION current + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $RELEASE_VERSION" + scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION + scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && rm 5.0.x && ln -s $RELEASE_VERSION 5.0.x" unzip spring-batch-$RELEASE_VERSION-schemas.zip scp -i $HOME/.ssh/key batch/*.xsd $DOCS_USERNAME@$DOCS_HOST:$BATCH_SCHEMA_PATH diff --git a/.github/workflows/maven-central-release.yml b/.github/workflows/maven-central-release.yml deleted file mode 100644 index 6d3905dea2..0000000000 --- a/.github/workflows/maven-central-release.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Maven Central Release - -on: - workflow_dispatch: - inputs: - releaseVersion: - description: "Release version" - required: true - -jobs: - build: - runs-on: ubuntu-latest - steps: - - - name: Capture release version - run: echo RELEASE_VERSION=${{ github.event.inputs.releaseVersion }} >> $GITHUB_ENV - - - name: Prepare directory structure - run: | - mkdir -p nexus/org/springframework/batch/spring-batch-bom/$RELEASE_VERSION - mkdir -p nexus/org/springframework/batch/spring-batch-infrastructure/$RELEASE_VERSION - mkdir -p nexus/org/springframework/batch/spring-batch-core/$RELEASE_VERSION - mkdir -p nexus/org/springframework/batch/spring-batch-test/$RELEASE_VERSION - mkdir -p nexus/org/springframework/batch/spring-batch-integration/$RELEASE_VERSION - - - name: Download release files from Artifactory - env: - ARTIFACTORY_URL: "https://repo.spring.io/libs-staging-local/org/springframework/batch" - run: | - echo "Downloading BOM artifacts" - cd nexus/org/springframework/batch/spring-batch-bom/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-bom/$RELEASE_VERSION/spring-batch-bom-$RELEASE_VERSION.pom - - echo "Downloading infrastructure artifacts" - cd ../../../../../.. - cd nexus/org/springframework/batch/spring-batch-infrastructure/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-infrastructure/$RELEASE_VERSION/spring-batch-infrastructure-$RELEASE_VERSION.pom - wget $ARTIFACTORY_URL/spring-batch-infrastructure/$RELEASE_VERSION/spring-batch-infrastructure-$RELEASE_VERSION.jar - wget $ARTIFACTORY_URL/spring-batch-infrastructure/$RELEASE_VERSION/spring-batch-infrastructure-$RELEASE_VERSION-javadoc.jar - wget $ARTIFACTORY_URL/spring-batch-infrastructure/$RELEASE_VERSION/spring-batch-infrastructure-$RELEASE_VERSION-sources.jar - - echo "Downloading core artifacts" - cd ../../../../../.. - cd nexus/org/springframework/batch/spring-batch-core/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-core/$RELEASE_VERSION/spring-batch-core-$RELEASE_VERSION.pom - wget $ARTIFACTORY_URL/spring-batch-core/$RELEASE_VERSION/spring-batch-core-$RELEASE_VERSION.jar - wget $ARTIFACTORY_URL/spring-batch-core/$RELEASE_VERSION/spring-batch-core-$RELEASE_VERSION-javadoc.jar - wget $ARTIFACTORY_URL/spring-batch-core/$RELEASE_VERSION/spring-batch-core-$RELEASE_VERSION-sources.jar - - echo "Downloading test artifacts" - cd ../../../../../.. - cd nexus/org/springframework/batch/spring-batch-test/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-test/$RELEASE_VERSION/spring-batch-test-$RELEASE_VERSION.pom - wget $ARTIFACTORY_URL/spring-batch-test/$RELEASE_VERSION/spring-batch-test-$RELEASE_VERSION.jar - wget $ARTIFACTORY_URL/spring-batch-test/$RELEASE_VERSION/spring-batch-test-$RELEASE_VERSION-javadoc.jar - wget $ARTIFACTORY_URL/spring-batch-test/$RELEASE_VERSION/spring-batch-test-$RELEASE_VERSION-sources.jar - - echo "Downloading integration artifacts" - cd ../../../../../.. - cd nexus/org/springframework/batch/spring-batch-integration/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-integration/$RELEASE_VERSION/spring-batch-integration-$RELEASE_VERSION.pom - wget $ARTIFACTORY_URL/spring-batch-integration/$RELEASE_VERSION/spring-batch-integration-$RELEASE_VERSION.jar - wget $ARTIFACTORY_URL/spring-batch-integration/$RELEASE_VERSION/spring-batch-integration-$RELEASE_VERSION-javadoc.jar - wget $ARTIFACTORY_URL/spring-batch-integration/$RELEASE_VERSION/spring-batch-integration-$RELEASE_VERSION-sources.jar - - - name: Sign artifacts and release them to Maven Central - uses: jvalkeal/nexus-sync@v0 - id: nexus - with: - url: ${{ secrets.OSSRH_URL }} - username: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }} - password: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }} - staging-profile-name: ${{ secrets.OSSRH_STAGING_PROFILE_NAME }} - create: true - upload: true - close: true - release: true - generate-checksums: true - pgp-sign: true - pgp-sign-passphrase: ${{ secrets.GPG_PASSPHRASE }} - pgp-sign-private-key: ${{ secrets.GPG_PRIVATE_KEY }} diff --git a/.github/workflows/maven-central-stage.yml b/.github/workflows/maven-central-stage.yml deleted file mode 100644 index e01f26c54d..0000000000 --- a/.github/workflows/maven-central-stage.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Maven Central Staging - -on: - workflow_dispatch: - inputs: - buildName: - description: "Artifactory build name" - required: true - buildNumber: - description: "Artifactory build number" - required: true - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # to get spec file in .github - - uses: actions/checkout@v2 - - # Setup jfrog cli - - uses: jfrog/setup-jfrog-cli@v1 - with: - version: 1.43.2 - env: - JF_ARTIFACTORY_SPRING: ${{ secrets.JF_ARTIFACTORY_SPRING }} - - # Extract build id from input - - name: Extract Build Id - run: | - echo JFROG_CLI_BUILD_NAME=${{ github.event.inputs.buildName }} >> $GITHUB_ENV - echo JFROG_CLI_BUILD_NUMBER=${{ github.event.inputs.buildNumber }} >> $GITHUB_ENV - - # Download released files - - name: Download Release Files - run: | - jfrog rt download \ - --spec .github/release-files-spec.json \ - --spec-vars "buildname=$JFROG_CLI_BUILD_NAME;buildnumber=$JFROG_CLI_BUILD_NUMBER" - - # Create checksums, signatures and create staging repo on central and upload - - uses: jvalkeal/nexus-sync@v0 - id: nexus - with: - url: ${{ secrets.OSSRH_URL }} - username: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }} - password: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }} - staging-profile-name: ${{ secrets.OSSRH_STAGING_PROFILE_NAME }} - create: true - upload: true - generate-checksums: true - pgp-sign: true - pgp-sign-passphrase: ${{ secrets.GPG_PASSPHRASE }} - pgp-sign-private-key: ${{ secrets.GPG_PRIVATE_KEY }} - - # Print staging repo id - - name: Print Staging Repo Id - run: echo ${{ steps.nexus.outputs.staged-repository-id }} diff --git a/.github/workflows/release-notes-generation.yml b/.github/workflows/release-notes-generation.yml deleted file mode 100644 index fa601a05fa..0000000000 --- a/.github/workflows/release-notes-generation.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Generate Release notes - -on: - workflow_dispatch: - inputs: - milestoneNumber: - description: "Milestone title" - required: true - generatorVersion: - description: "Changelog Generator version" - required: true - -jobs: - build: - name: Generate release notes - runs-on: ubuntu-latest - steps: - - name: Capture milestone number and generator version - run: | - echo MILESTONE_NUMBER=${{ github.event.inputs.milestoneNumber }} >> $GITHUB_ENV - echo GENERATOR_VERSION=${{ github.event.inputs.generatorVersion }} >> $GITHUB_ENV - - - name: Download changelog generator - run: wget https://github.com/spring-io/github-changelog-generator/releases/download/v$GENERATOR_VERSION/github-changelog-generator.jar - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - - name: Prepare configuration file - run: | - cat << EOF > application.yml - changelog: - repository: spring-projects/spring-batch - sections: - - title: ":star: New features" - labels: [ "type: feature" ] - - title: ":rocket: Enhancements" - labels: [ "type: enhancement" ] - - title: ":lady_beetle: Bug fixes" - labels: [ "type: bug" ] - - title: ":notebook_with_decorative_cover: Documentation" - labels: [ "in: documentation" ] - - title: ":hammer: Tasks" - labels: [ "type: task" ] - EOF - - - name: Generate release notes - run: java -jar github-changelog-generator.jar $MILESTONE_NUMBER release-notes.md - - - name: Print release notes - run: cat release-notes.md diff --git a/pom.xml b/pom.xml index 390eab4dbe..66915893eb 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.3-SNAPSHOT + 5.0.7-SNAPSHOT pom https://projects.spring.io/spring-batch @@ -61,29 +61,29 @@ 17 - 6.0.9 - 2.0.1 - 6.0.5 - 1.10.7 + 6.0.20 + 2.0.6 + 6.0.9 + 1.10.13 - 3.0.6 - 3.0.6 - 4.0.6 - 3.0.7 - 3.0.4 - 3.0.3 + 3.0.12 + 3.0.12 + 4.0.12 + 3.0.17 + 3.0.14 + 3.0.6 2.14.3 1.9.2 2.9.1 6.1.7.Final 2.1.1 - 2.1.1 + 2.1.3 3.1.0 3.0.2 3.1.0 - 4.0.5 + 4.0.10 4.9.1 5.9.3 @@ -91,49 +91,49 @@ 3.0.2 - 1.0.5 + 1.1.13 1.4.20 4.13.2 ${junit-jupiter.version} 2.2 3.24.2 - 5.3.1 + 5.7.0 2.9.1 - 2.11.0 - 2.9.0 - 2.0.7 - 2.7.1 - 2.1.214 - 3.41.2.1 + 2.15.1 + 2.11.0 + 2.0.13 + 2.7.2 + 2.2.224 + 3.44.1.0 10.16.1.1 - 2.16.14 - 2.28.0 - 4.0.2 - 2.20.0 - 8.0.0.Final + 2.18.16 + 2.31.2 + 4.0.5 + 2.22.1 + 8.0.1.Final 5.0.1 4.0.2 2.0.1 - 4.0.0 - 2.0.1 + 4.0.1 + 2.0.3 6.5.1 - 1.9.19 - 8.0.33 - 3.1.4 - 42.6.0 - 11.5.8.0 - 19.18.0.0 + 1.9.21.2 + 8.3.0 + 3.3.3 + 42.7.3 + 11.5.9.0 + 19.22.0.0 11.2.3.jre17 1.3.1 - 1.18.1 + 1.19.8 1.5.1 ${spring-amqp.version} 2.3.2 0.16.0 - 3.0.15 + 3.0.19 1.6.2 @@ -141,19 +141,19 @@ 0.0.5 - 3.10.1 - 3.1.0 - 3.1.0 - 3.5.0 - 3.2.1 + 3.11.0 + 3.1.2 + 3.1.2 + 3.6.0 + 3.3.0 0.8.10 1.5.0 3.1.1 - 2.2.3 + 2.2.4 3.6.0 - 3.5.0 + 3.6.0 3.12.1 - 3.4.3 + 3.4.5 3.3.0 0.0.39 diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index 88cab82c3c..91accf3644 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.7-SNAPSHOT spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index 6527acf379..124f3008eb 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.7-SNAPSHOT spring-batch-core jar diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java index 44078f7db0..01ee5034cc 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java @@ -142,7 +142,7 @@ public String getString(String key, @Nullable String defaultValue) { } /** - * Typesafe getter for the {@link Long} represented by the provided key. + * Typesafe getter for the {@link Double} represented by the provided key. * @param key The key for which to get a value. * @return The {@link Double} value or {@code null} if the key is absent. */ @@ -330,6 +330,21 @@ public Map> getParameters() { return Collections.unmodifiableMap(parameters); } + /** + * Get a map of identifying parameters. + * @since 5.1 + * @return an unmodifiable map containing identifying parameters. + */ + public Map> getIdentifyingParameters() { + Map> identifyingParameters = new HashMap<>(); + for (Map.Entry> entry : this.parameters.entrySet()) { + if (entry.getValue().isIdentifying()) { + identifyingParameters.put(entry.getKey(), entry.getValue()); + } + } + return Collections.unmodifiableMap(identifyingParameters); + } + /** * @return {@code true} if the parameters object is empty or {@code false} otherwise. */ diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java index 3450f4894a..9727fa52a5 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java @@ -105,6 +105,7 @@ public JobParametersBuilder addString(String key, @NonNull String parameter) { * @return a reference to this object. */ public JobParametersBuilder addString(String key, @NonNull String parameter, boolean identifying) { + Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null"); this.parameterMap.put(key, new JobParameter<>(parameter, String.class, identifying)); return this; } @@ -128,6 +129,7 @@ public JobParametersBuilder addDate(String key, @NonNull Date parameter) { * @return a reference to this object. */ public JobParametersBuilder addDate(String key, @NonNull Date parameter, boolean identifying) { + Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null"); this.parameterMap.put(key, new JobParameter<>(parameter, Date.class, identifying)); return this; } @@ -151,6 +153,7 @@ public JobParametersBuilder addLocalDate(String key, @NonNull LocalDate paramete * @return a reference to this object. */ public JobParametersBuilder addLocalDate(String key, @NonNull LocalDate parameter, boolean identifying) { + Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null"); this.parameterMap.put(key, new JobParameter<>(parameter, LocalDate.class, identifying)); return this; } @@ -174,6 +177,7 @@ public JobParametersBuilder addLocalTime(String key, @NonNull LocalTime paramete * @return a reference to this object. */ public JobParametersBuilder addLocalTime(String key, @NonNull LocalTime parameter, boolean identifying) { + Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null"); this.parameterMap.put(key, new JobParameter<>(parameter, LocalTime.class, identifying)); return this; } @@ -197,6 +201,7 @@ public JobParametersBuilder addLocalDateTime(String key, @NonNull LocalDateTime * @return a reference to this object. */ public JobParametersBuilder addLocalDateTime(String key, @NonNull LocalDateTime parameter, boolean identifying) { + Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null"); this.parameterMap.put(key, new JobParameter<>(parameter, LocalDateTime.class, identifying)); return this; } @@ -220,6 +225,7 @@ public JobParametersBuilder addLong(String key, @NonNull Long parameter) { * @return a reference to this object. */ public JobParametersBuilder addLong(String key, @NonNull Long parameter, boolean identifying) { + Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null"); this.parameterMap.put(key, new JobParameter<>(parameter, Long.class, identifying)); return this; } @@ -243,6 +249,7 @@ public JobParametersBuilder addDouble(String key, @NonNull Double parameter) { * @return a reference to this object. */ public JobParametersBuilder addDouble(String key, @NonNull Double parameter, boolean identifying) { + Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null"); this.parameterMap.put(key, new JobParameter<>(parameter, Double.class, identifying)); return this; } @@ -285,27 +292,28 @@ public JobParametersBuilder addJobParameter(String key, JobParameter jobParam /** * Add a job parameter. * @param name the name of the parameter - * @param value the value of the parameter + * @param value the value of the parameter. Must not be {@code null}. * @param type the type of the parameter * @param identifying true if the parameter is identifying. false otherwise * @return a reference to this object. * @param the type of the parameter * @since 5.0 */ - public JobParametersBuilder addJobParameter(String name, T value, Class type, boolean identifying) { + public JobParametersBuilder addJobParameter(String name, @NonNull T value, Class type, boolean identifying) { + Assert.notNull(value, "Value for parameter '" + name + "' must not be null"); return addJobParameter(name, new JobParameter<>(value, type, identifying)); } /** * Add an identifying job parameter. * @param name the name of the parameter - * @param value the value of the parameter + * @param value the value of the parameter. Must not be {@code null}. * @param type the type of the parameter * @return a reference to this object. * @param the type of the parameter * @since 5.0 */ - public JobParametersBuilder addJobParameter(String name, T value, Class type) { + public JobParametersBuilder addJobParameter(String name, @NonNull T value, Class type) { return addJobParameter(name, value, type, true); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java index ab0cfdb6ba..79bd590d7b 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -168,7 +168,11 @@ protected JobParameter decode(String encodedJobParameter) { } private String parseValue(String encodedJobParameter) { - return StringUtils.commaDelimitedListToStringArray(encodedJobParameter)[0]; + String[] tokens = StringUtils.commaDelimitedListToStringArray(encodedJobParameter); + if (tokens.length == 0) { + return ""; + } + return tokens[0]; } private Class parseType(String encodedJobParameter) { diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java index dde3e6571c..db072f65de 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java @@ -48,6 +48,7 @@ * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine + * @author Injae Kim * @since 2.2 * @param the type of object returned by the builder (by default a Flow) * @@ -107,7 +108,8 @@ public Q build() { /** * Transition to the next step on successful completion of the current step. All other - * outcomes are treated as failures. + * outcomes are treated as failures. If no steps are registered yet, then this method + * will behave in the same way as {@link #start(Step)}. * @param step the next step * @return this to enable chaining */ @@ -250,26 +252,32 @@ private void doNext(Object input) { if (this.currentState == null) { doStart(input); } - State next = createState(input); - addTransition("COMPLETED", next); - addTransition("*", failedState); - this.currentState = next; + else { + State next = createState(input); + addTransition("COMPLETED", next); + addTransition("*", failedState); + this.currentState = next; + } } private void doStart(Object input) { if (this.currentState != null) { doFrom(input); } - this.currentState = createState(input); + else { + this.currentState = createState(input); + } } private void doFrom(Object input) { if (currentState == null) { doStart(input); } - State state = createState(input); - tos.put(currentState.getName(), currentState); - this.currentState = state; + else { + State state = createState(input); + tos.put(currentState.getName(), currentState); + this.currentState = state; + } } private State createState(Object input) { diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java index 67fb991f53..d00372346a 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java @@ -62,7 +62,7 @@ public SimpleJobBuilder start(Step step) { /** * Create a new job builder that will execute a flow. * @param flow a flow to execute - * @return a {@link SimpleJobBuilder} + * @return a {@link JobFlowBuilder} */ public JobFlowBuilder start(Flow flow) { return new FlowJobBuilder(this).start(flow); @@ -71,7 +71,7 @@ public JobFlowBuilder start(Flow flow) { /** * Create a new job builder that will execute a step or sequence of steps. * @param step a step to execute - * @return a {@link SimpleJobBuilder} + * @return a {@link JobFlowBuilder} */ public JobFlowBuilder flow(Step step) { return new FlowJobBuilder(this).start(step); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/SimpleFlow.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/SimpleFlow.java index 2101c171d4..f66ce004c2 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/SimpleFlow.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/SimpleFlow.java @@ -48,6 +48,7 @@ * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine + * @author Taeik Lim * @since 2.0 */ public class SimpleFlow implements Flow, InitializingBean { @@ -124,9 +125,7 @@ public Collection getStates() { */ @Override public void afterPropertiesSet() throws Exception { - if (startState == null) { - initializeTransitions(); - } + initializeTransitionsIfNotInitialized(); } /** @@ -134,9 +133,8 @@ public void afterPropertiesSet() throws Exception { */ @Override public FlowExecution start(FlowExecutor executor) throws FlowExecutionException { - if (startState == null) { - initializeTransitions(); - } + initializeTransitionsIfNotInitialized(); + State state = startState; String stateName = state.getName(); return resume(stateName, executor); @@ -262,6 +260,12 @@ protected boolean isFlowContinued(State state, FlowExecutionStatus status, StepE return continued; } + private synchronized void initializeTransitionsIfNotInitialized() { + if (startState == null) { + initializeTransitions(); + } + } + /** * Analyse the transitions provided and generate all the information needed to execute * the flow. diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBean.java index ce2ef8e4f2..a3c07375ec 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 the original author or authors. + * Copyright 2022-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,7 +71,7 @@ public class JobOperatorFactoryBean implements FactoryBean, Initial public void afterPropertiesSet() throws Exception { Assert.notNull(this.transactionManager, "TransactionManager must not be null"); Assert.notNull(this.jobLauncher, "JobLauncher must not be null"); - Assert.notNull(this.jobRegistry, "JobLocator must not be null"); + Assert.notNull(this.jobRegistry, "JobRegistry must not be null"); Assert.notNull(this.jobExplorer, "JobExplorer must not be null"); Assert.notNull(this.jobRepository, "JobRepository must not be null"); if (this.transactionAttributeSource == null) { diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/OrderedComposite.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/OrderedComposite.java index abd24cbc77..75f9c2516c 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/OrderedComposite.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/OrderedComposite.java @@ -83,7 +83,7 @@ else if (!unordered.contains(item)) { * @return an iterator over the list of items */ public Iterator iterator() { - return new ArrayList<>(list).iterator(); + return Collections.unmodifiableList(list).iterator(); } /** diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java index 9748d469a1..3e5fe34e2c 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java @@ -174,6 +174,9 @@ private abstract class JobParametersMixIn { @JsonIgnore abstract boolean isEmpty(); + @JsonIgnore + abstract Map> getIdentifyingParameters(); + } private class JobParameterSerializer extends StdSerializer { @@ -295,7 +298,8 @@ static class TrustedTypeIdResolver implements TypeIdResolver { "java.lang.Byte", "java.lang.Short", "java.lang.Integer", "java.lang.Long", "java.lang.Double", "java.lang.Float", "java.math.BigDecimal", "java.math.BigInteger", "java.lang.String", "java.lang.Character", "java.lang.CharSequence", "java.util.Properties", "[Ljava.util.Properties;", - "org.springframework.batch.core.JobParameter", "org.springframework.batch.core.JobParameters"); + "org.springframework.batch.core.JobParameter", "org.springframework.batch.core.JobParameters", + "java.util.concurrent.ConcurrentHashMap", "java.sql.Date"); private final Set trustedClassNames = new LinkedHashSet<>(TRUSTED_CLASS_NAMES); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java index 20eaacafe6..48610fbf77 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; -import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; @@ -54,6 +53,7 @@ * @author Mahmoud Ben Hassine * @author Baris Cubukcuoglu * @author Parikshit Dutta + * @author Mark John Moreno * @see JobRepository * @see JobInstanceDao * @see JobExecutionDao @@ -151,15 +151,14 @@ public JobExecution createJobExecution(String jobName, JobParameters jobParamete + "The last execution ended with a failure that could not be rolled back, " + "so it may be dangerous to proceed. Manual intervention is probably necessary."); } - Collection> allJobParameters = execution.getJobParameters().getParameters().values(); - long identifyingJobParametersCount = allJobParameters.stream() - .filter(JobParameter::isIdentifying) - .count(); - if (identifyingJobParametersCount > 0 + JobParameters allJobParameters = execution.getJobParameters(); + JobParameters identifyingJobParameters = new JobParameters(allJobParameters.getIdentifyingParameters()); + if (!identifyingJobParameters.isEmpty() && (status == BatchStatus.COMPLETED || status == BatchStatus.ABANDONED)) { throw new JobInstanceAlreadyCompleteException( - "A job instance already exists and is complete for parameters=" + jobParameters - + ". If you want to run this job again, change the parameters."); + "A job instance already exists and is complete for identifying parameters=" + + identifyingJobParameters + ". If you want to run this job again, " + + "change the parameters."); } } executionContext = ecDao.getExecutionContext(jobExecutionDao.getLastJobExecution(jobInstance)); @@ -329,7 +328,7 @@ public void deleteJobExecution(JobExecution jobExecution) { @Override public void deleteJobInstance(JobInstance jobInstance) { - List jobExecutions = this.jobExecutionDao.findJobExecutions(jobInstance); + List jobExecutions = findJobExecutions(jobInstance); for (JobExecution jobExecution : jobExecutions) { deleteJobExecution(jobExecution); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java index 8ab4fb2a14..eb61b652d1 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java @@ -49,6 +49,7 @@ * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine + * @author Ilpyo Yang * @since 2.2 * @param the type of builder represented */ @@ -74,6 +75,23 @@ public AbstractTaskletStepBuilder(StepBuilderHelper parent) { super(parent); } + /** + * Create a new builder initialized with any properties in the parent. The parent is + * copied, so it can be re-used. + * @param parent a parent helper containing common step properties + */ + public AbstractTaskletStepBuilder(AbstractTaskletStepBuilder parent) { + super(parent); + this.chunkListeners = parent.chunkListeners; + this.stepOperations = parent.stepOperations; + this.transactionManager = parent.transactionManager; + this.transactionAttribute = parent.transactionAttribute; + this.streams.addAll(parent.streams); + this.exceptionHandler = parent.exceptionHandler; + this.throttleLimit = parent.throttleLimit; + this.taskExecutor = parent.taskExecutor; + } + protected abstract Tasklet createTasklet(); /** @@ -199,9 +217,10 @@ public B taskExecutor(TaskExecutor taskExecutor) { * in the job repository for this step. * @param throttleLimit maximum number of concurrent tasklet executions allowed * @return this for fluent chaining - * @deprecated since 5.0, scheduled for removal in 6.0. Use a pooled - * {@link TaskExecutor} implementation with a limited capacity of its task queue - * instead. + * @deprecated with no replacement since 5.0, scheduled for removal in 6.0. Use a + * custom {@link RepeatOperations} implementation (based on a {@link TaskExecutor} + * with a bounded task queue) and set it on the step with + * {@link #stepOperations(RepeatOperations)}. */ @Deprecated(since = "5.0", forRemoval = true) public B throttleLimit(int throttleLimit) { diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java index 9bf252cbd2..088b17ca5f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,8 +58,8 @@ /** * Step builder for simple item processing (chunk oriented) steps. Items are read and - * cached in chunks, and then processed (transformed) and written (optionally either the - * processor or the writer can be omitted) all in the same transaction. + * cached in chunks, and then processed (transformed) and written (optionally the + * processor can be omitted) all in the same transaction. * * @see FaultTolerantStepBuilder for a step that handles retry and skip of failed items * @author Dave Syer @@ -114,7 +114,6 @@ protected SimpleStepBuilder(SimpleStepBuilder parent) { this.itemListeners = parent.itemListeners; this.readerTransactionalQueue = parent.readerTransactionalQueue; this.meterRegistry = parent.meterRegistry; - this.transactionManager(parent.getTransactionManager()); } public FaultTolerantStepBuilder faultTolerant() { diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java index f1eb7321f5..ecb797111c 100755 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -306,7 +306,9 @@ else if (shouldSkip(itemProcessSkipPolicy, e, contribution.getStepSkipCount())) break; } } - + if (inputs.isEnd()) { + outputs.setEnd(); + } return outputs; } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java index 813b6eb403..101945bb22 100755 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -340,6 +340,9 @@ protected Chunk transform(StepContribution contribution, Chunk inputs) thr iterator.remove(); } } + if (inputs.isEnd()) { + outputs.setEnd(); + } return outputs; } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java index 948b144712..f37de435a5 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java @@ -79,6 +79,9 @@ public JobParameters getJobParameters(Job job, StepExecution stepExecution) { if (executionContext.containsKey(key)) { properties.setProperty(key, executionContext.getString(key)); } + else if (jobParameters.containsKey(key)) { + builder.addJobParameter(key, jobParameters.get(key)); + } } builder.addJobParameters(this.jobParametersConverter.getJobParameters(properties)); return builder.toJobParameters(); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/SystemCommandTasklet.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/SystemCommandTasklet.java index b35a228a4d..4499279e8e 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/SystemCommandTasklet.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/SystemCommandTasklet.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,6 +60,7 @@ * @author Robert Kasanicky * @author Will Schipp * @author Mahmoud Ben Hassine + * @author Injae Kim */ public class SystemCommandTasklet implements StepExecutionListener, StoppableTasklet, InitializingBean { @@ -121,8 +122,15 @@ public RepeatStatus execute(StepContribution contribution, ChunkContext chunkCon } if (systemCommandTask.isDone()) { - contribution.setExitStatus(systemProcessExitCodeMapper.getExitStatus(systemCommandTask.get())); - return RepeatStatus.FINISHED; + Integer exitCode = systemCommandTask.get(); + ExitStatus exitStatus = systemProcessExitCodeMapper.getExitStatus(exitCode); + contribution.setExitStatus(exitStatus); + if (ExitStatus.FAILED.equals(exitStatus)) { + throw new SystemCommandException("Execution of system command failed with exit code " + exitCode); + } + else { + return RepeatStatus.FINISHED; + } } else if (System.currentTimeMillis() - t0 > timeout) { systemCommandTask.cancel(interruptOnCancel); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java index b5941c1ecc..58a22395c4 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java @@ -431,7 +431,9 @@ public RepeatStatus doInTransaction(TransactionStatus status) { try { // Going to attempt a commit. If it fails this flag will // stay false and we can use that later. - getJobRepository().updateExecutionContext(stepExecution); + if (stepExecution.getExecutionContext().isDirty()) { + getJobRepository().updateExecutionContext(stepExecution); + } stepExecution.incrementCommitCount(); if (logger.isDebugEnabled()) { logger.debug("Saving step execution before commit: " + stepExecution); diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/migration/5.0/migration-h2.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/migration/5.0/migration-h2.sql index 8916a0f04e..5bdac69327 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/migration/5.0/migration-h2.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/migration/5.0/migration-h2.sql @@ -5,9 +5,12 @@ ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN DATE_VAL; ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN LONG_VAL; ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN DOUBLE_VAL; -ALTER TABLE BATCH_JOB_EXECUTION_PARAMS MODIFY COLUMN TYPE_CD PARAMETER_TYPE VARCHAR(100); -ALTER TABLE BATCH_JOB_EXECUTION_PARAMS MODIFY COLUMN KEY_NAME PARAMETER_NAME VARCHAR(100); -ALTER TABLE BATCH_JOB_EXECUTION_PARAMS MODIFY COLUMN STRING_VAL PARAMETER_VALUE VARCHAR(2500); +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN TYPE_CD RENAME TO PARAMETER_TYPE; +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN PARAMETER_TYPE SET DATA TYPE VARCHAR(100); +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN KEY_NAME RENAME TO PARAMETER_NAME; +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN PARAMETER_NAME SET DATA TYPE VARCHAR(100); +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN STRING_VAL RENAME TO PARAMETER_VALUE; +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN PARAMETER_VALUE SET DATA TYPE VARCHAR(2500); ALTER TABLE BATCH_JOB_EXECUTION ALTER COLUMN CREATE_TIME SET DATA TYPE TIMESTAMP(9); ALTER TABLE BATCH_JOB_EXECUTION ALTER COLUMN START_TIME SET DATA TYPE TIMESTAMP(9); @@ -17,4 +20,4 @@ ALTER TABLE BATCH_JOB_EXECUTION ALTER COLUMN LAST_UPDATED SET DATA TYPE TIMESTAM ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN CREATE_TIME SET DATA TYPE TIMESTAMP(9); ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN START_TIME SET DATA TYPE TIMESTAMP(9); ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN END_TIME SET DATA TYPE TIMESTAMP(9); -ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN LAST_UPDATED SET DATA TYPE TIMESTAMP(9); \ No newline at end of file +ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN LAST_UPDATED SET DATA TYPE TIMESTAMP(9); diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlserver.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlserver.sql index d217ec569b..247ae20760 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlserver.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlserver.sql @@ -7,6 +7,6 @@ DROP TABLE BATCH_JOB_EXECUTION_PARAMS; DROP TABLE BATCH_JOB_EXECUTION; DROP TABLE BATCH_JOB_INSTANCE; -DROP TABLE BATCH_STEP_EXECUTION_SEQ; -DROP TABLE BATCH_JOB_EXECUTION_SEQ; -DROP TABLE BATCH_JOB_SEQ; +DROP SEQUENCE BATCH_STEP_EXECUTION_SEQ; +DROP SEQUENCE BATCH_JOB_EXECUTION_SEQ; +DROP SEQUENCE BATCH_JOB_SEQ; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java index a79efcca41..220dfc4724 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the original author or authors. + * Copyright 2008-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Set; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -61,7 +62,7 @@ class JobParametersBuilderTests { @BeforeEach void initialize() { this.job = new SimpleJob("simpleJob"); - this.jobExplorer = mock(JobExplorer.class); + this.jobExplorer = mock(); this.jobInstanceList = new ArrayList<>(1); this.jobExecutionList = new ArrayList<>(1); this.parametersBuilder = new JobParametersBuilder(this.jobExplorer); @@ -85,6 +86,13 @@ void testAddingExistingJobParameters() { assertEquals(finalParams.getString("baz"), "quix"); } + @Test + void testAddingNullJobParameters() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> new JobParametersBuilder().addString("foo", null).toJobParameters()); + Assertions.assertEquals("Value for parameter 'foo' must not be null", exception.getMessage()); + } + @Test void testNonIdentifyingParameters() { this.parametersBuilder.addDate("SCHEDULE_DATE", date, false); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersTests.java index b3a4b310d8..28c70c7615 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersTests.java @@ -187,6 +187,25 @@ void testSerialization() { assertEquals(params, SerializationUtils.clone(params)); } + @Test + void testGetIdentifyingParameters() { + // given + Map> parametersMap = new HashMap<>(); + JobParameter jobParameter1 = new JobParameter<>("value1", String.class, true); + JobParameter jobParameter2 = new JobParameter<>("value2", String.class, false); + parametersMap.put("key1", jobParameter1); + parametersMap.put("key2", jobParameter2); + JobParameters parameters = new JobParameters(parametersMap); + + // when + Map> identifyingParameters = parameters.getIdentifyingParameters(); + + // then + assertEquals(1, identifyingParameters.size()); + JobParameter key1 = identifyingParameters.get("key1"); + assertEquals(jobParameter1, key1); + } + @Test void testLongReturnsNullWhenKeyDoesntExit() { assertNull(new JobParameters().getLong("keythatdoesntexist")); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java index 066db5b3c7..b07fc71e7e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java @@ -179,7 +179,7 @@ public static class JobConfigurationWithoutTransactionManager { @Bean public DataSource dataSource() { - return Mockito.mock(DataSource.class); + return Mockito.mock(); } } @@ -190,27 +190,27 @@ public static class JobConfigurationWithUserDefinedInfrastructureBeans { @Bean public JobRepository jobRepository() { - return Mockito.mock(JobRepository.class); + return Mockito.mock(); } @Bean public JobExplorer jobExplorer() { - return Mockito.mock(JobExplorer.class); + return Mockito.mock(); } @Bean public JobLauncher jobLauncher() { - return Mockito.mock(JobLauncher.class); + return Mockito.mock(); } @Bean public JobRegistry jobRegistry() { - return Mockito.mock(JobRegistry.class); + return Mockito.mock(); } @Bean public JobOperator jobOperator() { - return Mockito.mock(JobOperator.class); + return Mockito.mock(); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java index c58894659f..61112f4768 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java @@ -183,7 +183,7 @@ void testStartStopRunning() { @Test void testStartStopRunningWithCallback() { - Runnable callback = Mockito.mock(Runnable.class); + Runnable callback = Mockito.mock(); Resource[] jobPaths = new Resource[] { new ClassPathResource("org/springframework/batch/core/launch/support/2jobs.xml") }; setUpApplicationContextFactories(jobPaths, null); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java index e413162a41..d39b9ad5eb 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test; +import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.util.StringUtils; @@ -129,6 +130,22 @@ void testGetParametersWithBogusLong() { } } + @Test + void testGetParametersWithEmptyValue() { + // given + String[] args = new String[] { "parameter=" }; + + // when + JobParameters jobParameters = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "=")); + + // then + assertEquals(1, jobParameters.getParameters().size()); + JobParameter parameter = jobParameters.getParameters().get("parameter"); + assertEquals("", parameter.getValue()); + assertEquals(String.class, parameter.getType()); + assertTrue(parameter.isIdentifying()); + } + @Test void testGetParametersWithDoubleValueDeclaredAsLong() { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBeanTests.java index fa7cef0e7c..5f8b13913b 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBeanTests.java @@ -54,8 +54,8 @@ class JobExplorerFactoryBeanTests { void setUp() { factory = new JobExplorerFactoryBean(); - DataSource dataSource = mock(DataSource.class); - PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class); + DataSource dataSource = mock(); + PlatformTransactionManager transactionManager = mock(); factory.setDataSource(dataSource); factory.setTransactionManager(transactionManager); factory.setTablePrefix(tablePrefix); @@ -73,7 +73,7 @@ void testDefaultJdbcOperations() throws Exception { @Test void testCustomJdbcOperations() throws Exception { - JdbcOperations customJdbcOperations = mock(JdbcOperations.class); + JdbcOperations customJdbcOperations = mock(); factory.setJdbcOperations(customJdbcOperations); factory.afterPropertiesSet(); assertEquals(customJdbcOperations, ReflectionTestUtils.getField(factory, "jdbcOperations")); @@ -111,7 +111,7 @@ void testCreateExplorer() throws Exception { @Test public void testCustomTransactionAttributesSource() throws Exception { // given - TransactionAttributeSource transactionAttributeSource = Mockito.mock(TransactionAttributeSource.class); + TransactionAttributeSource transactionAttributeSource = Mockito.mock(); this.factory.setTransactionAttributeSource(transactionAttributeSource); this.factory.afterPropertiesSet(); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java index 8b275d9c7d..7e7122d0b0 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java @@ -65,10 +65,10 @@ class SimpleJobExplorerTests { @BeforeEach void setUp() { - jobExecutionDao = mock(JobExecutionDao.class); - jobInstanceDao = mock(JobInstanceDao.class); - stepExecutionDao = mock(StepExecutionDao.class); - ecDao = mock(ExecutionContextDao.class); + jobExecutionDao = mock(); + jobInstanceDao = mock(); + stepExecutionDao = mock(); + ecDao = mock(); jobExplorer = new SimpleJobExplorer(jobInstanceDao, jobExecutionDao, stepExecutionDao, ecDao); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/CompositeJobParametersValidatorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/CompositeJobParametersValidatorTests.java index 767df315e3..93694fc764 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/CompositeJobParametersValidatorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/CompositeJobParametersValidatorTests.java @@ -52,7 +52,7 @@ void testValidatorsCanNotBeEmpty() { @Test void testDelegateIsInvoked() throws JobParametersInvalidException { - JobParametersValidator validator = mock(JobParametersValidator.class); + JobParametersValidator validator = mock(); validator.validate(parameters); compositeJobParametersValidator.setValidators(Arrays.asList(validator)); compositeJobParametersValidator.validate(parameters); @@ -60,7 +60,7 @@ void testDelegateIsInvoked() throws JobParametersInvalidException { @Test void testDelegatesAreInvoked() throws JobParametersInvalidException { - JobParametersValidator validator = mock(JobParametersValidator.class); + JobParametersValidator validator = mock(); validator.validate(parameters); validator.validate(parameters); compositeJobParametersValidator.setValidators(Arrays.asList(validator, validator)); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java index ff0ea2a720..29b359ab47 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java @@ -416,7 +416,7 @@ void testRestart() throws Exception { void testInterruptWithListener() { step1.setProcessException(new JobInterruptedException("job interrupted!")); - JobExecutionListener listener = mock(JobExecutionListener.class); + JobExecutionListener listener = mock(); listener.beforeJob(jobExecution); listener.afterJob(jobExecution); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java index cfe457aae1..dd47b49999 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test; +import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInterruptedException; @@ -34,26 +35,79 @@ import org.springframework.batch.core.step.StepSupport; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; /** * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine + * @author Injae Kim * */ class FlowBuilderTests { @Test - void test() throws Exception { + void testNext() throws Exception { FlowBuilder builder = new FlowBuilder<>("flow"); JobRepository jobRepository = new JobRepositorySupport(); JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); - builder.start(new StepSupport("step") { - @Override - public void execute(StepExecution stepExecution) - throws JobInterruptedException, UnexpectedJobExecutionException { - } - }).end().start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + builder.next(createCompleteStep("stepA")) + .end() + .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + Iterator stepExecutions = execution.getStepExecutions().iterator(); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertFalse(stepExecutions.hasNext()); + } + + @Test + void testMultipleNext() throws Exception { + FlowBuilder builder = new FlowBuilder<>("flow"); + JobRepository jobRepository = new JobRepositorySupport(); + JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); + + builder.next(createCompleteStep("stepA")) + .next(createCompleteStep("stepB")) + .next(createCompleteStep("stepC")) + .end() + .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + Iterator stepExecutions = execution.getStepExecutions().iterator(); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertEquals(stepExecutions.next().getStepName(), "stepB"); + assertEquals(stepExecutions.next().getStepName(), "stepC"); + assertFalse(stepExecutions.hasNext()); + } + + @Test + void testStart() throws Exception { + FlowBuilder builder = new FlowBuilder<>("flow"); + JobRepository jobRepository = new JobRepositorySupport(); + JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); + + builder.start(createCompleteStep("stepA")) + .end() + .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + Iterator stepExecutions = execution.getStepExecutions().iterator(); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertFalse(stepExecutions.hasNext()); + } + + @Test + void testFrom() throws Exception { + FlowBuilder builder = new FlowBuilder<>("flow"); + JobRepository jobRepository = new JobRepositorySupport(); + JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); + + builder.from(createCompleteStep("stepA")) + .end() + .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + Iterator stepExecutions = execution.getStepExecutions().iterator(); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertFalse(stepExecutions.hasNext()); } @Test @@ -66,7 +120,7 @@ void testTransitionOrdering() throws Exception { @Override public void execute(StepExecution stepExecution) throws JobInterruptedException, UnexpectedJobExecutionException { - stepExecution.setExitStatus(new ExitStatus("FAILED")); + stepExecution.setExitStatus(ExitStatus.FAILED); } }; @@ -94,10 +148,20 @@ public void execute(StepExecution stepExecution) .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); Iterator stepExecutions = execution.getStepExecutions().iterator(); - StepExecution stepExecutionA = stepExecutions.next(); - assertEquals(stepExecutionA.getStepName(), "stepA"); - StepExecution stepExecutionC = stepExecutions.next(); - assertEquals(stepExecutionC.getStepName(), "stepC"); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertEquals(stepExecutions.next().getStepName(), "stepC"); + assertFalse(stepExecutions.hasNext()); + } + + private static StepSupport createCompleteStep(String name) { + return new StepSupport(name) { + @Override + public void execute(StepExecution stepExecution) + throws JobInterruptedException, UnexpectedJobExecutionException { + stepExecution.upgradeStatus(BatchStatus.COMPLETED); + stepExecution.setExitStatus(ExitStatus.COMPLETED); + } + }; } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java index 3b1068d225..34c8663548 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java @@ -142,6 +142,15 @@ void testBuildSingleFlow() { assertEquals(2, execution.getStepExecutions().size()); } + @Test + void testBuildSingleFlowAddingStepsViaNext() { + Flow flow = new FlowBuilder("subflow").next(step1).next(step2).build(); + FlowJobBuilder builder = new JobBuilder("flow", jobRepository).start(flow).end().preventRestart(); + builder.build().execute(execution); + assertEquals(BatchStatus.COMPLETED, execution.getStatus()); + assertEquals(2, execution.getStepExecutions().size()); + } + @Test void testBuildOverTwoLines() { FlowJobBuilder builder = new JobBuilder("flow", jobRepository).start(step1).on("COMPLETED").to(step2).end(); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/SplitStateTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/SplitStateTests.java index 0e89afd8d8..c864d1fbab 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/SplitStateTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/SplitStateTests.java @@ -43,8 +43,8 @@ class SplitStateTests { void testBasicHandling() throws Exception { Collection flows = new ArrayList<>(); - Flow flow1 = mock(Flow.class); - Flow flow2 = mock(Flow.class); + Flow flow1 = mock(); + Flow flow2 = mock(); flows.add(flow1); flows.add(flow2); @@ -61,8 +61,8 @@ void testBasicHandling() throws Exception { @Test void testConcurrentHandling() throws Exception { - Flow flow1 = mock(Flow.class); - Flow flow2 = mock(Flow.class); + Flow flow1 = mock(); + Flow flow2 = mock(); SplitState state = new SplitState(Arrays.asList(flow1, flow2), "foo"); state.setTaskExecutor(new SimpleAsyncTaskExecutor()); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/TaskExecutorJobLauncherTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/TaskExecutorJobLauncherTests.java index a1109852c6..2d8863826e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/TaskExecutorJobLauncherTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/TaskExecutorJobLauncherTests.java @@ -72,7 +72,7 @@ public void execute(JobExecution execution) { void setUp() { jobLauncher = new TaskExecutorJobLauncher(); - jobRepository = mock(JobRepository.class); + jobRepository = mock(); jobLauncher.setJobRepository(jobRepository); } @@ -265,13 +265,13 @@ void testRunStepStatusStopping() { private void testRestartStepExecutionInvalidStatus(BatchStatus status) throws Exception { String jobName = "test_job"; - JobRepository jobRepository = mock(JobRepository.class); + JobRepository jobRepository = mock(); JobParameters parameters = new JobParametersBuilder().addLong("runtime", System.currentTimeMillis()) .toJobParameters(); - JobExecution jobExecution = mock(JobExecution.class); - Job job = mock(Job.class); - JobParametersValidator validator = mock(JobParametersValidator.class); - StepExecution stepExecution = mock(StepExecution.class); + JobExecution jobExecution = mock(); + Job job = mock(); + JobParametersValidator validator = mock(); + StepExecution stepExecution = mock(); when(job.getName()).thenReturn(jobName); when(job.isRestartable()).thenReturn(true); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementerTests.java index 60d55e1680..a56457d06f 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementerTests.java @@ -31,7 +31,7 @@ */ class DataFieldMaxValueJobParametersIncrementerTests { - private final DataFieldMaxValueIncrementer incrementer = mock(DataFieldMaxValueIncrementer.class); + private final DataFieldMaxValueIncrementer incrementer = mock(); @Test void testInvalidKey() { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBeanTests.java index b984fe438e..c09cbe5925 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBeanTests.java @@ -39,17 +39,17 @@ */ class JobOperatorFactoryBeanTests { - private final PlatformTransactionManager transactionManager = Mockito.mock(PlatformTransactionManager.class); + private final PlatformTransactionManager transactionManager = Mockito.mock(); - private final JobRepository jobRepository = Mockito.mock(JobRepository.class); + private final JobRepository jobRepository = Mockito.mock(); - private final JobLauncher jobLauncher = Mockito.mock(JobLauncher.class); + private final JobLauncher jobLauncher = Mockito.mock(); - private final JobRegistry jobRegistry = Mockito.mock(JobRegistry.class); + private final JobRegistry jobRegistry = Mockito.mock(); - private final JobExplorer jobExplorer = Mockito.mock(JobExplorer.class); + private final JobExplorer jobExplorer = Mockito.mock(); - private final JobParametersConverter jobParametersConverter = Mockito.mock(JobParametersConverter.class); + private final JobParametersConverter jobParametersConverter = Mockito.mock(); @Test public void testJobOperatorCreation() throws Exception { @@ -76,7 +76,7 @@ public void testJobOperatorCreation() throws Exception { @Test public void testCustomTransactionAttributesSource() throws Exception { // given - TransactionAttributeSource transactionAttributeSource = Mockito.mock(TransactionAttributeSource.class); + TransactionAttributeSource transactionAttributeSource = Mockito.mock(); JobOperatorFactoryBean jobOperatorFactoryBean = new JobOperatorFactoryBean(); jobOperatorFactoryBean.setTransactionManager(this.transactionManager); jobOperatorFactoryBean.setJobLauncher(this.jobLauncher); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java index 32f01dae7a..d5d3951c2c 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java @@ -120,11 +120,11 @@ public Set getJobNames() { jobOperator.setJobLauncher( (job, jobParameters) -> new JobExecution(new JobInstance(123L, job.getName()), 999L, jobParameters)); - jobExplorer = mock(JobExplorer.class); + jobExplorer = mock(); jobOperator.setJobExplorer(jobExplorer); - jobRepository = mock(JobRepository.class); + jobRepository = mock(); jobOperator.setJobRepository(jobRepository); jobOperator.setJobParametersConverter(new DefaultJobParametersConverter() { @@ -288,7 +288,7 @@ public void testGetJobInstanceWithNameAndParameters() { // given String jobName = "job"; JobParameters jobParameters = new JobParameters(); - JobInstance jobInstance = mock(JobInstance.class); + JobInstance jobInstance = mock(); // when when(this.jobExplorer.getJobInstance(jobName, jobParameters)).thenReturn(jobInstance); @@ -338,14 +338,14 @@ void testStop() throws Exception { void testStopTasklet() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); - StoppableTasklet tasklet = mock(StoppableTasklet.class); + StoppableTasklet tasklet = mock(); TaskletStep taskletStep = new TaskletStep(); taskletStep.setTasklet(tasklet); MockJob job = new MockJob(); job.taskletStep = taskletStep; - JobRegistry jobRegistry = mock(JobRegistry.class); - TaskletStep step = mock(TaskletStep.class); + JobRegistry jobRegistry = mock(); + TaskletStep step = mock(); when(step.getTasklet()).thenReturn(tasklet); when(step.getName()).thenReturn("test_job.step1"); @@ -363,9 +363,9 @@ void testStopTasklet() throws Exception { void testStopTaskletWhenJobNotRegistered() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); - StoppableTasklet tasklet = mock(StoppableTasklet.class); - JobRegistry jobRegistry = mock(JobRegistry.class); - TaskletStep step = mock(TaskletStep.class); + StoppableTasklet tasklet = mock(); + JobRegistry jobRegistry = mock(); + TaskletStep step = mock(); when(step.getTasklet()).thenReturn(tasklet); when(jobRegistry.getJob(job.getName())).thenThrow(new NoSuchJobException("Unable to find job")); @@ -399,8 +399,8 @@ public void stop() { MockJob job = new MockJob(); job.taskletStep = taskletStep; - JobRegistry jobRegistry = mock(JobRegistry.class); - TaskletStep step = mock(TaskletStep.class); + JobRegistry jobRegistry = mock(); + TaskletStep step = mock(); when(step.getTasklet()).thenReturn(tasklet); when(step.getName()).thenReturn("test_job.step1"); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeChunkListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeChunkListenerTests.java index 3d1284b060..1ae514a1a1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeChunkListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeChunkListenerTests.java @@ -39,7 +39,7 @@ class CompositeChunkListenerTests { @BeforeEach void setUp() { chunkContext = new ChunkContext(null); - listener = mock(ChunkListener.class); + listener = mock(); compositeListener = new CompositeChunkListener(); compositeListener.register(listener); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemProcessListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemProcessListenerTests.java index ed00b162a4..c9703acad0 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemProcessListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemProcessListenerTests.java @@ -37,7 +37,7 @@ class CompositeItemProcessListenerTests { @SuppressWarnings("unchecked") @BeforeEach void setUp() { - listener = mock(ItemProcessListener.class); + listener = mock(); compositeListener = new CompositeItemProcessListener<>(); compositeListener.register(listener); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemReadListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemReadListenerTests.java index f559b8a3ca..ac9bd41bac 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemReadListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemReadListenerTests.java @@ -38,7 +38,7 @@ class CompositeItemReadListenerTests { @SuppressWarnings("unchecked") @BeforeEach void setUp() { - listener = mock(ItemReadListener.class); + listener = mock(); compositeListener = new CompositeItemReadListener<>(); compositeListener.register(listener); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemWriteListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemWriteListenerTests.java index 714f48bc32..6531b4ef35 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemWriteListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemWriteListenerTests.java @@ -40,7 +40,7 @@ class CompositeItemWriteListenerTests { @SuppressWarnings("unchecked") @BeforeEach void setUp() { - listener = mock(ItemWriteListener.class); + listener = mock(); compositeListener = new CompositeItemWriteListener<>(); compositeListener.register(listener); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDaoTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDaoTests.java index d43b250122..b7f69611bc 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDaoTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDaoTests.java @@ -30,7 +30,7 @@ class JdbcExecutionContextDaoTests extends AbstractExecutionContextDaoTests { @Test void testNullSerializer() { JdbcExecutionContextDao jdbcExecutionContextDao = new JdbcExecutionContextDao(); - jdbcExecutionContextDao.setJdbcTemplate(mock(JdbcOperations.class)); + jdbcExecutionContextDao.setJdbcTemplate(mock()); Exception exception = assertThrows(IllegalArgumentException.class, () -> jdbcExecutionContextDao.setSerializer(null)); assertEquals("Serializer must not be null", exception.getMessage()); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java index d28daf95a2..26591735c9 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java @@ -78,11 +78,11 @@ class JobRepositoryFactoryBeanTests { void setUp() { factory = new JobRepositoryFactoryBean(); - dataSource = mock(DataSource.class); - transactionManager = mock(PlatformTransactionManager.class); + dataSource = mock(); + transactionManager = mock(); factory.setDataSource(dataSource); factory.setTransactionManager(transactionManager); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); factory.setIncrementerFactory(incrementerFactory); factory.setTablePrefix(tablePrefix); @@ -91,8 +91,8 @@ void setUp() { @Test void testNoDatabaseType() throws Exception { - DatabaseMetaData dmd = mock(DatabaseMetaData.class); - Connection con = mock(Connection.class); + DatabaseMetaData dmd = mock(); + Connection con = mock(); when(dataSource.getConnection()).thenReturn(con); when(con.getMetaData()).thenReturn(dmd); when(dmd.getDatabaseProductName()).thenReturn("Oracle"); @@ -115,7 +115,7 @@ void testOracleLobHandler() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -135,7 +135,7 @@ void testCustomLobHandler() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -158,7 +158,7 @@ void tesDefaultSerializer() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -178,7 +178,7 @@ void testCustomSerializer() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -199,7 +199,7 @@ void testDefaultJdbcOperations() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -219,7 +219,7 @@ void testCustomJdbcOperations() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -228,7 +228,7 @@ void testCustomJdbcOperations() throws Exception { .thenReturn(new StubIncrementer()); factory.setIncrementerFactory(incrementerFactory); - JdbcOperations customJdbcOperations = mock(JdbcOperations.class); + JdbcOperations customJdbcOperations = mock(); factory.setJdbcOperations(customJdbcOperations); factory.afterPropertiesSet(); @@ -313,7 +313,7 @@ void testTransactionAttributesForCreateMethod() throws Exception { DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW); transactionDefinition.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_SERIALIZABLE); when(transactionManager.getTransaction(transactionDefinition)).thenReturn(null); - Connection conn = mock(Connection.class); + Connection conn = mock(); when(dataSource.getConnection()).thenReturn(conn); Exception exception = assertThrows(IllegalArgumentException.class, () -> repository.createJobExecution("foo", new JobParameters())); @@ -331,7 +331,7 @@ void testSetTransactionAttributesForCreateMethod() throws Exception { DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW); transactionDefinition.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_READ_UNCOMMITTED); when(transactionManager.getTransaction(transactionDefinition)).thenReturn(null); - Connection conn = mock(Connection.class); + Connection conn = mock(); when(dataSource.getConnection()).thenReturn(conn); Exception exception = assertThrows(IllegalArgumentException.class, () -> repository.createJobExecution("foo", new JobParameters())); @@ -341,7 +341,7 @@ void testSetTransactionAttributesForCreateMethod() throws Exception { @Test public void testCustomTransactionAttributesSource() throws Exception { // given - TransactionAttributeSource transactionAttributeSource = Mockito.mock(TransactionAttributeSource.class); + TransactionAttributeSource transactionAttributeSource = Mockito.mock(); this.factory.setTransactionAttributeSource(transactionAttributeSource); // when diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java index 53c33b178e..eb81dbd246 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2022 the original author or authors. + * Copyright 2008-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,12 +32,13 @@ import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; -import java.util.Arrays; +import java.util.List; +import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; /** * Repository tests using JDBC DAOs (rather than mocks). @@ -152,11 +153,7 @@ void testGetStepExecutionCountAndLastStepExecution() throws Exception { @Transactional @Test void testSaveExecutionContext() throws Exception { - ExecutionContext ctx = new ExecutionContext() { - { - putLong("crashedPosition", 7); - } - }; + ExecutionContext ctx = new ExecutionContext(Map.of("crashedPosition", 7)); JobExecution jobExec = jobRepository.createJobExecution(job.getName(), jobParameters); jobExec.setStartTime(LocalDateTime.now()); jobExec.setExecutionContext(ctx); @@ -169,11 +166,6 @@ void testSaveExecutionContext() throws Exception { StepExecution retrievedStepExec = jobRepository.getLastStepExecution(jobExec.getJobInstance(), step.getName()); assertEquals(stepExec, retrievedStepExec); assertEquals(ctx, retrievedStepExec.getExecutionContext()); - - // JobExecution retrievedJobExec = - // jobRepository.getLastJobExecution(jobExec.getJobInstance()); - // assertEquals(jobExec, retrievedJobExec); - // assertEquals(ctx, retrievedJobExec.getExecutionContext()); } /* @@ -205,7 +197,7 @@ void testGetLastJobExecution() throws Exception { jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters); StepExecution stepExecution = new StepExecution("step1", jobExecution); jobRepository.add(stepExecution); - jobExecution.addStepExecutions(Arrays.asList(stepExecution)); + jobExecution.addStepExecutions(List.of(stepExecution)); assertEquals(jobExecution, jobRepository.getLastJobExecution(job.getName(), jobParameters)); assertEquals(stepExecution, jobExecution.getStepExecutions().iterator().next()); } @@ -233,42 +225,41 @@ void testReExecuteWithSameJobParameters() throws Exception { */ @Transactional @Test - public void testReExecuteWithSameJobParametersWhenRunning() throws Exception { + void testReExecuteWithSameJobParametersWhenRunning() throws Exception { JobParameters jobParameters = new JobParametersBuilder().addString("stringKey", "stringValue") .toJobParameters(); // jobExecution with status STARTING JobExecution jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters); - try { - jobRepository.createJobExecution(job.getName(), jobParameters); - fail(); - } - catch (JobExecutionAlreadyRunningException e) { - // expected - } + assertThrows(JobExecutionAlreadyRunningException.class, + () -> jobRepository.createJobExecution(job.getName(), jobParameters)); // jobExecution with status STARTED jobExecution.setStatus(BatchStatus.STARTED); jobExecution.setStartTime(LocalDateTime.now()); jobRepository.update(jobExecution); - try { - jobRepository.createJobExecution(job.getName(), jobParameters); - fail(); - } - catch (JobExecutionAlreadyRunningException e) { - // expected - } + assertThrows(JobExecutionAlreadyRunningException.class, + () -> jobRepository.createJobExecution(job.getName(), jobParameters)); // jobExecution with status STOPPING jobExecution.setStatus(BatchStatus.STOPPING); jobRepository.update(jobExecution); - try { - jobRepository.createJobExecution(job.getName(), jobParameters); - fail(); - } - catch (JobExecutionAlreadyRunningException e) { - // expected - } + assertThrows(JobExecutionAlreadyRunningException.class, + () -> jobRepository.createJobExecution(job.getName(), jobParameters)); + } + + @Transactional + @Test + void testDeleteJobInstance() throws Exception { + var jobParameters = new JobParametersBuilder().addString("foo", "bar").toJobParameters(); + var jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters); + var stepExecution = new StepExecution("step", jobExecution); + jobRepository.add(stepExecution); + + jobRepository.deleteJobInstance(jobExecution.getJobInstance()); + + assertEquals(0, jobRepository.findJobInstancesByName(job.getName(), 0, 1).size()); + assertNull(jobRepository.getLastJobExecution(job.getName(), jobParameters)); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java index 99d0429e42..5b903d0f14 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java @@ -96,10 +96,10 @@ class SimpleJobRepositoryTests { @BeforeEach void setUp() { - jobExecutionDao = mock(JobExecutionDao.class); - jobInstanceDao = mock(JobInstanceDao.class); - stepExecutionDao = mock(StepExecutionDao.class); - ecDao = mock(ExecutionContextDao.class); + jobExecutionDao = mock(); + jobInstanceDao = mock(); + stepExecutionDao = mock(); + ecDao = mock(); jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao, ecDao); @@ -348,9 +348,9 @@ public void testGetJobInstanceWithNameAndParameters() { @Test void testDeleteJobExecution() { // given - StepExecution stepExecution1 = mock(StepExecution.class); - StepExecution stepExecution2 = mock(StepExecution.class); - JobExecution jobExecution = mock(JobExecution.class); + StepExecution stepExecution1 = mock(); + StepExecution stepExecution2 = mock(); + JobExecution jobExecution = mock(); when(jobExecution.getStepExecutions()).thenReturn(Arrays.asList(stepExecution1, stepExecution2)); // when @@ -369,9 +369,9 @@ void testDeleteJobExecution() { @Test void testDeleteJobInstance() { // given - JobExecution jobExecution1 = mock(JobExecution.class); - JobExecution jobExecution2 = mock(JobExecution.class); - JobInstance jobInstance = mock(JobInstance.class); + JobExecution jobExecution1 = mock(); + JobExecution jobExecution2 = mock(); + JobInstance jobInstance = mock(); when(this.jobExecutionDao.findJobExecutions(jobInstance)) .thenReturn(Arrays.asList(jobExecution1, jobExecution2)); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilderTests.java new file mode 100644 index 0000000000..6cd6f2374e --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilderTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.step.builder; + +import org.junit.jupiter.api.Test; + +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.tasklet.TaskletStep; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.transaction.PlatformTransactionManager; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.Mockito.mock; + +/** + * Test cases for verifying the {@link AbstractTaskletStepBuilder} and faultTolerant() + * functionality. + * + * Issue: https://github.com/spring-projects/spring-batch/issues/4438 + * + * @author Ilpyo Yang + * @author Mahmoud Ben Hassine + */ +public class AbstractTaskletStepBuilderTests { + + private final JobRepository jobRepository = mock(JobRepository.class); + + private final PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class); + + private final int chunkSize = 10; + + private final ItemReader itemReader = mock(ItemReader.class); + + private final ItemProcessor itemProcessor = mock(ItemProcessor.class); + + private final ItemWriter itemWriter = mock(ItemWriter.class); + + private final SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); + + @Test + void testSetTaskExecutorBeforeFaultTolerant() { + TaskletStep step = new StepBuilder("step-name", jobRepository) + .chunk(chunkSize, transactionManager) + .taskExecutor(taskExecutor) + .reader(itemReader) + .processor(itemProcessor) + .writer(itemWriter) + .faultTolerant() + .build(); + + Object stepOperations = ReflectionTestUtils.getField(step, "stepOperations"); + assertInstanceOf(TaskExecutorRepeatTemplate.class, stepOperations); + } + + @Test + void testSetTaskExecutorAfterFaultTolerant() { + TaskletStep step = new StepBuilder("step-name", jobRepository) + .chunk(chunkSize, transactionManager) + .reader(itemReader) + .processor(itemProcessor) + .writer(itemWriter) + .faultTolerant() + .taskExecutor(taskExecutor) + .build(); + + Object stepOperations = ReflectionTestUtils.getField(step, "stepOperations"); + assertInstanceOf(TaskExecutorRepeatTemplate.class, stepOperations); + } + +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessorTests.java index 5070b277a4..d30e06917e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the original author or authors. + * Copyright 2008-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.util.ArrayList; @@ -97,6 +98,16 @@ public String process(String item) throws Exception { assertEquals(1, contribution.getFilterCount()); } + @Test + void testTransformChunkEnd() throws Exception { + Chunk inputs = new Chunk<>(Arrays.asList("1", "2")); + inputs.setEnd(); + processor.initializeUserData(inputs); + Chunk outputs = processor.transform(contribution, inputs); + assertEquals(Arrays.asList("1", "2"), outputs.getItems()); + assertTrue(outputs.isEnd()); + } + @Test void testFilterCountOnSkip() throws Exception { processor.setProcessSkipPolicy(new AlwaysSkipItemSkipPolicy()); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java index f775d86cf7..78e138272c 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java @@ -88,7 +88,7 @@ void setUp() throws Exception { @Test void testSkip() throws Exception { @SuppressWarnings("unchecked") - SkipListener skipListener = mock(SkipListener.class); + SkipListener skipListener = mock(); skipListener.onSkipInWrite("3", exception); skipListener.onSkipInWrite("4", exception); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleChunkProcessorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleChunkProcessorTests.java index e9a7e0e678..5ebcb49ced 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleChunkProcessorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleChunkProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the original author or authors. + * Copyright 2008-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.batch.core.step.item; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.Arrays; @@ -76,4 +77,15 @@ void testProcess() throws Exception { assertEquals(2, contribution.getWriteCount()); } + @Test + void testTransform() throws Exception { + Chunk inputs = new Chunk<>(); + inputs.add("foo"); + inputs.add("bar"); + inputs.setEnd(); + Chunk outputs = processor.transform(contribution, inputs); + assertEquals(Arrays.asList("foo", "bar"), outputs.getItems()); + assertTrue(outputs.isEnd()); + } + } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractorTests.java index 1f124694d1..c94a6d2de5 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,12 @@ import org.junit.jupiter.api.Test; import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.StepExecution; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -109,4 +111,25 @@ void testDontUseParentParameters() { assertNotNull(jobParameters.getParameter("foo").getValue()); } + @Test + public void testGetKeysFromParentParametersWhenNotInExecutionContext() { + DefaultJobParametersExtractor extractor = new DefaultJobParametersExtractor(); + extractor.setUseAllParentParameters(false); + + JobExecution jobExecution = new JobExecution(0L, + new JobParametersBuilder().addString("parentParam", "val").addDouble("foo", 22.2).toJobParameters()); + + StepExecution stepExecution = new StepExecution("step", jobExecution); + + stepExecution.getExecutionContext().put("foo", "11.1,java.lang.Double"); + extractor.setKeys(new String[] { "foo", "parentParam" }); + + JobParameters jobParameters = extractor.getJobParameters(null, stepExecution); + + assertThat(jobParameters.getParameter("parentParam")).isNotNull() + .extracting(JobParameter::getValue) + .isEqualTo("val"); + assertEquals(11.1, jobParameters.getDouble("foo")); + } + } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/MethodInvokingTaskletAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/MethodInvokingTaskletAdapterTests.java index 5adc41058a..246e91bdc1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/MethodInvokingTaskletAdapterTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/MethodInvokingTaskletAdapterTests.java @@ -42,8 +42,8 @@ class MethodInvokingTaskletAdapterTests { @BeforeEach void setUp() { - stepContribution = new StepContribution(mock(StepExecution.class)); - chunkContext = mock(ChunkContext.class); + stepContribution = new StepContribution(mock()); + chunkContext = mock(); tasklet = new TestTasklet(); adapter = new MethodInvokingTaskletAdapter(); adapter.setTargetObject(tasklet); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java index f4b401ba3e..b703d91ee3 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the original author or authors. + * Copyright 2008-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -292,8 +292,8 @@ private boolean isRunningOnWindows() { @Test public void testExecuteWithSuccessfulCommandRunnerMockExecution() throws Exception { StepContribution stepContribution = stepExecution.createStepContribution(); - CommandRunner commandRunner = mock(CommandRunner.class); - Process process = mock(Process.class); + CommandRunner commandRunner = mock(); + Process process = mock(); String[] command = new String[] { "invalid command" }; when(commandRunner.exec(eq(command), any(), any())).thenReturn(process); @@ -312,8 +312,8 @@ public void testExecuteWithSuccessfulCommandRunnerMockExecution() throws Excepti @Test public void testExecuteWithFailedCommandRunnerMockExecution() throws Exception { StepContribution stepContribution = stepExecution.createStepContribution(); - CommandRunner commandRunner = mock(CommandRunner.class); - Process process = mock(Process.class); + CommandRunner commandRunner = mock(); + Process process = mock(); String[] command = new String[] { "invalid command" }; when(commandRunner.exec(eq(command), any(), any())).thenReturn(process); @@ -323,9 +323,8 @@ public void testExecuteWithFailedCommandRunnerMockExecution() throws Exception { tasklet.setCommand(command); tasklet.afterPropertiesSet(); - RepeatStatus exitStatus = tasklet.execute(stepContribution, null); - - assertEquals(RepeatStatus.FINISHED, exitStatus); + Exception exception = assertThrows(SystemCommandException.class, () -> tasklet.execute(stepContribution, null)); + assertTrue(exception.getMessage().contains("failed with exit code")); assertEquals(ExitStatus.FAILED, stepContribution.getExitStatus()); } diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index f59eb521be..a437241444 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.7-SNAPSHOT spring-batch-docs Spring Batch Docs diff --git a/spring-batch-docs/src/main/asciidoc/domain.adoc b/spring-batch-docs/src/main/asciidoc/domain.adoc index c544b10539..10f78d4284 100644 --- a/spring-batch-docs/src/main/asciidoc/domain.adoc +++ b/spring-batch-docs/src/main/asciidoc/domain.adoc @@ -557,6 +557,12 @@ As noted in the comment, `ecStep` does not equal `ecJob`. They are two different `ExecutionContexts`. The one scoped to the `Step` is saved at every commit point in the `Step`, whereas the one scoped to the Job is saved in between every `Step` execution. +NOTE: In the `ExecutionContext`, all non-transient entries must be `Serializable`. +Proper serialization of the execution context underpins the restart capability of steps and jobs. +Should you use keys or values that are not natively serializable, you are required to +employ a tailored serialization approach. Failing to serialize the execution context +may jeopardize the state persistence process, making failed jobs impossible to recover properly. + === JobRepository `JobRepository` is the persistence mechanism for all of the stereotypes mentioned earlier. diff --git a/spring-batch-docs/src/main/asciidoc/images/meta-data-erd.png b/spring-batch-docs/src/main/asciidoc/images/meta-data-erd.png old mode 100755 new mode 100644 index ff099a67c4..4c2a858131 Binary files a/spring-batch-docs/src/main/asciidoc/images/meta-data-erd.png and b/spring-batch-docs/src/main/asciidoc/images/meta-data-erd.png differ diff --git a/spring-batch-docs/src/main/asciidoc/job.adoc b/spring-batch-docs/src/main/asciidoc/job.adoc index 94f3aab23c..91049567d7 100644 --- a/spring-batch-docs/src/main/asciidoc/job.adoc +++ b/spring-batch-docs/src/main/asciidoc/job.adoc @@ -449,6 +449,7 @@ public class MyJobConfiguration { return new JdbcTransactionManager(dataSource); } + @Bean public Job job(JobRepository jobRepository) { return new JobBuilder("myJob", jobRepository) //define job flow as needed diff --git a/spring-batch-docs/src/main/asciidoc/scalability.adoc b/spring-batch-docs/src/main/asciidoc/scalability.adoc index 4a387f8e5b..6d8928fa24 100644 --- a/spring-batch-docs/src/main/asciidoc/scalability.adoc +++ b/spring-batch-docs/src/main/asciidoc/scalability.adoc @@ -121,6 +121,29 @@ Note also that there may be limits placed on concurrency by any pooled resources your step, such as a `DataSource`. Be sure to make the pool in those resources at least as large as the desired number of concurrent threads in the step. +[WARNING] +.Throttle limit deprecation +==== +As of v5.0, the throttle limit is deprecated with no replacement. If you want to replace the +current throttling mechanism in the default `TaskExecutorRepeatTemplate`, you need to provide +a custom `RepeatOperations` implementation (based on a `TaskExecutor` with a bounded task queue) +and set it on the step with `StepBuilder#stepOperations`: + +.Java Configuration +[source, java] +---- +@Bean +public Step sampleStep(RepeatOperations customRepeatOperations, JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new StepBuilder("sampleStep", jobRepository) + .chunk(10, transactionManager) + .reader(itemReader()) + .writer(itemWriter()) + .stepOperations(customRepeatOperations) + .build(); +} +---- +==== + There are some practical limitations of using multi-threaded `Step` implementations for some common batch use cases. Many participants in a `Step` (such as readers and writers) are stateful. If the state is not segregated by thread, those components are not @@ -315,8 +338,8 @@ configuration: [source, java, role="javaContent"] ---- @Bean -public Step step1Manager() { - return stepBuilderFactory.get("step1.manager") +public Step step1Manager(JobRepository jobRepository) { + return new StepBuilder("step1.manager", jobRepository) .partitioner("step1", partitioner()) .step(step1()) .gridSize(10) diff --git a/spring-batch-docs/src/main/asciidoc/step.adoc b/spring-batch-docs/src/main/asciidoc/step.adoc index 9825377c7f..4c746bffe7 100644 --- a/spring-batch-docs/src/main/asciidoc/step.adoc +++ b/spring-batch-docs/src/main/asciidoc/step.adoc @@ -1184,9 +1184,10 @@ public interface ItemWriteListener extends StepListener { ---- The `beforeWrite` method is called before `write` on the `ItemWriter` and is handed the -list of items that is written. The `afterWrite` method is called after the item has been -successfully written. If there was an error while writing, the `onWriteError` method is -called. The exception encountered and the item that was attempted to be written are +list of items that is written. The `afterWrite` method is called after the items have been +successfully written, but before committing the transaction associated with the chunk's processing. +If there was an error while writing, the `onWriteError` method is called. +The exception encountered and the item that was attempted to be written are provided, so that they can be logged. The annotations corresponding to this interface are: @@ -1373,7 +1374,7 @@ public class FileDeletingTasklet implements Tasklet, InitializingBean { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { File dir = directory.getFile(); - Assert.state(dir.isDirectory()); + Assert.state(dir.isDirectory(), "The resource must be a directory"); File[] files = dir.listFiles(); for (int i = 0; i < files.length; i++) { @@ -1391,7 +1392,7 @@ public class FileDeletingTasklet implements Tasklet, InitializingBean { } public void afterPropertiesSet() throws Exception { - Assert.state(directory != null, "directory must be set"); + Assert.state(directory != null, "Directory must be set"); } } ---- @@ -1689,14 +1690,14 @@ the condition of the execution having skipped records, as the following example [source, java] ---- -public class SkipCheckingListener extends StepExecutionListenerSupport { +public class SkipCheckingListener implements StepExecutionListener { + @Override public ExitStatus afterStep(StepExecution stepExecution) { String exitCode = stepExecution.getExitStatus().getExitCode(); if (!exitCode.equals(ExitStatus.FAILED.getExitCode()) && - stepExecution.getSkipCount() > 0) { + stepExecution.getSkipCount() > 0) { return new ExitStatus("COMPLETED WITH SKIPS"); - } - else { + } else { return null; } } diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index 432a276385..3dc7b43bb2 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.7-SNAPSHOT spring-batch-infrastructure jar diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/Chunk.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/Chunk.java index 4cdfa1c7e6..aababa36c2 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/Chunk.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/Chunk.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -154,6 +154,13 @@ public int size() { /** * Flag to indicate if the source data is exhausted. + * + *

+ * Note: This may return false if the last chunk has the same number of items as the + * configured commit interval. Consequently, in such cases,there will be a last empty + * chunk that won't be processed. It is recommended to consider this behavior when + * utilizing this method. + *

* @return true if there is no more data to process */ public boolean isEnd() { diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ExecutionContext.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ExecutionContext.java index 49f0d348fb..393e31da42 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ExecutionContext.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ExecutionContext.java @@ -29,8 +29,9 @@ * that allows optionally for type safety on reads. It also allows for dirty checking by * setting a 'dirty' flag whenever any put is called. *

- * Note that putting null value is equivalent to removing the entry for the - * given key. + * Non-transient entries should be serializable, otherwise a custom serializer should be + * used. Note that putting null value is equivalent to removing the entry for + * the given key. * * @author Lucas Ward * @author Douglas Kaminsky diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactory.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactory.java index 098ff06eb5..2ec50d2dc8 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactory.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -114,25 +114,24 @@ private boolean isEndOfLine(StringBuilder buffer, StringBuilder candidate, int n } char c = (char) next; - if (ending.charAt(0) == c || candidate.length() > 0) { + if (ending.charAt(0) == c || !candidate.isEmpty()) { candidate.append(c); } - - if (candidate.length() == 0) { + else { buffer.append(c); return false; } - boolean end = ending.equals(candidate.toString()); - if (end) { + if (ending.contentEquals(candidate)) { candidate.delete(0, candidate.length()); + return true; } - else if (candidate.length() >= ending.length()) { - buffer.append(candidate); - candidate.delete(0, candidate.length()); + while (!ending.startsWith(candidate.toString())) { + buffer.append(candidate.charAt(0)); + candidate.delete(0, 1); } - return end; + return false; } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java index c0e833831c..4ec95e4d53 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java @@ -33,9 +33,9 @@ import org.springframework.util.StringUtils; /** - * Default implementation of {@link FieldSet} using Java using Java primitive and standard - * types and utilities. Strings are trimmed before parsing by default, and so are plain - * String values. + * Default implementation of {@link FieldSet} using Java primitive and standard types and + * utilities. Strings are trimmed before parsing by default, and so are plain String + * values. * * @author Rob Harrop * @author Dave Syer @@ -65,8 +65,8 @@ public class DefaultFieldSet implements FieldSet { private List names; /** - * The {@link NumberFormat} to use for parsing numbers. If unset the US locale will be - * used ('.' as decimal place). + * The {@link NumberFormat} to use for parsing numbers. If unset the {@link Locale#US} + * will be used ('.' as decimal place). * @param numberFormat the {@link NumberFormat} to use for number parsing */ public final void setNumberFormat(NumberFormat numberFormat) { @@ -78,8 +78,8 @@ public final void setNumberFormat(NumberFormat numberFormat) { } /** - * The {@link DateFormat} to use for parsing numbers. If unset the default pattern is - * ISO standard yyyy/MM/dd. + * The {@link DateFormat} to use for parsing dates. If unset the default pattern is + * ISO standard yyyy-MM-dd. * @param dateFormat the {@link DateFormat} to use for date parsing */ public void setDateFormat(DateFormat dateFormat) { diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSetFactory.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSetFactory.java index 7ef0fca1bb..a958f50a1f 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSetFactory.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSetFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2012 the original author or authors. + * Copyright 2009-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ * {@link FieldSet} required. Returns a {@link DefaultFieldSet} from both factory methods. * * @author Dave Syer + * @author Mahmoud Ben Hassine * */ public class DefaultFieldSetFactory implements FieldSetFactory { @@ -32,8 +33,8 @@ public class DefaultFieldSetFactory implements FieldSetFactory { private NumberFormat numberFormat; /** - * The {@link NumberFormat} to use for parsing numbers. If unset the default locale - * will be used. + * The {@link NumberFormat} to use for parsing numbers. If unset then + * {@link java.util.Locale#US} will be used. * @param numberFormat the {@link NumberFormat} to use for number parsing */ public void setNumberFormat(NumberFormat numberFormat) { @@ -41,8 +42,8 @@ public void setNumberFormat(NumberFormat numberFormat) { } /** - * The {@link DateFormat} to use for parsing numbers. If unset the default pattern is - * ISO standard yyyy/MM/dd. + * The {@link DateFormat} to use for parsing dates. If unset the default pattern is + * ISO standard yyyy-MM-dd. * @param dateFormat the {@link DateFormat} to use for date parsing */ public void setDateFormat(DateFormat dateFormat) { diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriter.java index 1964276b72..65cf843acb 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,8 +40,8 @@ * Delegates the actual sending of messages to a {@link MailSender}, using the batch * method {@link MailSender#send(SimpleMailMessage[])}, which normally uses a single * server connection for the whole batch (depending on the implementation). The efficiency - * of for large volumes of messages (repeated calls to the item writer) might be improved - * by the use of a special {@link MailSender} that caches connections to the server in + * for large volumes of messages (repeated calls to the item writer) might be improved by + * the use of a special {@link MailSender} that caches connections to the server in * between calls. *

* diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java index 4e81315d14..7b7af3fc68 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java @@ -286,8 +286,15 @@ private void doHandle(Throwable throwable, RepeatContext context, Collection { }); - Session session = mock(Session.class); - MessageConsumer consumer = mock(MessageConsumer.class); - Message message = mock(Message.class); + Session session = mock(); + MessageConsumer consumer = mock(); + Message message = mock(); // Expect two calls to consumer (chunk size)... when(session.getTransacted()).thenReturn(true); @@ -73,8 +73,8 @@ void testReceiveAndExecuteWithCallbackReturningNull() throws Exception { template.setCompletionPolicy(new SimpleCompletionPolicy(2)); container = getContainer(template); - Session session = mock(Session.class); - MessageConsumer consumer = mock(MessageConsumer.class); + Session session = mock(); + MessageConsumer consumer = mock(); Message message = null; // Expect one call to consumer (chunk size is 2 but terminates on @@ -119,7 +119,7 @@ void testNonTransactionalReceiveAndExecuteWithCallbackThrowingError() throws Exc } private BatchMessageListenerContainer getContainer(RepeatTemplate template) { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); + ConnectionFactory connectionFactory = mock(); // Yuck: we need to turn these method in base class to no-ops because the invoker // is a private class // we can't create for test purposes... @@ -151,9 +151,9 @@ private boolean doTestWithException(final Throwable t, boolean expectRollback, i throw (Error) t; }); - Session session = mock(Session.class); - MessageConsumer consumer = mock(MessageConsumer.class); - Message message = mock(Message.class); + Session session = mock(); + MessageConsumer consumer = mock(); + Message message = mock(); if (expectGetTransactionCount > 0) { when(session.getTransacted()).thenReturn(true); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemReaderTests.java index 3838ef6463..a941cd276b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemReaderTests.java @@ -44,7 +44,7 @@ void testNullAmqpTemplate() { @Test void testNoItemType() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + final AmqpTemplate amqpTemplate = mock(); when(amqpTemplate.receiveAndConvert()).thenReturn("foo"); final AmqpItemReader amqpItemReader = new AmqpItemReader<>(amqpTemplate); @@ -53,7 +53,7 @@ void testNoItemType() { @Test void testNonMessageItemType() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + final AmqpTemplate amqpTemplate = mock(); when(amqpTemplate.receiveAndConvert()).thenReturn("foo"); final AmqpItemReader amqpItemReader = new AmqpItemReader<>(amqpTemplate); @@ -65,8 +65,8 @@ void testNonMessageItemType() { @Test void testMessageItemType() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); - final Message message = mock(Message.class); + final AmqpTemplate amqpTemplate = mock(); + final Message message = mock(); when(amqpTemplate.receive()).thenReturn(message); @@ -79,7 +79,7 @@ void testMessageItemType() { @Test void testTypeMismatch() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + final AmqpTemplate amqpTemplate = mock(); when(amqpTemplate.receiveAndConvert()).thenReturn("foo"); @@ -93,7 +93,7 @@ void testTypeMismatch() { @Test void testNullItemType() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + final AmqpTemplate amqpTemplate = mock(); final AmqpItemReader amqpItemReader = new AmqpItemReader<>(amqpTemplate); assertThrows(IllegalArgumentException.class, () -> amqpItemReader.setItemType(null)); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemWriterTests.java index eb81d9139e..49b505c3a0 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemWriterTests.java @@ -42,7 +42,7 @@ void testNullAmqpTemplate() { @Test void voidTestWrite() throws Exception { - AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + AmqpTemplate amqpTemplate = mock(); amqpTemplate.convertAndSend("foo"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilderTests.java index 40efe3f763..bba60288b7 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilderTests.java @@ -59,7 +59,7 @@ void testNonMessageItemType() { @Test void testMessageItemType() { - final Message message = mock(Message.class); + final Message message = mock(); when(this.amqpTemplate.receive()).thenReturn(message); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilderTests.java index 493c8f4368..c5bc741ce7 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilderTests.java @@ -43,7 +43,7 @@ void testNullAmqpTemplate() { @Test void voidTestWrite() throws Exception { - AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + AmqpTemplate amqpTemplate = mock(); AmqpItemWriter amqpItemWriter = new AmqpItemWriterBuilder().amqpTemplate(amqpTemplate).build(); amqpItemWriter.write(Chunk.of("foo", "bar")); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java index 208ceb3bb8..eaedf43165 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java @@ -252,9 +252,9 @@ void testResourceKeyCollision() { final String[] results = new String[limit]; for (int i = 0; i < limit; i++) { final int index = i; - MongoOperations mongoOperations = mock(MongoOperations.class); - BulkOperations bulkOperations = mock(BulkOperations.class); - MongoConverter mongoConverter = mock(MongoConverter.class); + MongoOperations mongoOperations = mock(); + BulkOperations bulkOperations = mock(); + MongoConverter mongoConverter = mock(); when(mongoOperations.bulkOps(any(), any(Class.class))).thenReturn(bulkOperations); when(mongoOperations.getConverter()).thenReturn(mongoConverter); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java index 70b49f668a..8513ebf26f 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java @@ -228,7 +228,7 @@ void testInvalidMethodName() { @Test void testDifferentTypes() throws Exception { - TestRepository differentRepository = mock(TestRepository.class); + TestRepository differentRepository = mock(); RepositoryItemReader reader = new RepositoryItemReader<>(); sorts = Collections.singletonMap("id", Direction.ASC); reader.setRepository(differentRepository); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/ExtendedConnectionDataSourceProxyTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/ExtendedConnectionDataSourceProxyTests.java index 0439f2ad22..dc362b28ce 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/ExtendedConnectionDataSourceProxyTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/ExtendedConnectionDataSourceProxyTests.java @@ -48,8 +48,8 @@ class ExtendedConnectionDataSourceProxyTests { @Test void testOperationWithDataSourceUtils() throws SQLException { - Connection con = mock(Connection.class); - DataSource ds = mock(DataSource.class); + Connection con = mock(); + DataSource ds = mock(); when(ds.getConnection()).thenReturn(con); // con1 con.close(); @@ -94,8 +94,8 @@ void testOperationWithDataSourceUtils() throws SQLException { @Test void testOperationWithDirectCloseCall() throws SQLException { - Connection con = mock(Connection.class); - DataSource ds = mock(DataSource.class); + Connection con = mock(); + DataSource ds = mock(); when(ds.getConnection()).thenReturn(con); // con1 con.close(); @@ -126,10 +126,10 @@ void testOperationWithDirectCloseCall() throws SQLException { @Test void testSuppressOfCloseWithJdbcTemplate() throws Exception { - Connection con = mock(Connection.class); - DataSource ds = mock(DataSource.class); - Statement stmt = mock(Statement.class); - ResultSet rs = mock(ResultSet.class); + Connection con = mock(); + DataSource ds = mock(); + Statement stmt = mock(); + ResultSet rs = mock(); // open and start suppressing close when(ds.getConnection()).thenReturn(con); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateCursorItemReaderStatefulIntegrationTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateCursorItemReaderStatefulIntegrationTests.java index 714295a12b..cc361b11f3 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateCursorItemReaderStatefulIntegrationTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateCursorItemReaderStatefulIntegrationTests.java @@ -44,9 +44,9 @@ protected boolean isUseStatelessSession() { @SuppressWarnings("unchecked") void testStatefulClose() { - SessionFactory sessionFactory = mock(SessionFactory.class); - Session session = mock(Session.class); - Query scrollableResults = mock(Query.class); + SessionFactory sessionFactory = mock(); + Session session = mock(); + Query scrollableResults = mock(); HibernateCursorItemReader itemReader = new HibernateCursorItemReader<>(); itemReader.setSessionFactory(sessionFactory); itemReader.setQueryString("testQuery"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemReaderHelperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemReaderHelperTests.java index 85ed47e53e..fd2d54f75e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemReaderHelperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemReaderHelperTests.java @@ -36,12 +36,12 @@ class HibernateItemReaderHelperTests { private final HibernateItemReaderHelper helper = new HibernateItemReaderHelper<>(); - private final SessionFactory sessionFactory = mock(SessionFactory.class); + private final SessionFactory sessionFactory = mock(); @Test void testOneSessionForAllPages() { - StatelessSession session = mock(StatelessSession.class); + StatelessSession session = mock(); when(sessionFactory.openStatelessSession()).thenReturn(session); helper.setSessionFactory(sessionFactory); @@ -55,7 +55,7 @@ void testOneSessionForAllPages() { @Test void testSessionReset() { - StatelessSession session = mock(StatelessSession.class); + StatelessSession session = mock(); when(sessionFactory.openStatelessSession()).thenReturn(session); helper.setSessionFactory(sessionFactory); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java index f95791a721..9d4272130f 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java @@ -46,8 +46,8 @@ class HibernateItemWriterTests { @BeforeEach void setUp() { writer = new HibernateItemWriter<>(); - factory = mock(SessionFactory.class); - currentSession = mock(Session.class); + factory = mock(); + currentSession = mock(); when(this.factory.getCurrentSession()).thenReturn(this.currentSession); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterClassicTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterClassicTests.java index a9b49f588a..bc5eb0cc7a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterClassicTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterClassicTests.java @@ -55,7 +55,7 @@ class JdbcBatchItemWriterClassicTests { @BeforeEach void setUp() { - ps = mock(PreparedStatement.class); + ps = mock(); jdbcTemplate = new JdbcTemplate() { @Override public T execute(String sql, PreparedStatementCallback action) throws DataAccessException { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterNamedParameterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterNamedParameterTests.java index 33e1ee9ae7..5cf270059c 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterNamedParameterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterNamedParameterTests.java @@ -85,7 +85,7 @@ public void setBar(String bar) { @BeforeEach void setUp() { - namedParameterJdbcOperations = mock(NamedParameterJdbcOperations.class); + namedParameterJdbcOperations = mock(); writer.setSql(sql); writer.setJdbcTemplate(namedParameterJdbcOperations); writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>()); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java index 978ff3534d..0a63671333 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java @@ -41,10 +41,10 @@ class JdbcCursorItemReaderConfigTests { */ @Test void testUsesCurrentTransaction() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); + DataSource ds = mock(); + Connection con = mock(); when(con.getAutoCommit()).thenReturn(false); - PreparedStatement ps = mock(PreparedStatement.class); + PreparedStatement ps = mock(); when(con.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT)) .thenReturn(ps); @@ -71,10 +71,10 @@ void testUsesCurrentTransaction() throws Exception { @Test void testUsesItsOwnTransaction() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); + DataSource ds = mock(); + Connection con = mock(); when(con.getAutoCommit()).thenReturn(false); - PreparedStatement ps = mock(PreparedStatement.class); + PreparedStatement ps = mock(); when(con.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) .thenReturn(ps); when(ds.getConnection()).thenReturn(con); @@ -98,10 +98,10 @@ void testOverrideConnectionAutoCommit() throws Exception { boolean initialAutoCommit = false; boolean neededAutoCommit = true; - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); + DataSource ds = mock(); + Connection con = mock(); when(con.getAutoCommit()).thenReturn(initialAutoCommit); - PreparedStatement ps = mock(PreparedStatement.class); + PreparedStatement ps = mock(); when(con.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) .thenReturn(ps); when(ds.getConnection()).thenReturn(con); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaItemWriterTests.java index cab71bf656..d5a8fdffad 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaItemWriterTests.java @@ -51,7 +51,7 @@ void setUp() { TransactionSynchronizationManager.clearSynchronization(); } writer = new JpaItemWriter<>(); - emf = mock(EntityManagerFactory.class, "emf"); + emf = mock(); writer.setEntityManagerFactory(emf); } @@ -65,7 +65,7 @@ void testAfterPropertiesSet() { @Test void testWriteAndFlushSunnyDay() { - EntityManager em = mock(EntityManager.class, "em"); + EntityManager em = mock(); em.contains("foo"); em.contains("bar"); em.merge("bar"); @@ -82,7 +82,7 @@ void testWriteAndFlushSunnyDay() { @Test void testPersist() { writer.setUsePersist(true); - EntityManager em = mock(EntityManager.class, "em"); + EntityManager em = mock(); TransactionSynchronizationManager.bindResource(emf, new EntityManagerHolder(em)); Chunk chunk = Chunk.of("persist1", "persist2"); writer.write(chunk); @@ -94,7 +94,7 @@ void testPersist() { @Test void testWriteAndFlushWithFailure() { final RuntimeException ex = new RuntimeException("ERROR"); - EntityManager em = mock(EntityManager.class, "em"); + EntityManager em = mock(); em.contains("foo"); em.contains("bar"); em.merge("bar"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/StoredprocedureItemReaderConfigTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/StoredprocedureItemReaderConfigTests.java index 50a02a9c04..c561addcfe 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/StoredprocedureItemReaderConfigTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/StoredprocedureItemReaderConfigTests.java @@ -41,14 +41,14 @@ class StoredprocedureItemReaderConfigTests { */ @Test void testUsesCurrentTransaction() throws Exception { - DataSource ds = mock(DataSource.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductName()).thenReturn("Oracle"); - Connection con = mock(Connection.class); + Connection con = mock(); when(con.getMetaData()).thenReturn(dmd); when(con.getMetaData()).thenReturn(dmd); when(con.getAutoCommit()).thenReturn(false); - CallableStatement cs = mock(CallableStatement.class); + CallableStatement cs = mock(); when(con.prepareCall("{call foo_bar()}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT)) .thenReturn(cs); @@ -75,14 +75,14 @@ void testUsesCurrentTransaction() throws Exception { @Test void testUsesItsOwnTransaction() throws Exception { - DataSource ds = mock(DataSource.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductName()).thenReturn("Oracle"); - Connection con = mock(Connection.class); + Connection con = mock(); when(con.getMetaData()).thenReturn(dmd); when(con.getMetaData()).thenReturn(dmd); when(con.getAutoCommit()).thenReturn(false); - CallableStatement cs = mock(CallableStatement.class); + CallableStatement cs = mock(); when(con.prepareCall("{call foo_bar()}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) .thenReturn(cs); when(ds.getConnection()).thenReturn(con); @@ -107,14 +107,14 @@ void testUsesItsOwnTransaction() throws Exception { @Test void testHandlesRefCursorPosition() throws Exception { - DataSource ds = mock(DataSource.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductName()).thenReturn("Oracle"); - Connection con = mock(Connection.class); + Connection con = mock(); when(con.getMetaData()).thenReturn(dmd); when(con.getMetaData()).thenReturn(dmd); when(con.getAutoCommit()).thenReturn(false); - CallableStatement cs = mock(CallableStatement.class); + CallableStatement cs = mock(); when(con.prepareCall("{call foo_bar(?, ?)}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) .thenReturn(cs); when(ds.getConnection()).thenReturn(con); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/StoredProcedureItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/StoredProcedureItemReaderBuilderTests.java index 57bf5d0322..b522f2b9be 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/StoredProcedureItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/StoredProcedureItemReaderBuilderTests.java @@ -38,7 +38,7 @@ */ class StoredProcedureItemReaderBuilderTests { - private final DataSource dataSource = Mockito.mock(DataSource.class); + private final DataSource dataSource = Mockito.mock(); @Test void testConfiguration() { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/orm/JpaNamedQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/orm/JpaNamedQueryProviderTests.java index 3e98b2e875..ac659c8f31 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/orm/JpaNamedQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/orm/JpaNamedQueryProviderTests.java @@ -69,8 +69,8 @@ void testJpaNamedQueryProviderEntityClassIsProvided() { void testNamedQueryCreation() throws Exception { // given String namedQuery = "allFoos"; - TypedQuery query = mock(TypedQuery.class); - EntityManager entityManager = Mockito.mock(EntityManager.class); + TypedQuery query = mock(); + EntityManager entityManager = Mockito.mock(); when(entityManager.createNamedQuery(namedQuery, Foo.class)).thenReturn(query); JpaNamedQueryProvider jpaNamedQueryProvider = new JpaNamedQueryProvider<>(); jpaNamedQueryProvider.setEntityManager(entityManager); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/ColumnMapExecutionContextRowMapperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/ColumnMapExecutionContextRowMapperTests.java index da677d07a7..8a05a6a09f 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/ColumnMapExecutionContextRowMapperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/ColumnMapExecutionContextRowMapperTests.java @@ -39,7 +39,7 @@ class ColumnMapExecutionContextRowMapperTests { @BeforeEach void setUp() { - ps = mock(PreparedStatement.class); + ps = mock(); mapper = new ColumnMapItemPreparedStatementSetter(); key = new LinkedHashMap<>(2); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java index 542714a12d..f819ff06d1 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java @@ -48,7 +48,7 @@ class DefaultDataFieldMaxValueIncrementerFactoryTests { @BeforeEach void setUp() { - DataSource dataSource = mock(DataSource.class); + DataSource dataSource = mock(); factory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java index f2be2f7437..5bd891ddfa 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java @@ -43,9 +43,9 @@ class DerbyPagingQueryProviderTests extends AbstractSqlPagingQueryProviderTests @Test void testInit() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + Connection con = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductVersion()).thenReturn("10.4.1.3"); when(con.getMetaData()).thenReturn(dmd); when(ds.getConnection()).thenReturn(con); @@ -54,9 +54,9 @@ void testInit() throws Exception { @Test void testInitWithRecentVersion() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + Connection con = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductVersion()).thenReturn("10.10.1.1"); when(con.getMetaData()).thenReturn(dmd); when(ds.getConnection()).thenReturn(con); @@ -65,9 +65,9 @@ void testInitWithRecentVersion() throws Exception { @Test void testInitWithUnsupportedVersion() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + Connection con = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductVersion()).thenReturn("10.2.9.9"); when(con.getMetaData()).thenReturn(dmd); when(ds.getConnection()).thenReturn(con); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HibernateNativeQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HibernateNativeQueryProviderTests.java index 22bf07b1ab..a03276fd0e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HibernateNativeQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HibernateNativeQueryProviderTests.java @@ -47,8 +47,8 @@ void testCreateQueryWithStatelessSession() { String sqlQuery = "select * from T_FOOS"; hibernateQueryProvider.setSqlQuery(sqlQuery); - StatelessSession session = mock(StatelessSession.class); - NativeQuery query = mock(NativeQuery.class); + StatelessSession session = mock(); + NativeQuery query = mock(); when(session.createNativeQuery(sqlQuery)).thenReturn(query); when(query.addEntity(Foo.class)).thenReturn(query); @@ -64,8 +64,8 @@ void shouldCreateQueryWithStatefulSession() { String sqlQuery = "select * from T_FOOS"; hibernateQueryProvider.setSqlQuery(sqlQuery); - Session session = mock(Session.class); - NativeQuery query = mock(NativeQuery.class); + Session session = mock(); + NativeQuery query = mock(); when(session.createNativeQuery(sqlQuery)).thenReturn(query); when(query.addEntity(Foo.class)).thenReturn(query); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/JpaNativeQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/JpaNativeQueryProviderTests.java index 0b48f7d65e..4c25edbf8a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/JpaNativeQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/JpaNativeQueryProviderTests.java @@ -49,8 +49,8 @@ void testCreateQuery() { String sqlQuery = "select * from T_FOOS where value >= :limit"; jpaQueryProvider.setSqlQuery(sqlQuery); - EntityManager entityManager = mock(EntityManager.class); - Query query = mock(Query.class); + EntityManager entityManager = mock(); + Query query = mock(); when(entityManager.createNativeQuery(sqlQuery, Foo.class)).thenReturn(query); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactoryTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactoryTests.java index 0a814af5aa..202fcc6476 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactoryTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ import java.io.BufferedReader; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.core.io.ByteArrayResource; /** @@ -75,16 +77,27 @@ void testCreateWithLineEndingAtEnd() throws Exception { assertNull(reader.readLine()); } - @Test - void testCreateWithFalseLineEnding() throws Exception { + @ParameterizedTest + @ValueSource(strings = { "||", "|||" }) + void testCreateWithFalseLineEnding(String lineEnding) throws Exception { SimpleBinaryBufferedReaderFactory factory = new SimpleBinaryBufferedReaderFactory(); - factory.setLineEnding("||"); + factory.setLineEnding(lineEnding); @SuppressWarnings("resource") - BufferedReader reader = factory.create(new ByteArrayResource("a|b||".getBytes()), "UTF-8"); + BufferedReader reader = factory.create(new ByteArrayResource(("a|b" + lineEnding).getBytes()), "UTF-8"); assertEquals("a|b", reader.readLine()); assertNull(reader.readLine()); } + @Test + void testCreateWithFalseMixedCharacterLineEnding() throws Exception { + SimpleBinaryBufferedReaderFactory factory = new SimpleBinaryBufferedReaderFactory(); + factory.setLineEnding("#@"); + @SuppressWarnings("resource") + BufferedReader reader = factory.create(new ByteArrayResource(("a##@").getBytes()), "UTF-8"); + assertEquals("a#", reader.readLine()); + assertNull(reader.readLine()); + } + @Test void testCreateWithIncompleteLineEnding() throws Exception { SimpleBinaryBufferedReaderFactory factory = new SimpleBinaryBufferedReaderFactory(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilderTests.java index 1f94531a7a..855876c322 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 the original author or authors. + * Copyright 2016-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import org.junit.jupiter.api.Test; @@ -266,7 +266,7 @@ void testFlags() throws Exception { WritableResource output = new FileSystemResource(File.createTempFile("foo", "txt")); - String encoding = Charset.defaultCharset().name(); + String encoding = StandardCharsets.UTF_8.name(); FlatFileItemWriter writer = new FlatFileItemWriterBuilder().name("foo") .resource(output) diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/mapping/DefaultLineMapperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/mapping/DefaultLineMapperTests.java index 47ee5aecc9..17d2aef012 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/mapping/DefaultLineMapperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/mapping/DefaultLineMapperTests.java @@ -50,11 +50,11 @@ void testMapping() throws Exception { final FieldSet fs = new DefaultFieldSet(new String[] { "token1", "token2" }); final String item = "ITEM"; - LineTokenizer tokenizer = mock(LineTokenizer.class); + LineTokenizer tokenizer = mock(); when(tokenizer.tokenize(line)).thenReturn(fs); @SuppressWarnings("unchecked") - FieldSetMapper fsMapper = mock(FieldSetMapper.class); + FieldSetMapper fsMapper = mock(); when(fsMapper.mapFieldSet(fs)).thenReturn(item); tested.setLineTokenizer(tokenizer); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java index 1613bd9c90..260a2c87f7 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java @@ -37,7 +37,7 @@ class JmsItemReaderTests { @Test void testNoItemTypeSunnyDay() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); when(jmsTemplate.receiveAndConvert()).thenReturn("foo"); itemReader.setJmsTemplate(jmsTemplate); @@ -46,7 +46,7 @@ void testNoItemTypeSunnyDay() { @Test void testSetItemTypeSunnyDay() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); when(jmsTemplate.receiveAndConvert()).thenReturn("foo"); itemReader.setJmsTemplate(jmsTemplate); @@ -56,7 +56,7 @@ void testSetItemTypeSunnyDay() { @Test void testSetItemSubclassTypeSunnyDay() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); Date date = new java.sql.Date(0L); when(jmsTemplate.receiveAndConvert()).thenReturn(date); @@ -70,7 +70,7 @@ void testSetItemSubclassTypeSunnyDay() { @Test void testSetItemTypeMismatch() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); when(jmsTemplate.receiveAndConvert()).thenReturn("foo"); JmsItemReader itemReader = new JmsItemReader<>(); @@ -82,8 +82,8 @@ void testSetItemTypeMismatch() { @Test void testNextMessageSunnyDay() { - JmsOperations jmsTemplate = mock(JmsOperations.class); - Message message = mock(Message.class); + JmsOperations jmsTemplate = mock(); + Message message = mock(); when(jmsTemplate.receive()).thenReturn(message); JmsItemReader itemReader = new JmsItemReader<>(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemWriterTests.java index cc5c2aa0fb..7a36cdb782 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemWriterTests.java @@ -31,7 +31,7 @@ class JmsItemWriterTests { @Test void testNoItemTypeSunnyDay() throws Exception { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); jmsTemplate.convertAndSend("foo"); jmsTemplate.convertAndSend("bar"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java index 7dc639a655..050f7d393b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java @@ -35,7 +35,7 @@ class JmsMethodArgumentsKeyGeneratorTests { @Test void testGetKeyFromMessage() throws Exception { - Message message = mock(Message.class); + Message message = mock(); when(message.getJMSMessageID()).thenReturn("foo"); JmsItemReader itemReader = new JmsItemReader<>(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java index 57aa7d5638..aaf41439ec 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java @@ -31,7 +31,7 @@ class JmsMethodInvocationRecovererTests { @Test void testRecoverWithNoDestination() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); jmsTemplate.convertAndSend("foo"); itemReader.setJmsTemplate(jmsTemplate); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java index 8851c92d5e..d3f7da272a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java @@ -35,7 +35,7 @@ class JmsNewMethodArgumentsIdentifierTests { @Test void testIsNewForMessage() throws Exception { - Message message = mock(Message.class); + Message message = mock(); when(message.getJMSRedelivered()).thenReturn(true); assertFalse(newMethodArgumentsIdentifier.isNew(new Object[] { message })); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemReaderBuilderTests.java index 45d9692ecc..fbb48ac41b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemReaderBuilderTests.java @@ -42,7 +42,7 @@ class JmsItemReaderBuilderTests { @BeforeEach void setupJmsTemplate() { - this.defaultJmsTemplate = mock(JmsOperations.class); + this.defaultJmsTemplate = mock(); when(this.defaultJmsTemplate.receiveAndConvert()).thenReturn("foo"); } @@ -55,7 +55,7 @@ void testBasicRead() { @Test void testSetItemSubclassType() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); Date date = new java.sql.Date(0L); when(jmsTemplate.receiveAndConvert()).thenReturn(date); @@ -77,8 +77,8 @@ void testSetItemTypeMismatch() { @Test void testMessageType() { - JmsOperations jmsTemplate = mock(JmsOperations.class); - Message message = mock(Message.class); + JmsOperations jmsTemplate = mock(); + Message message = mock(); when(jmsTemplate.receive()).thenReturn(message); JmsItemReader itemReader = new JmsItemReaderBuilder().jmsTemplate(jmsTemplate) diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemWriterBuilderTests.java index ad256ae325..6b88fea37d 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemWriterBuilderTests.java @@ -37,7 +37,7 @@ class JmsItemWriterBuilderTests { @Test void testNoItem() throws Exception { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); JmsItemWriter itemWriter = new JmsItemWriterBuilder().jmsTemplate(jmsTemplate).build(); ArgumentCaptor argCaptor = ArgumentCaptor.forClass(String.class); itemWriter.write(Chunk.of("foo", "bar")); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonFileItemWriterFunctionalTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonFileItemWriterFunctionalTests.java index 3612ba984d..a8d24a2534 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonFileItemWriterFunctionalTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonFileItemWriterFunctionalTests.java @@ -19,7 +19,6 @@ import java.io.File; import java.io.IOException; import java.math.BigDecimal; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -334,7 +333,7 @@ private void assertFileEquals(File expected, File actual) throws Exception { } private String getContent(File file) throws IOException { - return Files.readString(file.toPath(), Charset.defaultCharset()); + return Files.readString(file.toPath()); } } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java index 1fa37b7aa0..da3e032beb 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 the original author or authors. + * Copyright 2018-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package org.springframework.batch.item.json.builder; import java.io.File; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import org.junit.jupiter.api.BeforeEach; @@ -82,8 +82,8 @@ void testJsonFileItemWriterCreation() { boolean shouldDeleteIfExists = true; String encoding = "UTF-8"; String lineSeparator = "#"; - FlatFileHeaderCallback headerCallback = Mockito.mock(FlatFileHeaderCallback.class); - FlatFileFooterCallback footerCallback = Mockito.mock(FlatFileFooterCallback.class); + FlatFileHeaderCallback headerCallback = Mockito.mock(); + FlatFileFooterCallback footerCallback = Mockito.mock(); // when JsonFileItemWriter writer = new JsonFileItemWriterBuilder().name("jsonFileItemWriter") @@ -112,10 +112,10 @@ void testJsonFileItemWriterCreationDefaultEncoding() { boolean transactional = true; boolean shouldDeleteIfEmpty = true; boolean shouldDeleteIfExists = true; - String encoding = Charset.defaultCharset().name(); + String encoding = StandardCharsets.UTF_8.name(); String lineSeparator = "#"; - FlatFileHeaderCallback headerCallback = Mockito.mock(FlatFileHeaderCallback.class); - FlatFileFooterCallback footerCallback = Mockito.mock(FlatFileFooterCallback.class); + FlatFileHeaderCallback headerCallback = Mockito.mock(); + FlatFileFooterCallback footerCallback = Mockito.mock(); // when JsonFileItemWriter writer = new JsonFileItemWriterBuilder().name("jsonFileItemWriter") diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriterTests.java index 7d69fc64ce..43cbc5c59a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriterTests.java @@ -47,7 +47,7 @@ class SimpleMailMessageItemWriterTests { private final SimpleMailMessageItemWriter writer = new SimpleMailMessageItemWriter(); - private final MailSender mailSender = mock(MailSender.class); + private final MailSender mailSender = mock(); @BeforeEach void setUp() { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/builder/SimpleMailMessageItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/builder/SimpleMailMessageItemWriterBuilderTests.java index cc30179ab0..60bc88647c 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/builder/SimpleMailMessageItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/builder/SimpleMailMessageItemWriterBuilderTests.java @@ -52,7 +52,7 @@ class SimpleMailMessageItemWriterBuilderTests { @BeforeEach void setup() { - mailSender = mock(MailSender.class); + mailSender = mock(); this.foo = new SimpleMailMessage(); this.bar = new SimpleMailMessage(); this.items = new SimpleMailMessage[] { this.foo, this.bar }; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/javamail/MimeMessageItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/javamail/MimeMessageItemWriterTests.java index 573c531776..658fb71d0b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/javamail/MimeMessageItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/javamail/MimeMessageItemWriterTests.java @@ -49,7 +49,7 @@ class MimeMessageItemWriterTests { private final MimeMessageItemWriter writer = new MimeMessageItemWriter(); - private final JavaMailSender mailSender = mock(JavaMailSender.class); + private final JavaMailSender mailSender = mock(); private final Session session = Session.getDefaultInstance(new Properties()); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java index f8d15de35b..b4e7e84875 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java @@ -46,8 +46,8 @@ class CompositeItemProcessorTests { @SuppressWarnings("unchecked") @BeforeEach void setUp() throws Exception { - processor1 = mock(ItemProcessor.class); - processor2 = mock(ItemProcessor.class); + processor1 = mock(); + processor2 = mock(); composite.setDelegates(Arrays.asList(processor1, processor2)); @@ -80,8 +80,8 @@ void testTransform() throws Exception { @SuppressWarnings("unchecked") void testItemProcessorGenerics() throws Exception { CompositeItemProcessor composite = new CompositeItemProcessor<>(); - final ItemProcessor processor1 = mock(ItemProcessor.class); - final ItemProcessor processor2 = mock(ItemProcessor.class); + final ItemProcessor processor1 = mock(); + final ItemProcessor processor2 = mock(); composite.setDelegates(Arrays.asList(processor1, processor2)); composite.afterPropertiesSet(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java index 43ba76c879..8d5d3f7b62 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java @@ -52,7 +52,7 @@ void testProcess() throws Exception { for (int i = 0; i < NUMBER_OF_WRITERS; i++) { @SuppressWarnings("unchecked") - ItemWriter writer = mock(ItemWriter.class); + ItemWriter writer = mock(); writer.write(data); @@ -76,7 +76,7 @@ void testItemStreamNotCalled() throws Exception { private void doTestItemStream(boolean expectOpen) throws Exception { @SuppressWarnings("unchecked") - ItemStreamWriter writer = mock(ItemStreamWriter.class); + ItemStreamWriter writer = mock(); Chunk data = Chunk.of(new Object()); ExecutionContext executionContext = new ExecutionContext(); if (expectOpen) { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemWriterBuilderTests.java index 6ecc25f3ef..a5025db078 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemWriterBuilderTests.java @@ -48,7 +48,7 @@ void testProcess() throws Exception { List> writers = new ArrayList<>(); for (int i = 0; i < NUMBER_OF_WRITERS; i++) { - ItemWriter writer = mock(ItemWriter.class); + ItemWriter writer = mock(); writers.add(writer); } CompositeItemWriter itemWriter = new CompositeItemWriterBuilder<>().delegates(writers).build(); @@ -68,9 +68,9 @@ void testProcessVarargs() throws Exception { List> writers = new ArrayList<>(); - ItemWriter writer1 = mock(ItemWriter.class); + ItemWriter writer1 = mock(); writers.add(writer1); - ItemWriter writer2 = mock(ItemWriter.class); + ItemWriter writer2 = mock(); writers.add(writer2); CompositeItemWriter itemWriter = new CompositeItemWriterBuilder<>().delegates(writer1, writer2).build(); @@ -90,7 +90,7 @@ void isStreamOpen() throws Exception { @SuppressWarnings("unchecked") private void ignoreItemStream(boolean ignoreItemStream) throws Exception { - ItemStreamWriter writer = mock(ItemStreamWriter.class); + ItemStreamWriter writer = mock(); Chunk data = Chunk.of(new Object()); ExecutionContext executionContext = new ExecutionContext(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java index 5d6ea420ef..a080e16c8e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java @@ -29,7 +29,7 @@ class ValidatingItemProcessorTests { @SuppressWarnings("unchecked") - private final Validator validator = mock(Validator.class); + private final Validator validator = mock(); private static final String ITEM = "item"; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java index 7b08eb6b02..2afc86738b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java @@ -168,15 +168,15 @@ void testCustomEncoding() throws Exception { @Test void testNullEncoding() throws Exception { // given - XMLEventReader eventReader = mock(XMLEventReader.class); + XMLEventReader eventReader = mock(); when(eventReader.peek()).thenReturn(mock(StartDocument.class)); - Resource resource = mock(Resource.class); - InputStream inputStream = mock(InputStream.class); + Resource resource = mock(); + InputStream inputStream = mock(); when(resource.getInputStream()).thenReturn(inputStream); when(resource.isReadable()).thenReturn(true); when(resource.exists()).thenReturn(true); - XMLInputFactory xmlInputFactory = mock(XMLInputFactory.class); + XMLInputFactory xmlInputFactory = mock(); when(xmlInputFactory.createXMLEventReader(inputStream)).thenReturn(eventReader); StaxEventItemReader reader = new StaxEventItemReader<>(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java index caeb995fa7..f904c59441 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java @@ -446,7 +446,7 @@ void testOpenAndClose() throws Exception { @Test void testNonExistantResource() throws Exception { - WritableResource doesntExist = mock(WritableResource.class); + WritableResource doesntExist = mock(); when(doesntExist.getFile()).thenReturn(File.createTempFile("arbitrary", null)); when(doesntExist.exists()).thenReturn(false); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventReaderWrapperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventReaderWrapperTests.java index 500f32c1fb..b7cbd3e773 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventReaderWrapperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventReaderWrapperTests.java @@ -32,7 +32,7 @@ */ class AbstractEventReaderWrapperTests { - private final XMLEventReader xmlEventReader = mock(XMLEventReader.class); + private final XMLEventReader xmlEventReader = mock(); private final AbstractEventReaderWrapper eventReaderWrapper = new StubEventReader(xmlEventReader); @@ -76,7 +76,7 @@ void testNext() { @Test void testNextEvent() throws XMLStreamException { - XMLEvent event = mock(XMLEvent.class); + XMLEvent event = mock(); when(xmlEventReader.nextEvent()).thenReturn(event); assertEquals(eventReaderWrapper.nextEvent(), event); } @@ -84,7 +84,7 @@ void testNextEvent() throws XMLStreamException { @Test void testNextTag() throws XMLStreamException { - XMLEvent event = mock(XMLEvent.class); + XMLEvent event = mock(); when(xmlEventReader.nextTag()).thenReturn(event); assertEquals(eventReaderWrapper.nextTag(), event); } @@ -92,7 +92,7 @@ void testNextTag() throws XMLStreamException { @Test void testPeek() throws XMLStreamException { - XMLEvent event = mock(XMLEvent.class); + XMLEvent event = mock(); when(xmlEventReader.peek()).thenReturn(event); assertEquals(eventReaderWrapper.peek(), event); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventWriterWrapperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventWriterWrapperTests.java index c2d279c1e3..2e15b2ee73 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventWriterWrapperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventWriterWrapperTests.java @@ -35,14 +35,14 @@ */ class AbstractEventWriterWrapperTests { - private final XMLEventWriter xmlEventWriter = mock(XMLEventWriter.class); + private final XMLEventWriter xmlEventWriter = mock(); private final AbstractEventWriterWrapper eventWriterWrapper = new StubEventWriter(xmlEventWriter); @Test void testAdd() throws XMLStreamException { - XMLEvent event = mock(XMLEvent.class); + XMLEvent event = mock(); xmlEventWriter.add(event); eventWriterWrapper.add(event); @@ -51,7 +51,7 @@ void testAdd() throws XMLStreamException { @Test void testAddReader() throws XMLStreamException { - XMLEventReader reader = mock(XMLEventReader.class); + XMLEventReader reader = mock(); xmlEventWriter.add(reader); eventWriterWrapper.add(reader); } @@ -70,7 +70,7 @@ void testFlush() throws XMLStreamException { @Test void testGetNamespaceContext() { - NamespaceContext context = mock(NamespaceContext.class); + NamespaceContext context = mock(); when(xmlEventWriter.getNamespaceContext()).thenReturn(context); assertEquals(eventWriterWrapper.getNamespaceContext(), context); } @@ -92,7 +92,7 @@ void testSetDefaultNamespace() throws XMLStreamException { @Test void testSetNamespaceContext() throws XMLStreamException { - NamespaceContext context = mock(NamespaceContext.class); + NamespaceContext context = mock(); xmlEventWriter.setNamespaceContext(context); eventWriterWrapper.setNamespaceContext(context); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/NoStartEndDocumentWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/NoStartEndDocumentWriterTests.java index 068cce26a1..1af18717f0 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/NoStartEndDocumentWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/NoStartEndDocumentWriterTests.java @@ -34,7 +34,7 @@ */ class NoStartEndDocumentWriterTests { - private final XMLEventWriter wrappedWriter = mock(XMLEventWriter.class); + private final XMLEventWriter wrappedWriter = mock(); private final NoStartEndDocumentStreamWriter writer = new NoStartEndDocumentStreamWriter(wrappedWriter); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnclosedElementCollectingEventWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnclosedElementCollectingEventWriterTests.java index af18881900..de1abda1e5 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnclosedElementCollectingEventWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnclosedElementCollectingEventWriterTests.java @@ -34,7 +34,7 @@ */ class UnclosedElementCollectingEventWriterTests { - private final XMLEventWriter wrappedWriter = mock(XMLEventWriter.class); + private final XMLEventWriter wrappedWriter = mock(); private final UnclosedElementCollectingEventWriter writer = new UnclosedElementCollectingEventWriter(wrappedWriter); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnopenedElementClosingEventWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnopenedElementClosingEventWriterTests.java index 1849ca3fdd..7287eb0fef 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnopenedElementClosingEventWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnopenedElementClosingEventWriterTests.java @@ -62,8 +62,8 @@ class UnopenedElementClosingEventWriterTests { @BeforeEach void setUp() { - wrappedWriter = mock(XMLEventWriter.class); - ioWriter = mock(Writer.class); + wrappedWriter = mock(); + ioWriter = mock(); unopenedElements.add(unopenedA); unopenedElements.add(unopenedB); writer = new UnopenedElementClosingEventWriter(wrappedWriter, ioWriter, unopenedElements); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTestUtils.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTestUtils.java index f58592b410..69947429c4 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTestUtils.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTestUtils.java @@ -54,9 +54,9 @@ public static DataSource getMockDataSource(String databaseProductName) throws Ex } public static DataSource getMockDataSource(String databaseProductName, String databaseVersion) throws Exception { - DatabaseMetaData dmd = mock(DatabaseMetaData.class); - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); + DatabaseMetaData dmd = mock(); + DataSource ds = mock(); + Connection con = mock(); when(ds.getConnection()).thenReturn(con); when(con.getMetaData()).thenReturn(dmd); when(dmd.getDatabaseProductName()).thenReturn(databaseProductName); @@ -67,7 +67,7 @@ public static DataSource getMockDataSource(String databaseProductName, String da } public static DataSource getMockDataSource(Exception e) throws Exception { - DataSource ds = mock(DataSource.class); + DataSource ds = mock(); when(ds.getConnection()).thenReturn(null); return ds; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java index 1c236239df..6ef4df7735 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java @@ -53,7 +53,7 @@ class TransactionAwareBufferedWriterTests { @BeforeEach void init() { - fileChannel = mock(FileChannel.class); + fileChannel = mock(); writer = new TransactionAwareBufferedWriter(fileChannel, () -> { try { @@ -300,7 +300,7 @@ void testResourceKeyCollision() throws Exception { final String[] results = new String[limit]; for (int i = 0; i < limit; i++) { final int index = i; - FileChannel fileChannel = mock(FileChannel.class); + FileChannel fileChannel = mock(); when(fileChannel.write(any(ByteBuffer.class))).thenAnswer(invocation -> { ByteBuffer buffer = (ByteBuffer) invocation.getArguments()[0]; String val = new String(buffer.array(), StandardCharsets.UTF_8); diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index bd69db83b1..370bd162b2 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.7-SNAPSHOT spring-batch-integration Spring Batch Integration diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/aot/IntegrationRuntimeHints.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/aot/IntegrationRuntimeHints.java index 72674495fb..5f42caf800 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/aot/IntegrationRuntimeHints.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/aot/IntegrationRuntimeHints.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 the original author or authors. + * Copyright 2023-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,9 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.batch.integration.chunk.ChunkRequest; import org.springframework.batch.integration.chunk.ChunkResponse; +import org.springframework.batch.integration.partition.MessageChannelPartitionHandler; +import org.springframework.batch.integration.partition.StepExecutionRequest; +import org.springframework.batch.integration.partition.StepExecutionRequestHandler; /** * AOT hints for Spring Batch integration module. @@ -32,12 +35,16 @@ public class IntegrationRuntimeHints implements RuntimeHintsRegistrar { @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { // reflection hints - hints.reflection().registerType(ChunkRequest.class, MemberCategory.values()); - hints.reflection().registerType(ChunkResponse.class, MemberCategory.values()); + MemberCategory[] memberCategories = MemberCategory.values(); + hints.reflection().registerType(ChunkRequest.class, memberCategories); + hints.reflection().registerType(ChunkResponse.class, memberCategories); + hints.reflection().registerType(StepExecutionRequestHandler.class, memberCategories); + hints.reflection().registerType(MessageChannelPartitionHandler.class, memberCategories); // serialization hints hints.serialization().registerType(ChunkRequest.class); hints.serialization().registerType(ChunkResponse.class); + hints.serialization().registerType(StepExecutionRequest.class); } } diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemWriter.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemWriter.java index 4b3336afc6..1d69d4d18a 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemWriter.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,13 +67,13 @@ public void write(Chunk> items) throws Exception { T item = future.get(); if (item != null) { - list.add(future.get()); + list.add(item); } } catch (ExecutionException e) { Throwable cause = e.getCause(); - if (cause != null && cause instanceof Exception) { + if (cause instanceof Exception) { logger.debug("An exception was thrown while processing an item", e); throw (Exception) cause; diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandler.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandler.java index 9b16964100..be541b880f 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandler.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2023 the original author or authors. + * Copyright 2009-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -251,24 +251,22 @@ protected Set doHandle(StepExecution managerStepExecution, private Set pollReplies(final StepExecution managerStepExecution, final Set split) throws Exception { - final Set result = new HashSet<>(split.size()); + Set partitionStepExecutionIds = split.stream().map(StepExecution::getId).collect(Collectors.toSet()); Callable> callback = () -> { - Set currentStepExecutionIds = split.stream().map(StepExecution::getId).collect(Collectors.toSet()); JobExecution jobExecution = jobExplorer.getJobExecution(managerStepExecution.getJobExecutionId()); - jobExecution.getStepExecutions() + Set finishedStepExecutions = jobExecution.getStepExecutions() .stream() - .filter(stepExecution -> currentStepExecutionIds.contains(stepExecution.getId())) - .filter(stepExecution -> !result.contains(stepExecution)) + .filter(stepExecution -> partitionStepExecutionIds.contains(stepExecution.getId())) .filter(stepExecution -> !stepExecution.getStatus().isRunning()) - .forEach(result::add); + .collect(Collectors.toSet()); if (logger.isDebugEnabled()) { logger.debug(String.format("Currently waiting on %s partitions to finish", split.size())); } - if (result.size() == split.size()) { - return result; + if (finishedStepExecutions.size() == split.size()) { + return finishedStepExecutions; } else { return null; diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilderTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilderTests.java index ffa1177996..097083fa8b 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilderTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilderTests.java @@ -232,12 +232,12 @@ void testSetters() throws Exception { NoBackOffPolicy backOffPolicy = new NoBackOffPolicy(); ItemStreamSupport stream = new ItemStreamSupport() { }; - StepExecutionListener stepExecutionListener = mock(StepExecutionListener.class); - ItemReadListener itemReadListener = mock(ItemReadListener.class); - ItemWriteListener itemWriteListener = mock(ItemWriteListener.class); - ChunkListener chunkListener = mock(ChunkListener.class); - SkipListener skipListener = mock(SkipListener.class); - RetryListener retryListener = mock(RetryListener.class); + StepExecutionListener stepExecutionListener = mock(); + ItemReadListener itemReadListener = mock(); + ItemWriteListener itemWriteListener = mock(); + ChunkListener chunkListener = mock(); + SkipListener skipListener = mock(); + RetryListener retryListener = mock(); when(retryListener.open(any(), any())).thenReturn(true); diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java index 9bb3314298..e9419e44c7 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java @@ -45,7 +45,7 @@ void testExceptionRaised() throws Exception { .withPayload(new JobLaunchRequest(new JobSupport("testJob"), new JobParameters())) .build(); - final JobLauncher jobLauncher = mock(JobLauncher.class); + final JobLauncher jobLauncher = mock(); when(jobLauncher.run(any(Job.class), any(JobParameters.class))) .thenThrow(new JobParametersInvalidException("This is a JobExecutionException.")); diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandlerTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandlerTests.java index 97200b2d7a..4f7b677649 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandlerTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandlerTests.java @@ -61,8 +61,8 @@ void testNoPartitions() throws Exception { // execute with no default set messageChannelPartitionHandler = new MessageChannelPartitionHandler(); // mock - StepExecution managerStepExecution = mock(StepExecution.class); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); + StepExecution managerStepExecution = mock(); + StepExecutionSplitter stepExecutionSplitter = mock(); // execute Collection executions = messageChannelPartitionHandler.handle(stepExecutionSplitter, @@ -77,10 +77,10 @@ void testHandleNoReply() throws Exception { // execute with no default set messageChannelPartitionHandler = new MessageChannelPartitionHandler(); // mock - StepExecution managerStepExecution = mock(StepExecution.class); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - Message message = mock(Message.class); + StepExecution managerStepExecution = mock(); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + Message message = mock(); // when HashSet stepExecutions = new HashSet<>(); stepExecutions.add(new StepExecution("step1", new JobExecution(5L))); @@ -104,11 +104,11 @@ void testHandleWithReplyChannel() throws Exception { // execute with no default set messageChannelPartitionHandler = new MessageChannelPartitionHandler(); // mock - StepExecution managerStepExecution = mock(StepExecution.class); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - Message message = mock(Message.class); - PollableChannel replyChannel = mock(PollableChannel.class); + StepExecution managerStepExecution = mock(); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + Message message = mock(); + PollableChannel replyChannel = mock(); // when HashSet stepExecutions = new HashSet<>(); stepExecutions.add(new StepExecution("step1", new JobExecution(5L))); @@ -134,10 +134,10 @@ void messageReceiveTimeout() throws Exception { // execute with no default set messageChannelPartitionHandler = new MessageChannelPartitionHandler(); // mock - StepExecution managerStepExecution = mock(StepExecution.class); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - Message message = mock(Message.class); + StepExecution managerStepExecution = mock(); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + Message message = mock(); // when HashSet stepExecutions = new HashSet<>(); stepExecutions.add(new StepExecution("step1", new JobExecution(5L))); @@ -158,9 +158,9 @@ void testHandleWithJobRepositoryPolling() throws Exception { // mock JobExecution jobExecution = new JobExecution(5L, new JobParameters()); StepExecution managerStepExecution = new StepExecution("step1", jobExecution, 1L); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - JobExplorer jobExplorer = mock(JobExplorer.class); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + JobExplorer jobExplorer = mock(); // when HashSet stepExecutions = new HashSet<>(); StepExecution partition1 = new StepExecution("step1:partition1", jobExecution, 2L); @@ -210,9 +210,9 @@ void testHandleWithJobRepositoryPollingTimeout() throws Exception { // mock JobExecution jobExecution = new JobExecution(5L, new JobParameters()); StepExecution managerStepExecution = new StepExecution("step1", jobExecution, 1L); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - JobExplorer jobExplorer = mock(JobExplorer.class); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + JobExplorer jobExplorer = mock(); // when HashSet stepExecutions = new HashSet<>(); StepExecution partition1 = new StepExecution("step1:partition1", jobExecution, 2L); diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderTests.java index fc9ca6d282..035bfedaad 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderTests.java @@ -142,7 +142,7 @@ void eitherOutputChannelOrMessagingTemplateMustBeProvided() { @Test void testUnsupportedOperationExceptionWhenSpecifyingPartitionHandler() { // given - PartitionHandler partitionHandler = Mockito.mock(PartitionHandler.class); + PartitionHandler partitionHandler = Mockito.mock(); final RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step", this.jobRepository); @@ -165,7 +165,7 @@ void testManagerStepCreationWhenPollingRepository() { long timeout = 1000L; long pollInterval = 5000L; DirectChannel outputChannel = new DirectChannel(); - Partitioner partitioner = Mockito.mock(Partitioner.class); + Partitioner partitioner = Mockito.mock(); StepExecutionAggregator stepExecutionAggregator = (result, executions) -> { }; @@ -208,7 +208,7 @@ void testManagerStepCreationWhenAggregatingReplies() { int gridSize = 5; int startLimit = 3; DirectChannel outputChannel = new DirectChannel(); - Partitioner partitioner = Mockito.mock(Partitioner.class); + Partitioner partitioner = Mockito.mock(); StepExecutionAggregator stepExecutionAggregator = (result, executions) -> { }; diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index 5f340c5c8e..05f2686e86 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.7-SNAPSHOT spring-batch-samples jar diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/OrderItemReaderTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/OrderItemReaderTests.java index 01a6e16b30..97ecc7dbfd 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/OrderItemReaderTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/OrderItemReaderTests.java @@ -36,7 +36,7 @@ class OrderItemReaderTests { @BeforeEach @SuppressWarnings("unchecked") void setUp() { - input = mock(ItemReader.class); + input = mock(); provider = new OrderItemReader(); provider.setFieldSetReader(input); @@ -76,7 +76,7 @@ void testNext() throws Exception { LineItem item = new LineItem(); @SuppressWarnings("rawtypes") - FieldSetMapper mapper = mock(FieldSetMapper.class); + FieldSetMapper mapper = mock(); when(mapper.mapFieldSet(headerFS)).thenReturn(order); when(mapper.mapFieldSet(customerFS)).thenReturn(customer); when(mapper.mapFieldSet(billingFS)).thenReturn(billing); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/CustomerUpdateProcessorTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/CustomerUpdateProcessorTests.java index 727fe9acbd..39435aa2fe 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/CustomerUpdateProcessorTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/CustomerUpdateProcessorTests.java @@ -41,8 +41,8 @@ class CustomerUpdateProcessorTests { @BeforeEach void init() { - customerDao = mock(CustomerDao.class); - logger = mock(InvalidCustomerLogger.class); + customerDao = mock(); + logger = mock(); processor = new CustomerUpdateProcessor(); processor.setCustomerDao(customerDao); processor.setInvalidCustomerLogger(logger); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdatePreparedStatementSetterTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdatePreparedStatementSetterTests.java index 07b9db5f94..3c8123edfa 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdatePreparedStatementSetterTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdatePreparedStatementSetterTests.java @@ -40,7 +40,7 @@ class CustomerCreditUpdatePreparedStatementSetterTests { @BeforeEach void setUp() { - ps = mock(PreparedStatement.class); + ps = mock(); credit = new CustomerCredit(); credit.setId(13); credit.setCredit(new BigDecimal(12000)); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdateProcessorTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdateProcessorTests.java index fab13fba93..9a61d998ec 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdateProcessorTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdateProcessorTests.java @@ -35,7 +35,7 @@ class CustomerCreditUpdateProcessorTests { @BeforeEach void setUp() { - dao = mock(CustomerCreditDao.class); + dao = mock(); writer = new CustomerCreditUpdateWriter(); writer.setDao(dao); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/FlatFileCustomerCreditDaoTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/FlatFileCustomerCreditDaoTests.java index e442ea4142..9a6e41d9a1 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/FlatFileCustomerCreditDaoTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/FlatFileCustomerCreditDaoTests.java @@ -35,7 +35,7 @@ class FlatFileCustomerCreditDaoTests { @BeforeEach void setUp() { - output = mock(ResourceLifecycleItemWriter.class); + output = mock(); writer = new FlatFileCustomerCreditDao(); writer.setItemWriter(output); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessorTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessorTests.java index 4a130314dd..38452d3138 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessorTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessorTests.java @@ -31,7 +31,7 @@ class TradeProcessorTests { @BeforeEach void setUp() { - writer = mock(TradeDao.class); + writer = mock(); processor = new TradeWriter(); processor.setDao(writer); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/quartz/JobLauncherDetailsTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/quartz/JobLauncherDetailsTests.java index ec270ebba2..0e6bd32b8d 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/quartz/JobLauncherDetailsTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/quartz/JobLauncherDetailsTests.java @@ -133,7 +133,7 @@ void testExecuteWithJobNameAndComplexParameters() { private final class StubJobExecutionContext extends JobExecutionContextImpl { private StubJobExecutionContext() { - super(mock(Scheduler.class), firedBundle, mock(Job.class)); + super(mock(), firedBundle, mock()); } } diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/AbstractRowMapperTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/AbstractRowMapperTests.java index 934c2975ee..10e73b0826 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/AbstractRowMapperTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/AbstractRowMapperTests.java @@ -38,7 +38,7 @@ public abstract class AbstractRowMapperTests { private static final int IGNORED_ROW_NUMBER = 0; // mock result set - private final ResultSet rs = mock(ResultSet.class); + private final ResultSet rs = mock(); /** * @return Expected result of mapping the mock ResultSet by the mapper diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index 31df071856..da125fcf43 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.7-SNAPSHOT spring-batch-test Spring Batch Test diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java index dbeb4dab21..b1a4da0f27 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java @@ -177,9 +177,10 @@ protected StepRunner getStepRunner() { } /** - * Launch just the specified step in the job. A unique set of JobParameters will - * automatically be generated. An IllegalStateException is thrown if there is no Step - * with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. A unique set of JobParameters + * will automatically be generated. An IllegalStateException is thrown if there is no + * Step with the given name. * @param stepName The name of the step to launch * @return JobExecution */ @@ -188,9 +189,10 @@ public JobExecution launchStep(String stepName) { } /** - * Launch just the specified step in the job. A unique set of JobParameters will - * automatically be generated. An IllegalStateException is thrown if there is no Step - * with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. A unique set of JobParameters + * will automatically be generated. An IllegalStateException is thrown if there is no + * Step with the given name. * @param stepName The name of the step to launch * @param jobExecutionContext An ExecutionContext whose values will be loaded into the * Job ExecutionContext prior to launching the step. @@ -201,8 +203,9 @@ public JobExecution launchStep(String stepName, ExecutionContext jobExecutionCon } /** - * Launch just the specified step in the job. An IllegalStateException is thrown if - * there is no Step with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. An IllegalStateException is + * thrown if there is no Step with the given name. * @param stepName The name of the step to launch * @param jobParameters The JobParameters to use during the launch * @return JobExecution @@ -212,8 +215,9 @@ public JobExecution launchStep(String stepName, JobParameters jobParameters) { } /** - * Launch just the specified step in the job. An IllegalStateException is thrown if - * there is no Step with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. An IllegalStateException is + * thrown if there is no Step with the given name. * @param stepName The name of the step to launch * @param jobParameters The JobParameters to use during the launch * @param jobExecutionContext An ExecutionContext whose values will be loaded into the diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestExecutionListener.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestExecutionListener.java index 6fca833885..89bf1730f9 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestExecutionListener.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestExecutionListener.java @@ -103,7 +103,7 @@ public void beforeTestMethod(org.springframework.test.context.TestContext testCo @Override public void afterTestMethod(TestContext testContext) throws Exception { if (testContext.hasAttribute(JOB_EXECUTION)) { - JobSynchronizationManager.close(); + JobSynchronizationManager.release(); } } diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestUtils.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestUtils.java index 00e9871fe5..989512bb46 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestUtils.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ * * @author Dave Syer * @author Jimmy Praet + * @author Mahmoud Ben Hassine */ public class JobScopeTestUtils { @@ -37,7 +38,7 @@ public static T doInJobScope(JobExecution jobExecution, Callable callable return callable.call(); } finally { - JobSynchronizationManager.close(); + JobSynchronizationManager.release(); } } diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java b/spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java index d60a129f38..2f1bc86801 100755 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java @@ -42,9 +42,8 @@ import org.springframework.lang.Nullable; /** - * Utility class for executing steps outside of a {@link Job}. This is useful in end to - * end testing in order to allow for the testing of a step individually without running - * every Step in a job. + * Utility class for executing steps. This is useful in end to end testing in order to + * allow for the testing of a step individually without running every Step in a job. * *
    *
  • launchStep(Step step): Launch the step with new parameters each time. (The @@ -67,6 +66,11 @@ */ public class StepRunner { + /** + * Name of the single-step job surrounding steps when tested individually + */ + public static final String JOB_NAME = "TestJob"; + /** Logger */ protected final Log logger = LogFactory.getLog(getClass()); @@ -80,9 +84,10 @@ public StepRunner(JobLauncher launcher, JobRepository jobRepository) { } /** - * Launch just the specified step as its own job. A unique set of JobParameters will - * automatically be generated. An IllegalStateException is thrown if there is no Step - * with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. A unique set of JobParameters + * will automatically be generated. An IllegalStateException is thrown if there is no + * Step with the given name. * @param step The step to launch * @return JobExecution */ @@ -91,9 +96,10 @@ public JobExecution launchStep(Step step) { } /** - * Launch just the specified step as its own job. A unique set of JobParameters will - * automatically be generated. An IllegalStateException is thrown if there is no Step - * with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. A unique set of JobParameters + * will automatically be generated. An IllegalStateException is thrown if there is no + * Step with the given name. * @param step The step to launch * @param jobExecutionContext An ExecutionContext whose values will be loaded into the * Job ExecutionContext prior to launching the step. @@ -104,8 +110,9 @@ public JobExecution launchStep(Step step, @Nullable ExecutionContext jobExecutio } /** - * Launch just the specified step as its own job. An IllegalStateException is thrown - * if there is no Step with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. An IllegalStateException is + * thrown if there is no Step with the given name. * @param step The step to launch * @param jobParameters The JobParameters to use during the launch * @return JobExecution @@ -115,8 +122,9 @@ public JobExecution launchStep(Step step, JobParameters jobParameters) { } /** - * Launch just the specified step as its own job. An IllegalStateException is thrown - * if there is no Step with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. An IllegalStateException is + * thrown if there is no Step with the given name. * @param step The step to launch * @param jobParameters The JobParameters to use during the launch * @param jobExecutionContext An ExecutionContext whose values will be loaded into the @@ -129,7 +137,7 @@ public JobExecution launchStep(Step step, JobParameters jobParameters, // Create a fake job // SimpleJob job = new SimpleJob(); - job.setName("TestJob"); + job.setName(JOB_NAME); job.setJobRepository(this.jobRepository); List stepsToExecute = new ArrayList<>(); diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/JobScopeTestExecutionListenerIntegrationTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/JobScopeTestExecutionListenerIntegrationTests.java index 707732bba7..d295007f00 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/JobScopeTestExecutionListenerIntegrationTests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/JobScopeTestExecutionListenerIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2022 the original author or authors. + * Copyright 2013-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; import org.springframework.batch.core.JobExecution; @@ -56,6 +57,8 @@ JobExecution getJobExecution() { void testJob() throws Exception { stream.open(new ExecutionContext()); assertEquals("foo", reader.read()); + assertEquals("bar", reader.read()); + assertNull(reader.read()); } } diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/context/BatchTestContextCustomizerTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/context/BatchTestContextCustomizerTests.java index aad114c2bb..efb96008f6 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/context/BatchTestContextCustomizerTests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/context/BatchTestContextCustomizerTests.java @@ -46,7 +46,7 @@ void removeSystemProperty() { void testCustomizeContext() { // given ConfigurableApplicationContext context = new GenericApplicationContext(); - MergedContextConfiguration mergedConfig = Mockito.mock(MergedContextConfiguration.class); + MergedContextConfiguration mergedConfig = Mockito.mock(); // when this.contextCustomizer.customizeContext(context, mergedConfig); @@ -60,8 +60,8 @@ void testCustomizeContext() { @Test void testCustomizeContext_whenBeanFactoryIsNotAnInstanceOfBeanDefinitionRegistry() { // given - ConfigurableApplicationContext context = Mockito.mock(ConfigurableApplicationContext.class); - MergedContextConfiguration mergedConfig = Mockito.mock(MergedContextConfiguration.class); + ConfigurableApplicationContext context = Mockito.mock(); + MergedContextConfiguration mergedConfig = Mockito.mock(); // when final Exception expectedException = assertThrows(IllegalArgumentException.class, @@ -77,7 +77,7 @@ void testCustomizeContext_whenUsingAotGeneratedArtifactsBatchTestContextIsNotReg // given SpringProperties.setProperty("spring.aot.enabled", "true"); ConfigurableApplicationContext context = new GenericApplicationContext(); - MergedContextConfiguration mergedConfig = Mockito.mock(MergedContextConfiguration.class); + MergedContextConfiguration mergedConfig = Mockito.mock(); // when this.contextCustomizer.customizeContext(context, mergedConfig);