diff --git a/.github/workflows/central-sync.yml b/.github/workflows/central-sync.yml index 23b80ba2e48..5945f4478a9 100644 --- a/.github/workflows/central-sync.yml +++ b/.github/workflows/central-sync.yml @@ -31,9 +31,9 @@ jobs: GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }} GPG_FILE: ${{ secrets.GPG_FILE }} - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} run: | echo $GPG_FILE | base64 -d > secring.gpg ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository diff --git a/.github/workflows/graalvm-dev.yml b/.github/workflows/graalvm-dev.yml index eb0203b2168..fcb66c1f669 100644 --- a/.github/workflows/graalvm-dev.yml +++ b/.github/workflows/graalvm-dev.yml @@ -12,9 +12,9 @@ jobs: if: github.repository != 'micronaut-projects/micronaut-project-template' runs-on: ubuntu-latest env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} outputs: matrix: ${{ steps.build-matrix.outputs.matrix }} steps: @@ -38,9 +38,9 @@ jobs: - java: 'latest-ea' distribution: 'graalvm-community' env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} steps: - uses: actions/checkout@v4 - name: Pre-Build Steps diff --git a/.github/workflows/graalvm-latest.yml b/.github/workflows/graalvm-latest.yml index d150aa60641..e3053b0dc87 100644 --- a/.github/workflows/graalvm-latest.yml +++ b/.github/workflows/graalvm-latest.yml @@ -18,9 +18,9 @@ jobs: if: github.repository != 'micronaut-projects/micronaut-project-template' runs-on: ubuntu-latest env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} outputs: matrix: ${{ steps.build-matrix.outputs.matrix }} steps: @@ -38,9 +38,9 @@ jobs: java: ['17', '21'] native_test_task: ${{ fromJson(needs.build_matrix.outputs.matrix).native_test_task }} env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} steps: - uses: actions/checkout@v4 - name: Pre-Build Steps diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index d68b2586397..1b6c51c6171 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -21,15 +21,17 @@ jobs: matrix: java: ['17', '21'] env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} GH_TOKEN_PUBLIC_REPOS_READONLY: ${{ secrets.GH_TOKEN_PUBLIC_REPOS_READONLY }} GH_USERNAME: ${{ secrets.GH_USERNAME }} TESTCONTAINERS_RYUK_DISABLED: true PREDICTIVE_TEST_SELECTION: "${{ github.event_name == 'pull_request' && 'true' || 'false' }}" SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OSS_INDEX_USERNAME: ${{ secrets.OSS_INDEX_USERNAME }} + OSS_INDEX_PASSWORD: ${{ secrets.OSS_INDEX_PASSWORD }} steps: # https://github.com/actions/virtual-environments/issues/709 - name: "🗑 Free disk space" @@ -45,7 +47,7 @@ jobs: fetch-depth: 0 - name: "🔧 Setup GraalVM CE" - uses: graalvm/setup-graalvm@v1.2.7 + uses: graalvm/setup-graalvm@v1.2.6 with: distribution: 'graalvm' java-version: ${{ matrix.java }} @@ -61,7 +63,7 @@ jobs: - name: "🚔 Sonatype Scan" id: sonatypescan run: | - ./gradlew ossIndexAudit --no-parallel + ./gradlew ossIndexAudit --no-parallel --info - name: "🛠 Build with Gradle" id: gradle @@ -83,7 +85,7 @@ jobs: - name: "📜 Upload binary compatibility check results" if: matrix.java == '17' - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: binary-compatibility-reports path: "**/build/reports/binary-compatibility-*.html" diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 0875db9223f..fdfadd590bc 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -27,7 +27,7 @@ jobs: env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} run: ./gradlew publishToSonatype --no-daemon diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2762f3e22e6..7a8b46b1df9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,9 +40,9 @@ jobs: GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }} GPG_FILE: ${{ secrets.GPG_FILE }} - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} run: | echo $GPG_FILE | base64 -d > secring.gpg # Publish both locally and to Sonatype. @@ -66,13 +66,13 @@ jobs: # Store the hash in a file, which is uploaded as a workflow artifact. sha256sum $ARTIFACTS | base64 -w0 > artifacts-sha256 - name: Upload build artifacts - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: gradle-build-outputs path: build/repo/${{ steps.publish.outputs.group }}/*/${{ steps.publish.outputs.version }}/* retention-days: 5 - name: Upload artifacts-sha256 - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: artifacts-sha256 path: artifacts-sha256 @@ -80,9 +80,9 @@ jobs: - name: Generate docs run: ./gradlew docs env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} GH_TOKEN_PUBLIC_REPOS_READONLY: ${{ secrets.GH_TOKEN_PUBLIC_REPOS_READONLY }} GH_USERNAME: ${{ secrets.GH_USERNAME }} - name: Export Gradle Properties @@ -97,9 +97,9 @@ jobs: FOLDER: build/docs VERSION: ${{ steps.release_version.outputs.release_version }} TARGET_REPOSITORY: ${{ github.repository == 'micronaut-projects/micronaut-core' && env.docsRepository || github.repository }} - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} + DEVELOCITY_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} - name: Run post-release if: success() uses: micronaut-projects/github-actions/post-release@master diff --git a/core-processor/src/main/java/io/micronaut/inject/beans/visitor/IntrospectedTypeElementVisitor.java b/core-processor/src/main/java/io/micronaut/inject/beans/visitor/IntrospectedTypeElementVisitor.java index 10528838001..8871c56bce7 100644 --- a/core-processor/src/main/java/io/micronaut/inject/beans/visitor/IntrospectedTypeElementVisitor.java +++ b/core-processor/src/main/java/io/micronaut/inject/beans/visitor/IntrospectedTypeElementVisitor.java @@ -241,7 +241,7 @@ private void processBuilderDefinition(ClassElement element, VisitorContext conte creatorMethod, writePrefixes, methodElement, - element.getDefaultConstructor().orElse(null), + returnType.getDefaultConstructor().orElse(null), returnType, methodMetadata, index, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index eb71507dc32..a5e7688cf25 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,8 +2,8 @@ awaitility = "4.2.2" bcpkix = "1.70" blaze = "1.6.14" -brotli4j = "1.16.0" -bytebuddy = "1.15.11" +brotli4j = "1.18.0" +bytebuddy = "1.16.1" caffeine = "2.9.3" classgraph = "4.8.179" compile-testing = "0.21.0" @@ -30,7 +30,7 @@ jsr305 = "3.0.2" jakarta-el = "5.0.1" jakarta-el-impl = "5.0.0-M1" japicmp-gradle-plugin="0.4.5" -jazzer = "0.22.1" +jazzer = "0.23.0" jcache = "1.1.1" junit5 = "5.11.4" junit-platform="1.11.4" @@ -54,7 +54,7 @@ neo4j-java-driver = "5.17.0" selenium = "4.27.0" okio = "3.9.1" slf4j = "2.0.16" -smallrye = "6.4.1" +smallrye = "6.7.3" spock = "2.3-groovy-4.0" spotbugs = "4.7.1" systemlambda = "1.2.1" @@ -230,6 +230,7 @@ junit-platform-engine = { module = "org.junit.platform:junit-platform-suite-engi junit-vintage = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } jazzer-junit = { module = "com.code-intelligence:jazzer-junit", version.ref = "jazzer" } +jazzer-api = { module = "com.code-intelligence:jazzer-api", version.ref = "jazzer" } jetbrains-annotations = { module = "org.jetbrains:annotations", version.ref = "jetbrains-annotations" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 94113f200e6..cea7a793a84 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6d6b1..f3b75f3b0d4 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/PipeliningServerHandler.java b/http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/PipeliningServerHandler.java index 14310381958..a4869e1dc11 100644 --- a/http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/PipeliningServerHandler.java +++ b/http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/PipeliningServerHandler.java @@ -67,6 +67,7 @@ import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; +import java.io.EOFException; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; @@ -557,8 +558,15 @@ void read(Object message) { } } + @Override + void discard() { + // note: this has to match RoutingInBoundHandler#IGNORABLE_ERROR_MESSAGE + handleUpstreamError(new EOFException("Connection closed before full body was received")); + } + @Override void handleUpstreamError(Throwable cause) { + inboundHandler = droppingInboundHandler; dest.error(cause); } @@ -697,6 +705,12 @@ void readComplete() { void handleUpstreamError(Throwable cause) { delegate.handleUpstreamError(cause); } + + @Override + void discard() { + dispose(); + delegate.discard(); + } } /** @@ -820,6 +834,11 @@ private void write(OutboundHandler handler) { return; } + if (ctx.isRemoved()) { + handler.discardOutbound(); + return; + } + if (this.handler instanceof ContinueOutboundHandler cont) { cont.next = handler; writeSome(); diff --git a/http-server-netty/src/test/groovy/io/micronaut/http/server/netty/fuzzing/FlagAppender.java b/http-server-netty/src/test/groovy/io/micronaut/http/server/netty/fuzzing/FlagAppender.java index 76e78a47f88..df26d656a75 100644 --- a/http-server-netty/src/test/groovy/io/micronaut/http/server/netty/fuzzing/FlagAppender.java +++ b/http-server-netty/src/test/groovy/io/micronaut/http/server/netty/fuzzing/FlagAppender.java @@ -19,6 +19,10 @@ public static void checkTriggered() { @Override protected void append(ILoggingEvent eventObject) { + if (eventObject.getLoggerName().equals(BufferLeakDetection.class.getName())) { + // ignore 'Canary leak detection failed.' messages + return; + } triggered = true; } } diff --git a/http-server-netty/src/test/groovy/io/micronaut/http/server/netty/fuzzing/FuzzyInputSpec.groovy b/http-server-netty/src/test/groovy/io/micronaut/http/server/netty/fuzzing/FuzzyInputSpec.groovy index b4f9d564655..65edf3502ea 100644 --- a/http-server-netty/src/test/groovy/io/micronaut/http/server/netty/fuzzing/FuzzyInputSpec.groovy +++ b/http-server-netty/src/test/groovy/io/micronaut/http/server/netty/fuzzing/FuzzyInputSpec.groovy @@ -2,6 +2,7 @@ package io.micronaut.http.server.netty.fuzzing import io.micronaut.context.ApplicationContext import io.micronaut.context.annotation.Requires +import io.micronaut.http.annotation.Body import io.micronaut.http.annotation.Controller import io.micronaut.http.annotation.Get import io.micronaut.http.annotation.Post @@ -84,8 +85,10 @@ class FuzzyInputSpec extends Specification { when: def embeddedChannel = embeddedServer.buildEmbeddedChannel(false) - embeddedChannel.writeInbound(Unpooled.wrappedBuffer(input)); - embeddedChannel.runPendingTasks(); + def b = embeddedChannel.alloc().buffer(input.length) + b.writeBytes(input) + embeddedChannel.writeInbound(b) + embeddedChannel.runPendingTasks() embeddedChannel.releaseOutbound() // don't release inbound, that doesn't happen normally either @@ -110,6 +113,8 @@ class FuzzyInputSpec extends Specification { Base64.decoder.decode("VCB4dCBQLzUuMQoKUDIg/CBIUFRQLzEuMgotdHlwZTo3ClRyYX5zZmVyLUVuRVRUbmc6ZGVmbGF0ZQoKL7lFUDIg/CBIUFRQLzEuMQotdHlwZTotdHlwZTo3ClRyYW5zZmVyeXBlOjf///////////////////////////////////////////////////////////////////////////////////////////8KVHJhbnNmZXItRW5jb2Rpbmc6ZGVmbGF0ZQpjb250ZW50LWxlbmd0aDo4CgoNSU9OUyAvILiqVFAvCgovuUVQMkdHR0d3AC07biE="), Base64.decoder.decode("UyAvIFAvMC4xMQpjb250ZW50LWxlbmd0aDo0ClRyYW5zZmVyLUVuY29kaW5nOmRlZmxhdGUKCi+5RVAyIPwgSC8xLjEK"), Base64.decoder.decode("cA1ACUhUVFAvOC4wCkhvc3Q6OgpPcmlnaW46Cgo="), + Base64.decoder.decode("SEVDc3QNQP/9P/8JSFRUUC8wLjEKZXB0OgoKcG9zdA1A/T/9Oi8v/y9lY2hvLXB1Ymxpc2hlcglIVFRQLzAuMQp0OgpDb250ZW50LUxlbmd0aDo1Cgr/"), + Base64.decoder.decode("SEVDRCBIIEhUVFAvMS4wCiY6MwoKcG9zdA1A//0//wlIVFRQLzAuMQplcHQ6Cgpwb3N0DUD9P/06Ly//L2VjaG8tcHVibGlzaGVyCUhUVFAvMC4xCnQ6CkNvbnRlbnQtTGVuZ3RoOjUKCv8="), ] } @@ -126,5 +131,10 @@ class FuzzyInputSpec extends Specification { public Publisher index(Publisher foo) { return foo } + + @Post("/echo-publisher") + public Publisher echo(@Body Publisher foo) { + return foo; + } } } diff --git a/http-server/src/main/java/io/micronaut/http/server/RouteExecutor.java b/http-server/src/main/java/io/micronaut/http/server/RouteExecutor.java index 7fce9f7baba..1b46c3cba61 100644 --- a/http-server/src/main/java/io/micronaut/http/server/RouteExecutor.java +++ b/http-server/src/main/java/io/micronaut/http/server/RouteExecutor.java @@ -72,6 +72,7 @@ import reactor.core.scheduler.Schedulers; import java.io.IOException; +import java.nio.channels.ClosedChannelException; import java.time.LocalDateTime; import java.util.Iterator; import java.util.List; @@ -273,6 +274,9 @@ void logException(Throwable cause) { } static boolean isIgnorable(Throwable cause) { + if (cause instanceof ClosedChannelException) { + return true; + } String message = cause.getMessage(); return cause instanceof IOException && message != null && IGNORABLE_ERROR_MESSAGE.matcher(message).matches(); } diff --git a/http/build.gradle.kts b/http/build.gradle.kts index 0ef00555ef9..f53d71153e2 100644 --- a/http/build.gradle.kts +++ b/http/build.gradle.kts @@ -22,6 +22,7 @@ dependencies { testImplementation(projects.micronautRuntime) testImplementation(libs.logback.classic) testImplementation(libs.jazzer.junit) + testImplementation(libs.jazzer.api) testImplementation(libs.junit.jupiter.params) testImplementation(libs.micronaut.test.junit5) { exclude(group= "io.micronaut") diff --git a/inject-java-test/src/test/groovy/io/micronaut/inject/beanimport/BeanImportSpec.groovy b/inject-java-test/src/test/groovy/io/micronaut/inject/beanimport/BeanImportSpec.groovy index 2243e3e8385..5c77d6c7d84 100644 --- a/inject-java-test/src/test/groovy/io/micronaut/inject/beanimport/BeanImportSpec.groovy +++ b/inject-java-test/src/test/groovy/io/micronaut/inject/beanimport/BeanImportSpec.groovy @@ -2,7 +2,6 @@ package io.micronaut.inject.beanimport import io.micronaut.annotation.processing.test.AbstractTypeElementSpec import io.micronaut.context.ApplicationContext -import io.smallrye.faulttolerance.CdiFaultToleranceSpi import io.smallrye.faulttolerance.CircuitBreakerMaintenanceImpl import io.smallrye.faulttolerance.DefaultAsyncExecutorProvider import io.smallrye.faulttolerance.DefaultExistingCircuitBreakerNames @@ -54,9 +53,7 @@ class Application {} expect: context.containsBean(DefaultAsyncExecutorProvider) context.containsBean(CircuitBreakerMaintenanceImpl) - context.containsBean(CdiFaultToleranceSpi.EagerDependencies) context.containsBean(DefaultExistingCircuitBreakerNames) - context.containsBean(CdiFaultToleranceSpi.EagerDependencies) context.containsBean(DefaultFallbackHandlerProvider) context.getBeanDefinition(DefaultFallbackHandlerProvider) .injectedFields.size() == 1 @@ -79,7 +76,6 @@ import io.smallrye.faulttolerance.*; @io.micronaut.context.annotation.Import(classes={ DefaultAsyncExecutorProvider.class, CircuitBreakerMaintenanceImpl.class, - CdiFaultToleranceSpi.EagerDependencies.class, DefaultExistingCircuitBreakerNames.class, DefaultFallbackHandlerProvider.class, DefaultFaultToleranceOperationProvider.class, @@ -91,7 +87,6 @@ class Application {} expect: context.containsBean(DefaultAsyncExecutorProvider) context.containsBean(CircuitBreakerMaintenanceImpl) - context.containsBean(CdiFaultToleranceSpi.EagerDependencies) context.containsBean(DefaultExistingCircuitBreakerNames) context.containsBean(DefaultFallbackHandlerProvider) context.getBeanDefinition(DefaultFallbackHandlerProvider) diff --git a/test-suite/src/test/java/io/micronaut/test/lombok/BarCommand.java b/test-suite/src/test/java/io/micronaut/test/lombok/BarCommand.java new file mode 100644 index 00000000000..0d75a582a31 --- /dev/null +++ b/test-suite/src/test/java/io/micronaut/test/lombok/BarCommand.java @@ -0,0 +1,23 @@ +package io.micronaut.test.lombok; + +import io.micronaut.core.annotation.Introspected; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Introspected +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class BarCommand { + + private String foo; + + private String bar; + + private String baz; +} diff --git a/test-suite/src/test/java/io/micronaut/test/lombok/LombokIntrospectedBuilderTest.java b/test-suite/src/test/java/io/micronaut/test/lombok/LombokIntrospectedBuilderTest.java index 572133d622f..1a4c6530aa2 100644 --- a/test-suite/src/test/java/io/micronaut/test/lombok/LombokIntrospectedBuilderTest.java +++ b/test-suite/src/test/java/io/micronaut/test/lombok/LombokIntrospectedBuilderTest.java @@ -15,6 +15,19 @@ public class LombokIntrospectedBuilderTest { + @Test + void testNoArgsAndAllArgsConstructor() { + BeanIntrospection introspection = BeanIntrospection.getIntrospection(BarCommand.class); + + BeanIntrospection.Builder builder = introspection.builder(); + + builder.with("foo", "one"); + builder.with("bar", "two"); + builder.with("baz", "three"); + BarCommand result = builder.build(); + assertEquals("BarCommand(foo=one, bar=two, baz=three)", result.toString()); + } + @Test void testLombokNoArgsConstructor() { BeanIntrospection introspection = BeanIntrospection.getIntrospection(Book.class);