├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ ├── config.yml │ ├── new_feature.yaml │ └── other.yaml ├── renovate.json ├── stale.yml └── workflows │ ├── central-sync.yml │ ├── graalvm-dev.yml │ ├── graalvm-latest.yml │ ├── gradle.yml │ ├── publish-snapshot.yml │ ├── release.yml │ └── update-gradle-wrapper.yml ├── .gitignore ├── LICENSE ├── MAINTAINING.md ├── README.md ├── SECURITY.md ├── aot-plugin ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ └── aot │ │ ├── AOTExtension.java │ │ ├── AOTOptimizations.java │ │ ├── AbstractMicronautAotCliTask.java │ │ ├── AotShadowSupport.java │ │ ├── MergeServiceFiles.java │ │ ├── MicronautAOTConfigWriterTask.java │ │ ├── MicronautAotOptimizerTask.java │ │ ├── MicronautAotPlugin.java │ │ ├── MicronautAotSampleConfTask.java │ │ ├── NettyOptimizations.java │ │ └── OptimizerIO.java │ ├── templates │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ └── aot │ │ └── Versions.java │ └── test │ └── groovy │ └── io │ └── micronaut │ └── gradle │ └── aot │ └── AotOptimizerConfigurationSpec.groovy ├── build.gradle ├── buildSrc ├── build.gradle └── src │ └── main │ └── groovy │ ├── io.micronaut.internal.build.documented.gradle │ ├── io.micronaut.internal.build.functional-testing.gradle │ ├── io.micronaut.internal.build.gradle-plugin.gradle │ ├── io.micronaut.internal.build.processed-sources.gradle │ ├── io.micronaut.internal.build.testing.gradle │ └── io │ └── micronaut │ └── internal │ └── build │ ├── docs │ └── Themer.groovy │ ├── plugin │ └── MicronautPluginExtension.java │ ├── sourcegen │ ├── SimpleSourceProcessor.java │ └── WriteVersions.java │ └── test │ └── FunctionalTestingExtension.groovy ├── config ├── HEADER ├── checkstyle │ ├── checkstyle.xml │ └── suppressions.xml └── spotless.license.java ├── crac-plugin ├── build.gradle └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── micronaut │ │ │ └── gradle │ │ │ └── crac │ │ │ ├── CRaCCheckpointDockerfile.java │ │ │ ├── CRaCConfiguration.java │ │ │ ├── CRaCFinalDockerfile.java │ │ │ ├── MicronautCRaCPlugin.java │ │ │ ├── TeeStringWriter.java │ │ │ └── tasks │ │ │ └── CheckpointScriptTask.java │ └── resources │ │ ├── checkpoint.sh │ │ ├── run.sh │ │ └── warmup.sh │ └── test │ └── groovy │ └── io │ └── micronaut │ └── gradle │ └── crac │ ├── BaseCracGradleBuildSpec.groovy │ ├── CracBuildTaskSpec.groovy │ └── CracCustomizationSpec.groovy ├── docker-plugin ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ └── docker │ │ ├── DockerBuildOptions.java │ │ ├── DockerExtension.java │ │ ├── DockerfileEditor.java │ │ ├── MicronautDockerPlugin.java │ │ ├── MicronautDockerfile.java │ │ ├── NativeImageDockerfile.java │ │ ├── editor │ │ ├── DefaultEditor.java │ │ ├── Editor.java │ │ └── FingerprintingEditor.java │ │ ├── model │ │ ├── DefaultMicronautDockerImage.java │ │ ├── Layer.java │ │ ├── LayerKind.java │ │ ├── MicronautDockerImage.java │ │ └── RuntimeKind.java │ │ └── tasks │ │ ├── BuildLayersTask.java │ │ ├── DockerResourceConfigDirectoryNamer.java │ │ └── PrepareDockerContext.java │ └── test │ ├── groovy │ └── io │ │ └── micronaut │ │ └── gradle │ │ ├── BuildLayersSpec.groovy │ │ ├── DockerBuildTaskSpec.groovy │ │ └── docker │ │ └── editor │ │ └── DefaultEditorTest.groovy │ └── resources │ ├── dummy-metadata.xml │ └── test-maven-metadata.xml ├── functional-tests ├── build.gradle └── src │ └── test │ ├── groovy │ └── io │ │ └── micronaut │ │ └── gradle │ │ ├── FullMicronautRuntimeSpec.groovy │ │ ├── RuntimeDependenciesSpec.groovy │ │ ├── aot │ │ ├── AbstractAOTPluginSpec.groovy │ │ ├── BasicMicronautAOTSpec.groovy │ │ ├── FunctionsMicronautAOTSpec.groovy │ │ ├── MicronautAOTDockerSpec.groovy │ │ └── ShadowMicronautAOTSpec.groovy │ │ ├── docker │ │ └── DockerNativeFunctionalTest.groovy │ │ ├── fixtures │ │ ├── AbstractEagerConfiguringFunctionalTest.groovy │ │ └── AbstractFunctionalTest.groovy │ │ ├── graalvm │ │ └── MicronautGraalPluginSpec.groovy │ │ ├── kotlin │ │ ├── Kotest5FunctionalTest.groovy │ │ └── KotlinLibraryFunctionalTest.groovy │ │ ├── lambda │ │ └── LambdaNativeImageSpec.groovy │ │ ├── openapi │ │ ├── AbstractOpenApiWithKotlinSpec.groovy │ │ ├── OpenApiClientWithKotlinSpec.groovy │ │ └── OpenApiServerWithKotlinSpec.groovy │ │ ├── settings │ │ └── VersionOverrideFunctionalTest.groovy │ │ ├── shadow │ │ └── ShadowJarSpec.groovy │ │ └── testresources │ │ ├── AbstractTestResourcesSpec.groovy │ │ ├── TestResourcesWithAotAndGraalVMSpec.groovy │ │ ├── TestResourcesWithAotSpec.groovy │ │ └── TestResourcesWithGraalVMSpec.groovy │ └── resources │ └── petstore.json ├── graalvm-plugin ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ └── graalvm │ │ ├── GraalUtil.java │ │ └── MicronautGraalPlugin.java │ └── test │ └── groovy │ └── io │ └── micronaut │ └── gradle │ ├── MicronautGraalWellBehavePluginSpec.groovy │ ├── NativeImageMultiProjectSpec.groovy │ └── NativeImageTaskSpec.groovy ├── gradle-plugin ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ ├── MicronautApplicationPlugin.java │ │ └── MicronautLibraryPlugin.java │ └── test │ └── groovy │ └── io │ └── micronaut │ └── gradle │ ├── MicronautApplicationPluginSpec.groovy │ └── MicronautLibraryPluginSpec.groovy ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jsonschema-plugin ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ └── jsonschema │ │ ├── DefaultJSONSchemaExtension.java │ │ ├── JSONSchemaExtension.java │ │ ├── JsonSchemaFileSpec.java │ │ ├── JsonSchemaSpec.java │ │ ├── JsonSchemaURLSpec.java │ │ ├── MicronautJSONSchemaPlugin.java │ │ └── tasks │ │ ├── AbstractJsonSchemaGenerator.java │ │ ├── AbstractJsonSchemaWorkAction.java │ │ ├── JsonSchemaFileGenerator.java │ │ ├── JsonSchemaFileWorkAction.java │ │ ├── JsonSchemaFolderGenerator.java │ │ ├── JsonSchemaFolderWorkAction.java │ │ ├── JsonSchemaUrlGenerator.java │ │ └── JsonSchemaUrlWorkAction.java │ └── test │ ├── groovy │ └── io │ │ └── micronaut │ │ └── gradle │ │ └── jsonschema │ │ └── JsonSchemaGeneratorSpec.groovy │ └── resources │ ├── animal.schema.json │ └── refFolder │ └── ref │ ├── head.schema.json │ └── types │ └── cheatsheet.schema.json ├── minimal-plugin ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ ├── AnnotationProcessing.java │ │ ├── AnnotationProcessingConfigBuilder.java │ │ ├── ApplicationClasspathInspector.java │ │ ├── AttributeUtils.java │ │ ├── LenientGradle.java │ │ ├── MicronautBasePlugin.java │ │ ├── MicronautComponentPlugin.java │ │ ├── MicronautExtension.java │ │ ├── MicronautKotlinSupport.java │ │ ├── MicronautMinimalApplicationPlugin.java │ │ ├── MicronautMinimalLibraryPlugin.java │ │ ├── MicronautRuntime.java │ │ ├── MicronautRuntimeDependencies.java │ │ ├── MicronautTestRuntime.java │ │ ├── PluginsHelper.java │ │ ├── ShadowPluginSupport.java │ │ ├── SourceSetConfigurer.java │ │ ├── SourceSetConfigurerRegistry.java │ │ ├── Strings.java │ │ ├── docker │ │ └── DockerBuildStrategy.java │ │ ├── graalvm │ │ ├── GraalUtil.java │ │ ├── NativeLambdaExtension.java │ │ └── NativeLambdaRuntime.java │ │ └── internal │ │ ├── AutomaticDependency.java │ │ ├── ConfigurableVersionProperty.java │ │ ├── Dependencies.java │ │ └── VersionCatalogLookupCache.java │ ├── test │ └── groovy │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ ├── AutomaticDependencySpec.groovy │ │ ├── MicronautDeprecationsPluginSpec.groovy │ │ ├── MicronautMinimalApplicationPluginSpec.groovy │ │ ├── MicronautMinimalLibraryPluginSpec.groovy │ │ └── MicronautRuntimeSpec.groovy │ └── testFixtures │ └── groovy │ └── io │ └── micronaut │ └── gradle │ └── AbstractGradleBuildSpec.groovy ├── openapi-plugin ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ └── openapi │ │ ├── DefaultOpenApiExtension.java │ │ ├── MicronautOpenAPIPlugin.java │ │ ├── OpenApiClientSpec.java │ │ ├── OpenApiExtension.java │ │ ├── OpenApiServerSpec.java │ │ ├── OpenApiSpec.java │ │ ├── ParameterMappingModel.java │ │ ├── ResponseBodyMappingModel.java │ │ └── tasks │ │ ├── AbstractOpenApiGenerator.java │ │ ├── AbstractOpenApiWorkAction.java │ │ ├── OpenApiClientGenerator.java │ │ ├── OpenApiClientWorkAction.java │ │ ├── OpenApiServerGenerator.java │ │ └── OpenApiServerWorkAction.java │ └── test │ ├── groovy │ └── io │ │ └── micronaut │ │ └── openapi │ │ └── gradle │ │ ├── AbstractOpenApiGeneratorSpec.groovy │ │ ├── OpenApiClientGeneratorSpec.groovy │ │ └── OpenApiServerGeneratorSpec.groovy │ └── resources │ └── petstore.json ├── platform-catalog-plugin ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── micronaut │ │ └── gradle │ │ └── catalog │ │ ├── LenientVersionCatalogParser.java │ │ ├── Library.java │ │ ├── MicronautCatalogSettingsPlugin.java │ │ ├── RichVersion.java │ │ ├── RichVersionParser.java │ │ ├── VersionCatalogTomlModel.java │ │ └── VersionModel.java │ └── test │ └── groovy │ └── io │ └── micronaut │ └── gradle │ └── settings │ └── CatalogPluginFunctionalTest.groovy ├── samples ├── aot │ ├── app-startup-fixture │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── micronaut │ │ │ └── aot │ │ │ └── fixture │ │ │ └── ApplicationStartupInterruption.java │ ├── aws-function │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── settings.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── example │ │ │ │ │ └── micronaut │ │ │ │ │ ├── Book.java │ │ │ │ │ ├── BookRequestHandler.java │ │ │ │ │ └── BookSaved.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── logback.xml │ │ │ └── test │ │ │ └── java │ │ │ └── example │ │ │ └── micronaut │ │ │ └── BookRequestHandlerTest.java │ ├── basic-app │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── settings.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── demo │ │ │ │ └── app │ │ │ │ └── Application.java │ │ │ └── resources │ │ │ └── logback.xml │ └── with-shadow │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── settings.gradle │ │ └── src │ │ └── main │ │ └── java │ │ └── demo │ │ └── app │ │ └── Application.java └── test-resources │ ├── custom-test-resource │ ├── build.gradle │ ├── gradle.properties │ ├── settings.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── demo │ │ │ │ └── Application.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── logback.xml │ │ ├── test │ │ └── java │ │ │ └── demo │ │ │ └── DemoTest.java │ │ └── testResources │ │ ├── java │ │ └── demo │ │ │ └── GreetingTestResource.java │ │ └── resources │ │ └── META-INF │ │ └── services │ │ └── io.micronaut.testresources.core.TestResourcesResolver │ ├── data-mysql │ ├── build.gradle │ ├── gradle.properties │ ├── settings.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── demo │ │ │ │ ├── Application.java │ │ │ │ ├── Book.java │ │ │ │ ├── BookController.java │ │ │ │ ├── BookRepository.java │ │ │ │ ├── User.java │ │ │ │ ├── UserController.java │ │ │ │ └── UserRepository.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── logback.xml │ │ └── test │ │ └── java │ │ └── demo │ │ └── DemoTest.java │ ├── isolated-multiproject │ ├── README.md │ ├── app1 │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── demo │ │ │ │ │ ├── Application.java │ │ │ │ │ ├── Book.java │ │ │ │ │ ├── BookController.java │ │ │ │ │ ├── BookRepository.java │ │ │ │ │ ├── User.java │ │ │ │ │ ├── UserController.java │ │ │ │ │ └── UserRepository.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── logback.xml │ │ │ └── test │ │ │ └── java │ │ │ └── demo │ │ │ └── DemoTest.java │ ├── app2 │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── demo │ │ │ │ │ ├── Application.java │ │ │ │ │ ├── Book.java │ │ │ │ │ ├── BookController.java │ │ │ │ │ ├── BookRepository.java │ │ │ │ │ ├── User.java │ │ │ │ │ ├── UserController.java │ │ │ │ │ └── UserRepository.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── logback.xml │ │ │ └── test │ │ │ └── java │ │ │ └── demo │ │ │ └── DemoTest.java │ ├── app3 │ │ ├── build.gradle │ │ └── src │ │ │ ├── test │ │ │ └── java │ │ │ │ └── demo │ │ │ │ └── DemoTest.java │ │ │ └── testResources │ │ │ ├── java │ │ │ └── demo │ │ │ │ └── GreetingTestResource.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── io.micronaut.testresources.core.TestResourcesResolver │ ├── gradle.properties │ └── settings.gradle │ └── multiproject │ ├── README.md │ ├── app1 │ ├── build.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── demo │ │ │ │ ├── Application.java │ │ │ │ ├── Book.java │ │ │ │ ├── BookController.java │ │ │ │ ├── BookRepository.java │ │ │ │ ├── User.java │ │ │ │ ├── UserController.java │ │ │ │ └── UserRepository.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── logback.xml │ │ └── test │ │ └── java │ │ └── demo │ │ └── DemoTest.java │ ├── app2 │ ├── build.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── demo │ │ │ │ ├── Application.java │ │ │ │ ├── Book.java │ │ │ │ ├── BookController.java │ │ │ │ ├── BookRepository.java │ │ │ │ ├── User.java │ │ │ │ ├── UserController.java │ │ │ │ └── UserRepository.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── logback.xml │ │ └── test │ │ └── java │ │ └── demo │ │ └── DemoTest.java │ ├── app3 │ ├── build.gradle │ └── src │ │ └── test │ │ └── java │ │ └── demo │ │ └── DemoTest.java │ ├── gradle.properties │ ├── settings.gradle │ └── testresources │ ├── build.gradle │ └── src │ └── testResources │ ├── java │ └── demo │ │ └── GreetingTestResource.java │ └── resources │ └── META-INF │ └── services │ └── io.micronaut.testresources.core.TestResourcesResolver ├── settings.gradle ├── src └── docs │ └── asciidoc │ ├── css │ ├── guide.css │ ├── highlight.css │ └── multi-lang-sample.css │ ├── highlight │ └── highlight.min.js │ ├── index.adoc │ ├── js │ └── multi-lang-sample.js │ └── template │ └── template.html └── test-resources-plugin ├── build.gradle └── src ├── main └── java │ └── io │ └── micronaut │ └── gradle │ └── testresources │ ├── MicronautTestResourcesConsumerPlugin.java │ ├── MicronautTestResourcesPlugin.java │ ├── ServerConnectionParametersProvider.java │ ├── StartTestResourcesService.java │ ├── StopTestResourcesService.java │ ├── TestResourcesConfiguration.java │ └── internal │ ├── TestResourcesAOT.java │ └── TestResourcesGraalVM.java └── test └── groovy └── io └── micronaut └── gradle └── testresources ├── ApplicationTestResourcesPluginSpec.groovy ├── CustomTestResourcePluginSpec.groovy ├── MicronautTestResourcesPluginTest.groovy └── MultiProjectTestResourcePluginSpec.groovy /.github/ISSUE_TEMPLATE/bug_report.yaml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | Thanks for reporting an issue, please review the task list below before submitting the issue. Your issue report will be closed if the issue is incomplete and the below tasks not completed. 8 | 9 | NOTE: If you are unsure about something and the issue is more of a question a better place to ask questions is on Github Discussions :arrow_up:, [Stack Overflow](https://stackoverflow.com/tags/micronaut) or [Gitter](https://gitter.im/micronautfw/). 10 | - type: textarea 11 | attributes: 12 | label: Expected Behavior 13 | description: A concise description of what you expected to happen. 14 | placeholder: Tell us what should happen 15 | validations: 16 | required: false 17 | - type: textarea 18 | attributes: 19 | label: Actual Behaviour 20 | description: A concise description of what you're experiencing. 21 | placeholder: Tell us what happens instead 22 | validations: 23 | required: false 24 | - type: textarea 25 | attributes: 26 | label: Steps To Reproduce 27 | description: Steps to reproduce the behavior. 28 | placeholder: | 29 | 1. In this environment... 30 | 2. With this config... 31 | 3. Run '...' 32 | 4. See error... 33 | validations: 34 | required: false 35 | - type: textarea 36 | attributes: 37 | label: Environment Information 38 | description: Environment information where the problem occurs. 39 | placeholder: | 40 | - Operating System: 41 | - JDK Version: 42 | validations: 43 | required: false 44 | - type: input 45 | id: example 46 | attributes: 47 | label: Example Application 48 | description: Example application link. 49 | placeholder: | 50 | Link to GitHub repository with an example that reproduces the issue 51 | validations: 52 | required: false 53 | - type: input 54 | id: version 55 | attributes: 56 | label: Version 57 | description: Micronaut version 58 | validations: 59 | required: true 60 | 61 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Micronaut Core Discussions 3 | url: https://github.com/micronaut-projects/micronaut-core/discussions 4 | about: Ask questions about Micronaut on Github 5 | - name: Micronaut Data Discussions 6 | url: https://github.com/micronaut-projects/micronaut-data/discussions 7 | about: Ask Micronaut Data related questions on Github 8 | - name: Stack Overflow 9 | url: https://stackoverflow.com/tags/micronaut 10 | about: Ask questions on Stack Overflow 11 | - name: Chat 12 | url: https://gitter.im/micronautfw/ 13 | about: Chat with us on Gitter. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new_feature.yaml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Create a new feature request 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | Please describe the feature you want for Micronaut to implement, before that check if there is already an existing issue to add it. 8 | - type: textarea 9 | attributes: 10 | label: Feature description 11 | placeholder: Tell us what feature you would like for Micronaut to have and what problem is it going to solve 12 | validations: 13 | required: true 14 | 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/other.yaml: -------------------------------------------------------------------------------- 1 | name: Other 2 | description: Something different 3 | body: 4 | - type: textarea 5 | attributes: 6 | label: Issue description 7 | validations: 8 | required: true 9 | 10 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "addLabels": ["dependency-upgrade"], 6 | "schedule": [ 7 | "every weekend" 8 | ], 9 | "prHourlyLimit": 1, 10 | "prConcurrentLimit": 20, 11 | "timezone": "Europe/Prague" 12 | } 13 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - "type: enhancement" 8 | # Label to use when marking an issue as stale 9 | staleLabel: "status: stale" 10 | # Comment to post when marking an issue as stale. Set to `false` to disable 11 | markComment: > 12 | This issue has been automatically marked as stale because it has not had 13 | recent activity. It will be closed if no further activity occurs. Thank you 14 | for your contributions. 15 | # Comment to post when closing a stale issue. Set to `false` to disable 16 | closeComment: false 17 | -------------------------------------------------------------------------------- /.github/workflows/central-sync.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Do not edit this file directly. Instead, go to: 2 | # 3 | # https://github.com/micronaut-projects/micronaut-project-template/tree/master/.github/workflows 4 | # 5 | # and edit them there. Note that it will be sync'ed to all the Micronaut repos 6 | name: Maven Central Sync 7 | on: 8 | workflow_dispatch: 9 | inputs: 10 | release_version: 11 | description: 'Release version (eg: 1.2.3)' 12 | required: true 13 | jobs: 14 | central-sync: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v4 19 | with: 20 | ref: v${{ github.event.inputs.release_version }} 21 | - uses: gradle/wrapper-validation-action@v3 22 | - name: Set up JDK 23 | uses: actions/setup-java@v4 24 | with: 25 | distribution: 'temurin' 26 | java-version: '17' 27 | - name: Publish to Sonatype OSSRH 28 | env: 29 | SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} 30 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} 31 | GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} 32 | GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }} 33 | GPG_FILE: ${{ secrets.GPG_FILE }} 34 | GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} 35 | GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} 36 | GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} 37 | run: | 38 | echo $GPG_FILE | base64 -d > secring.gpg 39 | ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository 40 | -------------------------------------------------------------------------------- /.github/workflows/publish-snapshot.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Do not edit this file directly. Instead, go to: 2 | # 3 | # https://github.com/micronaut-projects/micronaut-project-template/tree/master/.github/workflows 4 | # 5 | # and edit them there. Note that it will be sync'ed to all the Micronaut repos 6 | name: Publish snapshot release 7 | on: [workflow_dispatch] 8 | jobs: 9 | build: 10 | if: github.repository != 'micronaut-projects/micronaut-project-template' 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/cache@v4 15 | with: 16 | path: ~/.gradle/caches 17 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 18 | restore-keys: | 19 | ${{ runner.os }}-gradle- 20 | - name: Set up JDK 21 | uses: actions/setup-java@v4 22 | with: 23 | distribution: 'temurin' 24 | java-version: '17' 25 | - name: Publish to Sonatype Snapshots 26 | if: success() 27 | env: 28 | SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} 29 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} 30 | GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} 31 | GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} 32 | GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} 33 | run: ./gradlew publishToSonatype --no-daemon 34 | -------------------------------------------------------------------------------- /.github/workflows/update-gradle-wrapper.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Do not edit this file directly. Instead, go to: 2 | # 3 | # https://github.com/micronaut-projects/micronaut-project-template/tree/master/.github/workflows 4 | # 5 | # and edit them there. Note that it will be sync'ed to all the Micronaut repos 6 | name: Update Gradle Wrapper 7 | on: 8 | schedule: 9 | - cron: '0 3 * * SAT' 10 | jobs: 11 | update-wrapper: 12 | if: github.repository == 'micronaut-projects/micronaut-project-template' 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | token: ${{ secrets.GH_TOKEN }} 18 | - name: "Update Gradle Wrapper" 19 | id: update 20 | env: 21 | GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} 22 | GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USERNAME }} 23 | GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} 24 | run: | 25 | latest=`curl -s https://services.gradle.org/versions/current | jq -cr ".version"` 26 | echo ::set-output name=latest_version::${latest} 27 | ./gradlew wrapper --gradle-version $latest 28 | - uses: gradle/wrapper-validation-action@v3 29 | - uses: stefanzweifel/git-auto-commit-action@v5.1.0 30 | with: 31 | commit_message: Upgrade Gradle Wrapper to ${{ steps.update.outputs.latest_version }} 32 | commit_user_name: micronaut-build 33 | commit_user_email: ${{ secrets.MICRONAUT_BUILD_EMAIL }} 34 | commit_author: micronaut-build <${{ secrets.MICRONAUT_BUILD_EMAIL }}> 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | .DS_Store 3 | target/ 4 | .gradle/ 5 | .idea/ 6 | build/ 7 | !buildSrc/src/** 8 | !build-logic/src/main/java/io/micronaut/build 9 | classes/ 10 | out/ 11 | *.db 12 | *.log 13 | *.iml 14 | .classpath 15 | .factorypath 16 | bin/ 17 | .settings/ 18 | .project 19 | */test/ 20 | */META-INF/ 21 | *.ipr 22 | *.iws 23 | .kotlintest 24 | */.kotlintest/ 25 | 26 | # ignore resources, are downloaded via a gradle task from micronaut_docs 27 | src/main/docs/resources/css/highlight/*.css 28 | src/main/docs/resources/css/highlight/*.png 29 | src/main/docs/resources/css/highlight/*.jpg 30 | src/main/docs/resources/css/*.css 31 | src/main/docs/resources/js/*.js 32 | src/main/docs/resources/style/*.html 33 | src/main/docs/resources/img/micronaut-logo-white.svg 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Micronaut Gradle Plugin 2 | [![Revved up by Develocity](https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.micronaut.io/scans) 3 | 4 | 5 | A Gradle Plugin which makes development of Micronaut application and libraries a breeze. 6 | 7 | Please refer to the [documentation](https://micronaut-projects.github.io/micronaut-gradle-plugin/latest/) for help. 8 | 9 | Documentation for the development version of the plugin can be found [here](https://micronaut-projects.github.io/micronaut-gradle-plugin/snapshot/). 10 | 11 | Documentation for the 3.x version of the plugin can be found [here](https://github.com/micronaut-projects/micronaut-gradle-plugin/tree/3.7.x#readme). 12 | 13 | Documentation for the 2.x version of the plugin can be found [here](https://github.com/micronaut-projects/micronaut-gradle-plugin/tree/2.0.x#readme). 14 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | We release patches for security vulnerabilities. Which versions are eligible 4 | receiving such patches depend on the CVSS v3.0 Rating: 5 | 6 | | CVSS v3.0 | Supported Versions | 7 | |-----------|-------------------------------------------| 8 | | 9.0-10.0 | Releases within the previous three months | 9 | | 4.0-8.9 | Most recent release | 10 | 11 | ## Reporting a Vulnerability 12 | 13 | Please responsibly disclose (suspected) security vulnerabilities to 14 | **[The Micronaut Foundation](foundation@micronaut.io)**. You will receive a response from 15 | us within 48 hours. If the issue is confirmed, we will release a patch as soon 16 | as possible depending on complexity but historically within a few days. 17 | -------------------------------------------------------------------------------- /aot-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | id "io.micronaut.internal.build.processed-sources" 4 | } 5 | 6 | description = "Micronaut AOT Gradle plugin" 7 | 8 | micronautPlugins { 9 | register('aot', 'io.micronaut.gradle.aot.MicronautAotPlugin', 'Micronaut AOT Plugin') 10 | } 11 | 12 | dependencies { 13 | api projects.micronautMinimalPlugin 14 | api projects.micronautDockerPlugin 15 | api projects.micronautGraalvmPlugin 16 | 17 | implementation libs.micronaut.aot.api 18 | implementation libs.micronaut.aot.core 19 | implementation libs.micronaut.aot.std 20 | implementation libs.micronaut.aot.cli 21 | 22 | compileOnly libs.bundles.optionalPlugins 23 | compileOnly libs.shadowPlugin 24 | 25 | testImplementation testFixtures(projects.micronautMinimalPlugin) 26 | } 27 | -------------------------------------------------------------------------------- /aot-plugin/src/main/java/io/micronaut/gradle/aot/AOTExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.aot; 17 | 18 | import org.gradle.api.file.RegularFileProperty; 19 | import org.gradle.api.provider.Property; 20 | import org.gradle.api.tasks.Input; 21 | import org.gradle.api.tasks.InputFile; 22 | import org.gradle.api.tasks.Optional; 23 | 24 | /** 25 | * Micronaut AOT extension, used to configure 26 | * the ahead-of-time/build time optimizations. 27 | */ 28 | public interface AOTExtension extends AOTOptimizations { 29 | /** 30 | * Allows configuring the Micronaut AOT version to use. 31 | * @return the Micronaut AOT version 32 | */ 33 | @Optional 34 | @Input 35 | Property getVersion(); 36 | 37 | /** 38 | * Path to a user provided AOT configuration file. If not 39 | * provided, the plugin will use reasonable defaults. If 40 | * it's provided, the file will be read and merged with 41 | * options configured in this extension. 42 | * @return the configuration file 43 | */ 44 | @Optional 45 | @InputFile 46 | RegularFileProperty getConfigFile(); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /aot-plugin/src/main/java/io/micronaut/gradle/aot/MicronautAotSampleConfTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.aot; 17 | 18 | import io.micronaut.gradle.Strings; 19 | 20 | import java.io.File; 21 | import java.util.List; 22 | 23 | public abstract class MicronautAotSampleConfTask extends AbstractMicronautAotCliTask { 24 | @Override 25 | protected void configureExtraArguments(List args) { 26 | args.add("--config"); 27 | File targetFile = getOutputDirectory().zip(getTargetRuntime(), (dir, runtime) -> dir.file(runtime.getSimpleName() + ".properties")).get().getAsFile(); 28 | targetFile.getParentFile().mkdirs(); 29 | args.add(targetFile.getAbsolutePath()); 30 | } 31 | 32 | @Override 33 | protected void onSuccess(File outputDir) { 34 | var sampleFile = new File(outputDir, getTargetRuntime().map(runtime -> runtime.getSimpleName() + ".properties").orElse("sample.properties").get()); 35 | if (sampleFile.exists()) { 36 | getLogger().lifecycle("Sample configuration file written to {}", Strings.clickableUrl(sampleFile)); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /aot-plugin/src/main/java/io/micronaut/gradle/aot/NettyOptimizations.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.aot; 17 | 18 | import org.gradle.api.provider.Property; 19 | import org.gradle.api.tasks.Input; 20 | import org.gradle.api.tasks.Optional; 21 | 22 | public interface NettyOptimizations { 23 | /** 24 | * Determines if Netty optimizations are enabled. 25 | * @return the enabled property 26 | */ 27 | @Input 28 | Property getEnabled(); 29 | 30 | /** 31 | * If Netty optimizations are optimized, you can set 32 | * this property to a fixed machine ID instead of Micronaut AOT 33 | * computing a random ID at runtime (not recommended). 34 | * If you set the value to "netty", then Netty will determine 35 | * the machine id at runtime, effectively disabling this optimization. 36 | * @return the machine ID 37 | */ 38 | @Input 39 | @Optional 40 | Property getMachineId(); 41 | 42 | /** 43 | * If Netty optimizations are optimized, you can set 44 | * this property to a fixed PID instead of Micronaut AOT 45 | * computing a random ID at runtime (not recommended). 46 | * If you set the value to "netty", then Netty will determine 47 | * the PID at runtime, effectively disabling this optimization. 48 | * @return the machine ID 49 | */ 50 | @Input 51 | @Optional 52 | Property getPid(); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /aot-plugin/src/main/java/io/micronaut/gradle/aot/OptimizerIO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.aot; 17 | 18 | import org.gradle.api.file.ConfigurableFileCollection; 19 | import org.gradle.api.file.DirectoryProperty; 20 | import org.gradle.api.provider.Property; 21 | import org.gradle.api.tasks.Classpath; 22 | import org.gradle.api.tasks.Input; 23 | import org.gradle.api.tasks.OutputDirectory; 24 | 25 | import java.util.Locale; 26 | 27 | public interface OptimizerIO { 28 | @Classpath 29 | ConfigurableFileCollection getClasspath(); 30 | 31 | @Input 32 | Property getTargetRuntime(); 33 | 34 | @Input 35 | Property getTargetPackage(); 36 | 37 | @OutputDirectory 38 | DirectoryProperty getOutputDirectory(); 39 | 40 | enum TargetRuntime { 41 | JIT, 42 | NATIVE; 43 | 44 | public String getSimpleName() { 45 | return name().toLowerCase(Locale.US); 46 | } 47 | 48 | public String getCapitalizedName() { 49 | return switch (this) { 50 | case JIT -> "Jit"; 51 | case NATIVE -> "Native"; 52 | }; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /aot-plugin/src/templates/java/io/micronaut/gradle/aot/Versions.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.aot; 2 | 3 | /** 4 | * Versions needed at runtime by the AOT plugin. 5 | */ 6 | abstract class Versions { 7 | static final String AOT_VERSION = "%MICRONAUT_AOT_VERSION%"; 8 | } 9 | -------------------------------------------------------------------------------- /aot-plugin/src/test/groovy/io/micronaut/gradle/aot/AotOptimizerConfigurationSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.aot 2 | 3 | import io.micronaut.gradle.MicronautComponentPlugin 4 | import org.gradle.api.plugins.JavaPlugin 5 | import org.gradle.testfixtures.ProjectBuilder 6 | import spock.lang.Specification 7 | 8 | class AotOptimizerConfigurationSpec extends Specification { 9 | def "can configure JVM arguments"() { 10 | def serr = System.err 11 | given: 12 | def baos = new ByteArrayOutputStream() 13 | System.err = new PrintStream(baos) 14 | def project = ProjectBuilder.builder() 15 | .build() 16 | 17 | String micronautVersion = System.getProperty("micronautVersion") 18 | project.extensions.add('micronautVersion', micronautVersion) 19 | project.pluginManager.apply(JavaPlugin) 20 | project.pluginManager.apply(MicronautComponentPlugin) 21 | project.pluginManager.apply(MicronautAotPlugin) 22 | project.repositories.mavenCentral() 23 | project.tasks.withType(AbstractMicronautAotCliTask).configureEach { 24 | jvmArgs.add('-XX:ThisDoesNotExist') 25 | } 26 | project.dependencies.add("aotApplicationClasspath", "io.micronaut.platform:micronaut-platform:$micronautVersion") 27 | 28 | when: 29 | def t = project.tasks.getByName("prepareJitOptimizations").execute() 30 | 31 | then: 32 | Exception ex = thrown() 33 | baos.toString().contains("Unrecognized VM option 'ThisDoesNotExist'") 34 | 35 | cleanup: 36 | System.err = serr 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | import org.gradle.util.GradleVersion 2 | 3 | /* 4 | * Copyright 2017-2021 original authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | plugins { 19 | id "io.micronaut.build.internal.dependency-updates" 20 | id "io.micronaut.internal.build.documented" 21 | id "io.micronaut.build.internal.quality-reporting" 22 | } 23 | 24 | repositories { 25 | mavenCentral() 26 | gradlePluginPortal() 27 | // maven { 28 | // url "https://s01.oss.sonatype.org/content/repositories/snapshots" 29 | // } 30 | } 31 | 32 | dependencies { 33 | javadoc gradleApi() 34 | javadoc project(":micronaut-minimal-plugin") 35 | javadoc project(":micronaut-docker-plugin") 36 | javadoc project(":micronaut-graalvm-plugin") 37 | javadoc project(":micronaut-aot-plugin") 38 | javadoc project(":micronaut-gradle-plugin") 39 | javadoc project(":micronaut-openapi-plugin") 40 | javadoc project(":micronaut-platform-catalog-plugin") 41 | javadoc project(":micronaut-jsonschema-plugin") 42 | javadoc libs.micronaut.openapi.generator 43 | javadoc libs.bundles.optionalPlugins 44 | javadoc libs.shadowPlugin 45 | javadoc libs.micronaut.jsonschema.generator 46 | } 47 | 48 | asciidoctorj { 49 | attributes 'native-build-tools-version': libs.versions.graalvmPlugin.get(), 50 | 'kotlin-version': libs.versions.kotlin.get(), 51 | 'micronaut-version': libs.versions.micronaut.platform.get(), 52 | 'gradle-version': GradleVersion.current().version, 53 | 'shadow-version': libs.versions.shadow.get() 54 | } 55 | -------------------------------------------------------------------------------- /buildSrc/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'groovy-gradle-plugin' 3 | } 4 | 5 | repositories { 6 | gradlePluginPortal() 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | implementation 'org.asciidoctor:asciidoctor-gradle-jvm:4.0.4' 12 | implementation 'com.gradle.publish:plugin-publish-plugin:1.3.1' 13 | implementation 'pl.droidsonroids.gradle.jacoco:pl.droidsonroids.gradle.jacoco:1.0.12' 14 | implementation 'io.micronaut.build.internal.quality-checks:io.micronaut.build.internal.quality-checks.gradle.plugin:7.4.0' 15 | } 16 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/io.micronaut.internal.build.processed-sources.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | def catalog = extensions.findByType(VersionCatalogsExtension).named('libs') 6 | 7 | def processSources = tasks.register("processJavaSources", io.micronaut.internal.build.sourcegen.SimpleSourceProcessor) { 8 | templates = file("src/templates/java") 9 | outputDirectory = layout.buildDirectory.dir("generated-sources/templates/java") 10 | catalog.versionAliases.each { alias -> 11 | replacements.put("%${alias.replace('.','_').toUpperCase()}_VERSION%", catalog.findVersion(alias).get().requiredVersion) 12 | } 13 | } 14 | 15 | sourceSets.main.java.srcDir(processSources) 16 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/io.micronaut.internal.build.testing.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'pl.droidsonroids.jacoco.testkit' 4 | id 'com.adarshr.test-logger' 5 | } 6 | 7 | dependencies { 8 | testImplementation libs.groovy.core 9 | testImplementation libs.spock.core 10 | testImplementation libs.spock.junit4 11 | } 12 | 13 | // We are NOT using the `jvm-test-suite` plugin because 14 | // it would generate different source sets for each test 15 | // suite, which is not what we want: we simply need different 16 | // test tasks, with different includes 17 | 18 | tasks.withType(Test).configureEach { 19 | dependsOn("generateJacocoTestKitProperties") 20 | useJUnitPlatform() 21 | def graalvmHome = providers.environmentVariable('GRAALVM_HOME') 22 | .orElse(providers.environmentVariable("JAVA_HOME")) 23 | .getOrElse("") 24 | inputs.property("GRAALVM_HOME", graalvmHome) 25 | environment "GRAALVM_HOME", graalvmHome 26 | systemProperty "micronautVersion", libs.versions.micronaut.platform.get() 27 | develocity.predictiveTestSelection { 28 | enabled = micronautBuild.environment.isTestSelectionEnabled() 29 | } 30 | maxParallelForks = Math.max(1, (int) (Runtime.runtime.availableProcessors()/2)) 31 | } 32 | 33 | testlogger { 34 | theme = 'standard-parallel' 35 | showFullStackTraces = true 36 | showStandardStreams = true 37 | showPassedStandardStreams = false 38 | showSkippedStandardStreams = false 39 | showFailedStandardStreams = true 40 | } 41 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/io/micronaut/internal/build/plugin/MicronautPluginExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.internal.build.plugin; 17 | 18 | import org.codehaus.groovy.runtime.StringGroovyMethods; 19 | import org.gradle.plugin.devel.GradlePluginDevelopmentExtension; 20 | 21 | import javax.inject.Inject; 22 | 23 | public abstract class MicronautPluginExtension { 24 | 25 | private final GradlePluginDevelopmentExtension gradlePlugin; 26 | 27 | @Inject 28 | public MicronautPluginExtension(GradlePluginDevelopmentExtension gradlePlugin) { 29 | this.gradlePlugin = gradlePlugin; 30 | } 31 | 32 | public void register(String alias, String pluginClass, String description) { 33 | String[] parts = alias.split("\\."); 34 | for (int i=1; i { 40 | decl.setId("io.micronaut." + alias); 41 | decl.setImplementationClass(pluginClass); 42 | decl.setDescription(description); 43 | decl.setDisplayName(description); 44 | decl.getTags().addAll("micronaut", "official"); 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/io/micronaut/internal/build/test/FunctionalTestingExtension.groovy: -------------------------------------------------------------------------------- 1 | 2 | package io.micronaut.internal.build.test 3 | 4 | import org.gradle.api.artifacts.ProjectDependency 5 | import org.gradle.api.artifacts.dsl.DependencyHandler 6 | import org.gradle.api.model.ObjectFactory 7 | import org.gradle.api.provider.SetProperty 8 | 9 | import javax.inject.Inject 10 | 11 | abstract class FunctionalTestingExtension { 12 | @Inject 13 | abstract DependencyHandler getDependencies() 14 | 15 | @Inject 16 | abstract ObjectFactory getObjects() 17 | 18 | abstract SetProperty getPlugins() 19 | 20 | void pluginUnderTest(String alias) { 21 | plugins.add(alias) 22 | dependencies.add("pluginsUnderTest", dependencies.create( 23 | dependencies.project(path: ":micronaut-${alias}-plugin", configuration: 'repository') 24 | )) 25 | 26 | ProjectDependency projectDependency = dependencies.project(path: ":micronaut-${alias}-plugin") 27 | dependencies.add("jacocoAdditionalClasses", dependencies.create(projectDependency)) 28 | dependencies.add("jacocoAdditionalSources", dependencies.create(projectDependency)) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /config/HEADER: -------------------------------------------------------------------------------- 1 | Copyright ${year} original authors 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | https://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /config/checkstyle/suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /config/spotless.license.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-$YEAR original authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ -------------------------------------------------------------------------------- /crac-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | } 4 | 5 | description = "Micronaut CRaC Gradle plugin" 6 | 7 | micronautPlugins { 8 | register('crac', 'io.micronaut.gradle.crac.MicronautCRaCPlugin', 'Micronaut CRaC Plugin') 9 | } 10 | 11 | dependencies { 12 | api projects.micronautMinimalPlugin 13 | api projects.micronautDockerPlugin 14 | 15 | testImplementation testFixtures(projects.micronautMinimalPlugin) 16 | } 17 | -------------------------------------------------------------------------------- /crac-plugin/src/main/java/io/micronaut/gradle/crac/TeeStringWriter.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.crac; 2 | 3 | import org.gradle.api.logging.Logger; 4 | 5 | import java.io.IOException; 6 | import java.io.StringWriter; 7 | import java.io.Writer; 8 | 9 | public class TeeStringWriter extends Writer { 10 | 11 | private final Logger logger; 12 | private final StringWriter delegate; 13 | 14 | public TeeStringWriter(Logger logger) { 15 | this.logger = logger; 16 | this.delegate = new StringWriter(); 17 | } 18 | 19 | @Override 20 | @SuppressWarnings("java:S2629") // This is done by Gradle 21 | public void write(char[] cbuf, int off, int len) { 22 | delegate.write(cbuf, off, len); 23 | logger.lifecycle(new String(cbuf, off, len).trim()); 24 | } 25 | 26 | @Override 27 | public void flush() { 28 | delegate.flush(); 29 | } 30 | 31 | @Override 32 | public void close() throws IOException { 33 | delegate.close(); 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return delegate.toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /crac-plugin/src/main/resources/checkpoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Bump pid to avoid pid conflicts when restoring 5 | echo 599 > /proc/sys/kernel/ns_last_pid 6 | 7 | # Set a trap to close the app once the script finishes 8 | trap 'echo "Killing $PROCESS" && kill -0 $PROCESS 2>/dev/null && kill $PROCESS' EXIT 9 | 10 | echo "Starting application" 11 | 12 | # Fix for WSL and OS X Docker Kernels 13 | GLIBC_TUNABLES=glibc.pthread.rseq=0 14 | 15 | # Run the app in the background 16 | /azul-crac-jdk/bin/java \ 17 | -XX:CRaCCheckpointTo=cr \ 18 | -XX:+UnlockDiagnosticVMOptions \ 19 | -XX:+CRTraceStartupTime \ 20 | -Djdk.crac.trace-startup-time=true \ 21 | -jar application.jar & 22 | PROCESS=$! 23 | echo "Started application as process $PROCESS" 24 | 25 | 26 | # Wait for the app to be started 27 | echo "Waiting 10s for application to start" 28 | retries=5 29 | until $(@READINESS@); do 30 | if [ $retries -le 0 ]; then 31 | echo "failed" 32 | exit 1 33 | fi 34 | echo -n '.' 35 | sleep 2 36 | retries=$((retries - 1)) 37 | done 38 | 39 | # Warm up the app. 40 | echo "Warming up application" 41 | ./warmup.sh 42 | 43 | # Take a snapshot 44 | echo "Sending checkpoint signal to process $PROCESS" 45 | /azul-crac-jdk/bin/jcmd $PROCESS JDK.checkpoint 46 | 47 | echo "Wait up to 60s for snapshot to be complete" 48 | retries=12 49 | while [ $retries -gt 0 ]; do 50 | kill -0 $PROCESS 2>/dev/null 51 | OK=$? 52 | if [ $OK -eq 1 ] ; then 53 | echo ".done" 54 | break 55 | fi 56 | echo -n "$OK." 57 | sleep 5 58 | retries=$((retries - 1)) 59 | done 60 | 61 | kill -0 $PROCESS 2>/dev/null 62 | OK=$? 63 | if [ $OK -eq 1 ]; then 64 | wait $PROCESS 65 | echo "EXITED WITH $?" 66 | echo "Snapshotting complete" 67 | # Make the snapshot files readable to the host 68 | chmod 666 cr/* 69 | else 70 | echo "Snapshotting failed" 71 | exit 1 72 | fi 73 | -------------------------------------------------------------------------------- /crac-plugin/src/main/resources/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -- \ 4 | "-XX:CRaCRestoreFrom=cr" \ 5 | "$@" 6 | eval "set -- $( 7 | printf '%s\n' "$JAVA_OPTS" | 8 | xargs -n1 | 9 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 10 | tr '\n' ' ' 11 | )" '"$@"' 12 | exec /azul-crac-jdk/bin/java "$@" 13 | -------------------------------------------------------------------------------- /crac-plugin/src/main/resources/warmup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Warm up the app. For now, just call curl, we may want a way for this to be configurable 4 | curl http://localhost:8080 5 | echo "" -------------------------------------------------------------------------------- /docker-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | } 4 | 5 | description = "Micronaut Docker Gradle plugin" 6 | 7 | micronautPlugins { 8 | register('docker', 'io.micronaut.gradle.docker.MicronautDockerPlugin', 'Micronaut Docker Plugin') 9 | } 10 | 11 | dependencies { 12 | api projects.micronautMinimalPlugin 13 | api libs.dockerPlug 14 | 15 | compileOnly libs.graalvmPlugin 16 | 17 | testImplementation testFixtures(projects.micronautMinimalPlugin) 18 | testImplementation libs.mockserver.netty 19 | } 20 | -------------------------------------------------------------------------------- /docker-plugin/src/main/java/io/micronaut/gradle/docker/DockerBuildOptions.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.docker; 2 | 3 | import io.micronaut.gradle.docker.editor.Editor; 4 | import org.gradle.api.Action; 5 | import org.gradle.api.provider.ListProperty; 6 | import org.gradle.api.provider.Property; 7 | import org.gradle.api.tasks.Input; 8 | import org.gradle.api.tasks.Internal; 9 | 10 | /** 11 | * Build options for Docker. 12 | * 13 | * @author gkrocher 14 | * @since 1.0.0 15 | */ 16 | public interface DockerBuildOptions { 17 | /** 18 | * @return The arguments to use 19 | */ 20 | @Input 21 | ListProperty getArgs(); 22 | 23 | /** 24 | * @return The base image to use 25 | */ 26 | @Input 27 | Property getBaseImage(); 28 | 29 | /** 30 | * @return The default command to use 31 | */ 32 | @Input 33 | Property getDefaultCommand(); 34 | 35 | /** 36 | * @return The exposed ports 37 | */ 38 | @Input 39 | ListProperty getExposedPorts(); 40 | 41 | @Internal 42 | ListProperty> getDockerfileTweaks(); 43 | 44 | /** 45 | * Arguments for the entrypoint. 46 | * @param args The arguments 47 | * @return This 48 | */ 49 | DockerBuildOptions args(String... args); 50 | 51 | /** 52 | * The base image to use. 53 | * @param imageName The base image name 54 | * @return This 55 | */ 56 | DockerBuildOptions baseImage(String imageName); 57 | 58 | /** 59 | * @param ports The ports to expose 60 | * @return The ports 61 | */ 62 | DockerBuildOptions exportPorts(Integer... ports); 63 | 64 | /** 65 | * The working directory to use in the container. 66 | * Defaults to /home/app 67 | * @return the target directory 68 | */ 69 | Property getTargetWorkingDirectory(); 70 | 71 | /** 72 | * Adds a dockerfile tweak. 73 | * @param action the edition action 74 | */ 75 | default void editDockerfile(Action action) { 76 | getDockerfileTweaks().add(action); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /docker-plugin/src/main/java/io/micronaut/gradle/docker/DockerExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.docker; 17 | 18 | import org.gradle.api.provider.Property; 19 | 20 | public interface DockerExtension { 21 | Property getUseCopyLink(); 22 | } 23 | -------------------------------------------------------------------------------- /docker-plugin/src/main/java/io/micronaut/gradle/docker/model/DefaultMicronautDockerImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.docker.model; 17 | 18 | import org.gradle.api.Action; 19 | import org.gradle.api.model.ObjectFactory; 20 | import org.gradle.api.tasks.Internal; 21 | 22 | import javax.inject.Inject; 23 | 24 | public abstract class DefaultMicronautDockerImage implements MicronautDockerImage { 25 | 26 | private final String name; 27 | 28 | @Inject 29 | public DefaultMicronautDockerImage(String name) { 30 | this.name = name; 31 | } 32 | 33 | @Override 34 | @Internal 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | @Inject 40 | protected abstract ObjectFactory getObjects(); 41 | 42 | @Override 43 | public void addLayer(Action spec) { 44 | Layer layer = getObjects().newInstance(Layer.class); 45 | layer.getRuntimeKind().convention(RuntimeKind.ANY); 46 | spec.execute(layer); 47 | getLayers().add(layer); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docker-plugin/src/main/java/io/micronaut/gradle/docker/model/Layer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.docker.model; 17 | 18 | import org.gradle.api.file.ConfigurableFileCollection; 19 | import org.gradle.api.provider.Property; 20 | import org.gradle.api.tasks.Classpath; 21 | import org.gradle.api.tasks.Input; 22 | 23 | public interface Layer { 24 | @Input 25 | Property getLayerKind(); 26 | 27 | @Input 28 | Property getRuntimeKind(); 29 | 30 | @Classpath 31 | ConfigurableFileCollection getFiles(); 32 | } 33 | -------------------------------------------------------------------------------- /docker-plugin/src/main/java/io/micronaut/gradle/docker/model/LayerKind.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.docker.model; 17 | 18 | public enum LayerKind { 19 | PROJECT_LIBS("project_libs", "libs"), 20 | SNAPSHOT_LIBS("snapshot_libs", "libs"), 21 | LIBS("libs", "libs"), 22 | APP("app", ""), 23 | EXPANDED_RESOURCES("resources", "resources"); 24 | 25 | private final String sourceDirName; 26 | private final String targetDirName; 27 | 28 | LayerKind(String sourceDirName, String targetDirName) { 29 | this.sourceDirName = sourceDirName; 30 | this.targetDirName = targetDirName; 31 | } 32 | 33 | public String targetDirName() { 34 | return targetDirName; 35 | } 36 | 37 | public String sourceDirName() { 38 | return sourceDirName; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /docker-plugin/src/main/java/io/micronaut/gradle/docker/model/MicronautDockerImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.docker.model; 17 | 18 | import org.gradle.api.Action; 19 | import org.gradle.api.Named; 20 | import org.gradle.api.provider.ListProperty; 21 | 22 | import java.util.List; 23 | 24 | /** 25 | * Represents a Micronaut docker image, represented 26 | * with a name and a list of layers. 27 | * Tasks will be automatically created based on the declared 28 | * images. 29 | */ 30 | public interface MicronautDockerImage extends Named { 31 | ListProperty getLayers(); 32 | 33 | void addLayer(Action spec); 34 | 35 | default List findLayers(RuntimeKind runtimeKind) { 36 | return getLayers().map(layers -> layers.stream() 37 | .filter(layer -> layer.getRuntimeKind().get().isCompatibleWith(runtimeKind)) 38 | .toList()) 39 | .get(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docker-plugin/src/main/java/io/micronaut/gradle/docker/model/RuntimeKind.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.docker.model; 17 | 18 | /** 19 | * The kind of runtime a layer targets. 20 | */ 21 | public enum RuntimeKind { 22 | JIT, 23 | NATIVE, 24 | ANY; 25 | 26 | boolean isCompatibleWith(RuntimeKind target) { 27 | if (target == ANY || this == ANY) { 28 | return true; 29 | } 30 | return target == this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docker-plugin/src/main/java/io/micronaut/gradle/docker/tasks/DockerResourceConfigDirectoryNamer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.docker.tasks; 17 | 18 | import java.io.File; 19 | import java.nio.file.Path; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | public class DockerResourceConfigDirectoryNamer { 24 | private final Map counter = new HashMap<>(); 25 | 26 | public String determineNameFor(File configDir) { 27 | String name = configDir.getName(); 28 | File currentDir = configDir; 29 | for (int i = 0; i < 3; i++) { 30 | if (currentDir != null) { 31 | currentDir = currentDir.getParentFile(); 32 | } 33 | } 34 | if (currentDir != null && "exploded".equals(currentDir.getName())) { 35 | // This directory likely comes from the GraalVM metadata repository plugin 36 | Path fullPath = configDir.toPath(); 37 | Path relativePath = currentDir.toPath().relativize(fullPath); 38 | name = relativePath.toString(); 39 | } 40 | Integer count = counter.computeIfAbsent(name, k -> 0); 41 | if (count == 0) { 42 | return name; 43 | } else { 44 | count++; 45 | counter.put(name, count); 46 | return name + "/" + count; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docker-plugin/src/test/resources/dummy-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | dummy 6 | dummy 7 | 5.0.0-SNAPSHOT 8 | Micronaut Dummy 9 | Dummy 10 | https://micronaut.io 11 | 12 | 13 | The Apache Software License, Version 2.0 14 | http://www.apache.org/licenses/LICENSE-2.0.txt 15 | repo 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docker-plugin/src/test/resources/test-maven-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | dummy 4 | dummy 5 | 6 | xxxxxxxxtttttt 7 | 8 | xxxxxxxx.tttttt 9 | 1 10 | 11 | 12 | 5.0.0-SNAPSHOT 13 | 14 | -------------------------------------------------------------------------------- /functional-tests/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | plugins { 3 | id 'io.micronaut.internal.build.functional-testing' 4 | } 5 | 6 | description = """ 7 | This project contains functional tests for combinations of plugins 8 | """ 9 | 10 | repositories { 11 | mavenCentral() 12 | } 13 | 14 | functionalTesting { 15 | pluginUnderTest('platform-catalog') 16 | pluginUnderTest('minimal') 17 | pluginUnderTest('graalvm') 18 | pluginUnderTest('docker') 19 | pluginUnderTest('aot') 20 | pluginUnderTest('gradle') 21 | pluginUnderTest('openapi') 22 | pluginUnderTest('test-resources') 23 | } 24 | 25 | dependencies { 26 | testImplementation gradleTestKit() 27 | testImplementation testFixtures(projects.micronautMinimalPlugin) 28 | } 29 | -------------------------------------------------------------------------------- /functional-tests/src/test/groovy/io/micronaut/gradle/aot/ShadowMicronautAOTSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.aot 2 | 3 | class ShadowMicronautAOTSpec extends AbstractAOTPluginSpec { 4 | 5 | def "builds a fatjar optimized flavor"() { 6 | Process process 7 | withSample("aot/with-shadow") 8 | 9 | when: 10 | def result = build("optimizedJitJarAll") 11 | 12 | then: 13 | def fatJar = file("build/libs/basic-app-0.1-all-optimized.jar") 14 | fatJar.exists() 15 | 16 | when: 17 | def builder = new ProcessBuilder(new File(javaExecutable).canonicalPath, 18 | '-Dio.micronaut.internal.test.interrupt.startup=true', 19 | "-jar", fatJar.absolutePath) 20 | def runnerOutput = file("runner.txt") 21 | builder.redirectError(runnerOutput) 22 | builder.redirectOutput(runnerOutput) 23 | 24 | process = builder.start() 25 | Thread.startDaemon("process monitor") { 26 | // Sanity interruption if process doesn't stop as expected 27 | Thread.sleep(10000) 28 | process?.destroy() 29 | } 30 | def exitCode = process.waitFor() 31 | 32 | then: 33 | def outputText = runnerOutput.text 34 | println(outputText) 35 | exitCode == 0 36 | [ 37 | 'io.micronaut.core.reflect.ClassUtils$Optimizations', 38 | 'io.micronaut.core.util.EnvironmentProperties', 39 | 'io.micronaut.core.async.publisher.PublishersOptimizations', 40 | 'io.micronaut.core.io.service.SoftServiceLoader$Optimizations', 41 | 'io.micronaut.context.env.ConstantPropertySources' 42 | ].each { 43 | assert outputText.contains("Setting optimizations for class $it") 44 | } 45 | 46 | } 47 | 48 | static String getJavaExecutable() { 49 | String exec = System.getProperty("java.home") + "/bin/java".replace((char) '/', (char) File.separatorChar) 50 | if (System.getProperty("os.name").toLowerCase().contains("windows")) { 51 | exec += ".exe" 52 | } 53 | exec 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /functional-tests/src/test/groovy/io/micronaut/gradle/fixtures/AbstractEagerConfiguringFunctionalTest.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.fixtures 2 | 3 | import org.gradle.testkit.runner.BuildResult 4 | 5 | class AbstractEagerConfiguringFunctionalTest extends AbstractFunctionalTest { 6 | @Override 7 | BuildResult build(String... args) { 8 | return super.build("tasks", *args) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /functional-tests/src/test/groovy/io/micronaut/gradle/fixtures/AbstractFunctionalTest.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.fixtures 2 | 3 | import io.micronaut.gradle.AbstractGradleBuildSpec 4 | import org.gradle.testkit.runner.GradleRunner 5 | 6 | abstract class AbstractFunctionalTest extends AbstractGradleBuildSpec { 7 | @Override 8 | protected GradleRunner newRunner() { 9 | GradleRunner.create() 10 | } 11 | 12 | def setup() { 13 | patchSettings() 14 | } 15 | 16 | protected void patchSettings() { 17 | String version = System.getProperty('project.version') 18 | settingsFile.text = """ 19 | pluginManagement { 20 | repositories { 21 | ${guardString('mavenLocal()', allowMavenLocal)} 22 | mavenCentral() 23 | maven { 24 | url = "${System.getProperty("internal.plugin.repo")}" 25 | } 26 | ${guardString('maven { url = "https://s01.oss.sonatype.org/content/repositories/snapshots" }', allowSnapshots)} 27 | gradlePluginPortal() 28 | } 29 | plugins { 30 | id 'io.micronaut.platform.catalog' version '${version}' 31 | id 'io.micronaut.minimal.library' version '${version}' 32 | id 'io.micronaut.minimal.application' version '${version}' 33 | id 'io.micronaut.library' version '${version}' 34 | id 'io.micronaut.application' version '${version}' 35 | id 'io.micronaut.graalvm' version '${version}' 36 | id 'io.micronaut.docker' version '${version}' 37 | id 'io.micronaut.aot' version '${version}' 38 | id 'io.micronaut.openapi' version '${version}' 39 | id 'io.micronaut.test-resources' version '${version}' 40 | } 41 | } 42 | """ + (settingsFile.exists() ? settingsFile.text : "") 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /functional-tests/src/test/groovy/io/micronaut/gradle/openapi/AbstractOpenApiWithKotlinSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.openapi 2 | 3 | import io.micronaut.gradle.fixtures.AbstractEagerConfiguringFunctionalTest 4 | import spock.lang.Shared 5 | 6 | class AbstractOpenApiWithKotlinSpec extends AbstractEagerConfiguringFunctionalTest { 7 | @Shared 8 | protected final String kotlinVersion = System.getProperty("kotlinVersion") 9 | 10 | @Shared 11 | protected final String kspVersion = System.getProperty("kspVersion") 12 | 13 | protected void withPetstore() { 14 | file("petstore.json").text = this.class.getResourceAsStream("/petstore.json").getText("UTF-8") 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /functional-tests/src/test/groovy/io/micronaut/gradle/testresources/AbstractTestResourcesSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.testresources 2 | 3 | import io.micronaut.gradle.fixtures.AbstractEagerConfiguringFunctionalTest 4 | 5 | abstract class AbstractTestResourcesSpec extends AbstractEagerConfiguringFunctionalTest { 6 | 7 | @Override 8 | protected void withSample(String name) { 9 | super.withSample(name) 10 | patchSettings() 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /functional-tests/src/test/groovy/io/micronaut/gradle/testresources/TestResourcesWithAotAndGraalVMSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.testresources 2 | 3 | import io.micronaut.gradle.AbstractGradleBuildSpec 4 | import org.gradle.testkit.runner.TaskOutcome 5 | import spock.lang.Requires 6 | 7 | @Requires({ AbstractGradleBuildSpec.graalVmAvailable && !os.windows }) 8 | class TestResourcesWithAotAndGraalVMSpec extends AbstractTestResourcesSpec { 9 | 10 | def "runs optimized binary"() { 11 | withSample("test-resources/data-mysql") 12 | buildFile.text = buildFile.text.replace("""plugins { 13 | id("io.micronaut.minimal.application") 14 | id("io.micronaut.test-resources") 15 | }""", """plugins { 16 | id("io.micronaut.minimal.application") 17 | id("io.micronaut.test-resources") 18 | id("io.micronaut.aot") 19 | id("io.micronaut.graalvm") 20 | } 21 | 22 | graalvmNative.binaries.all { 23 | runtimeArgs.add("-DinterruptStartup=true") 24 | } 25 | 26 | micronaut { 27 | aot { 28 | deduceEnvironment = true 29 | optimizeServiceLoading = true 30 | } 31 | } 32 | """) 33 | 34 | when: 35 | def result = build 'nativeOptimizedRun', "-Dtestresources.native" 36 | 37 | then: 38 | result.task(':nativeOptimizedRun').outcome == TaskOutcome.SUCCESS 39 | result.output.contains "Loaded 2 test resources resolvers" 40 | result.output.contains "io.micronaut.testresources.mysql.MySQLTestResourceProvider" 41 | result.output.contains "io.micronaut.testresources.testcontainers.GenericTestContainerProvider" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /graalvm-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | } 4 | 5 | description = "Micronaut AOT Gradle plugin" 6 | 7 | micronautPlugins { 8 | register('graalvm', 'io.micronaut.gradle.graalvm.MicronautGraalPlugin', 'Micronaut GraalVM Plugin') 9 | } 10 | 11 | dependencies { 12 | api projects.micronautMinimalPlugin 13 | api libs.graalvmPlugin 14 | testImplementation testFixtures(projects.micronautMinimalPlugin) 15 | } 16 | -------------------------------------------------------------------------------- /graalvm-plugin/src/main/java/io/micronaut/gradle/graalvm/GraalUtil.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.graalvm; 2 | 3 | import java.util.Locale; 4 | 5 | /** 6 | * Utilities for GraalVM. 7 | */ 8 | public final class GraalUtil { 9 | 10 | private GraalUtil() { 11 | } 12 | 13 | /** 14 | * @return Return whether the JVM in use a GraalVM JVM. 15 | */ 16 | public static boolean isGraalJVM() { 17 | return isGraal("jvmci.Compiler", "java.vendor.version", "java.vendor"); 18 | } 19 | 20 | private static boolean isGraal(String... props) { 21 | for (String prop : props) { 22 | String vv = System.getProperty(prop); 23 | if (vv != null && vv.toLowerCase(Locale.ENGLISH).contains("graal")) { 24 | return true; 25 | } 26 | } 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /graalvm-plugin/src/test/groovy/io/micronaut/gradle/MicronautGraalWellBehavePluginSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle 2 | 3 | import org.gradle.testfixtures.ProjectBuilder 4 | import spock.lang.Specification 5 | 6 | class MicronautGraalWellBehavePluginSpec extends Specification { 7 | def "graal processor is added with plugin #plugin"() { 8 | def project = ProjectBuilder.builder().build() 9 | 10 | when: 11 | project.plugins.apply("io.micronaut.graalvm") 12 | project.plugins.apply (plugin) 13 | 14 | then: 15 | project.configurations.annotationProcessor.dependencies.find { it.name == 'micronaut-graal' } 16 | 17 | where: 18 | plugin << [ 19 | "io.micronaut.minimal.library", 20 | "io.micronaut.minimal.application", 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gradle-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | } 4 | 5 | description = "The main Micronaut Gradle plugin" 6 | 7 | micronautPlugins { 8 | register('library', 'io.micronaut.gradle.MicronautLibraryPlugin', 'Micronaut Library Plugin') 9 | register('application', 'io.micronaut.gradle.MicronautApplicationPlugin', 'Micronaut Application Plugin') 10 | } 11 | 12 | dependencies { 13 | constraints { 14 | implementation(libs.log4j2.core) { 15 | because("Log4j2 <2.15 is vulnerable to RCE (CVE-2021-44228)") 16 | } 17 | } 18 | api projects.micronautMinimalPlugin 19 | api projects.micronautDockerPlugin 20 | api projects.micronautGraalvmPlugin 21 | api projects.micronautAotPlugin 22 | api projects.micronautTestResourcesPlugin 23 | 24 | implementation libs.diffplugPlugin 25 | 26 | compileOnly libs.bundles.optionalPlugins 27 | 28 | testImplementation testFixtures(projects.micronautMinimalPlugin) 29 | } 30 | -------------------------------------------------------------------------------- /gradle-plugin/src/main/java/io/micronaut/gradle/MicronautApplicationPlugin.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle; 2 | 3 | import com.diffplug.gradle.eclipse.apt.AptEclipsePlugin; 4 | import io.micronaut.gradle.docker.MicronautDockerPlugin; 5 | import io.micronaut.gradle.graalvm.MicronautGraalPlugin; 6 | import org.gradle.api.Project; 7 | import org.gradle.api.plugins.PluginManager; 8 | 9 | /** 10 | * A plugin for a Micronaut application. Applies the "application" plugin. 11 | * 12 | * @author graemerocher 13 | * @since 1.0.0 14 | */ 15 | public class MicronautApplicationPlugin extends MicronautLibraryPlugin { 16 | 17 | @Override 18 | public void apply(Project project) { 19 | PluginManager pluginManager = project.getPluginManager(); 20 | pluginManager.apply(MicronautMinimalApplicationPlugin.class); 21 | pluginManager.apply(AptEclipsePlugin.class); 22 | pluginManager.apply(MicronautDockerPlugin.class); 23 | pluginManager.apply(MicronautGraalPlugin.class); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /gradle-plugin/src/main/java/io/micronaut/gradle/MicronautLibraryPlugin.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle; 2 | 3 | import com.diffplug.gradle.eclipse.apt.AptEclipsePlugin; 4 | import io.micronaut.gradle.graalvm.MicronautGraalPlugin; 5 | import org.gradle.api.Plugin; 6 | import org.gradle.api.Project; 7 | import org.gradle.api.plugins.PluginContainer; 8 | 9 | /** 10 | * A plugin for creating a Micronaut library. Applies the java-library plugin by default. 11 | * 12 | * @author graemerocher 13 | * @since 1.0.0 14 | */ 15 | public class MicronautLibraryPlugin implements Plugin { 16 | 17 | @Override 18 | public void apply(Project project) { 19 | final PluginContainer plugins = project.getPlugins(); 20 | 21 | plugins.apply(MicronautMinimalLibraryPlugin.class); 22 | plugins.apply(AptEclipsePlugin.class); 23 | plugins.apply(MicronautGraalPlugin.class); 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | projectVersion=4.5.4-SNAPSHOT 2 | projectGroup=io.micronaut.gradle 3 | 4 | title=Micronaut Gradle plugin 5 | projectDesc=Gradle plugin for integrating of Micronaut applications 6 | projectUrl=https://micronaut.io 7 | githubBranch=master 8 | githubSlug=micronaut-projects/micronaut-gradle-plugin 9 | 10 | org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 11 | org.gradle.configuration-cache=false 12 | org.gradle.configuration-cache.parallel=false 13 | org.gradle.caching=true 14 | org.gradle.parallel=true 15 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micronaut-projects/micronaut-gradle-plugin/e94e7eb2069adc7cf28fcf0d42120045d5a08642/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /jsonschema-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | } 4 | 5 | description = "Micronaut JSON Schema Gradle plugin" 6 | 7 | micronautPlugins { 8 | register('jsonschema', 'io.micronaut.gradle.jsonschema.MicronautJSONSchemaPlugin', 'Micronaut JSON Schema Plugin') 9 | } 10 | 11 | dependencies { 12 | compileOnly libs.micronaut.jsonschema.generator 13 | implementation projects.micronautMinimalPlugin 14 | testImplementation testFixtures(projects.micronautMinimalPlugin) 15 | testImplementation libs.mockserver.netty 16 | } -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/JSONSchemaExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.jsonschema; 17 | 18 | import org.gradle.api.Action; 19 | import org.gradle.api.provider.Property; 20 | 21 | import java.io.File; 22 | 23 | /** 24 | * Configures the JSON Schema code generator. 25 | */ 26 | public interface JSONSchemaExtension { 27 | /** 28 | * The version of the Micronaut JSON Schema generator. 29 | * @return the version 30 | */ 31 | Property getVersion(); 32 | 33 | /** 34 | * Configures generation, given a schema URL. 35 | * @param url the url string of a json schema 36 | * @param spec configuration for the server generation 37 | */ 38 | void fromUrl(String url, Action spec); 39 | 40 | /** 41 | * Configures generation, given a schema file. 42 | * @param file the json file 43 | * @param spec configuration for the server generation 44 | */ 45 | void fromFile(File file, Action spec); 46 | } 47 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/JsonSchemaFileSpec.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.jsonschema; 2 | 3 | import org.gradle.api.provider.Property; 4 | 5 | import java.io.File; 6 | 7 | public interface JsonSchemaFileSpec extends JsonSchemaSpec { 8 | Property getInputFile(); 9 | } 10 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/JsonSchemaSpec.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.jsonschema; 2 | 3 | import org.gradle.api.file.DirectoryProperty; 4 | import org.gradle.api.provider.ListProperty; 5 | import org.gradle.api.provider.Property; 6 | 7 | public interface JsonSchemaSpec { 8 | Property getLang(); 9 | 10 | ListProperty getAcceptedUrlPatterns(); 11 | 12 | Property getOutputFileName(); 13 | 14 | Property getOutputPackageName(); 15 | 16 | DirectoryProperty getOutputDirectory(); 17 | } 18 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/JsonSchemaURLSpec.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.jsonschema; 2 | 3 | import org.gradle.api.provider.Property; 4 | 5 | public interface JsonSchemaURLSpec extends JsonSchemaSpec { 6 | Property getInputUrl(); 7 | } 8 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/tasks/JsonSchemaFileGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.jsonschema.tasks; 17 | 18 | import org.gradle.api.file.RegularFileProperty; 19 | import org.gradle.api.tasks.InputFile; 20 | import org.gradle.api.tasks.PathSensitive; 21 | import org.gradle.api.tasks.PathSensitivity; 22 | 23 | public abstract class JsonSchemaFileGenerator extends AbstractJsonSchemaGenerator { 24 | 25 | @InputFile 26 | @PathSensitive(PathSensitivity.NONE) 27 | public abstract RegularFileProperty getInputFile(); 28 | 29 | @Override 30 | protected Class getWorkerAction() { 31 | return JsonSchemaFileWorkAction.class; 32 | } 33 | 34 | @Override 35 | protected void configureWorkerParameters(JsonSchemaFileWorkAction.FileParameters params) { 36 | params.getInputFile().set(getInputFile()); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/tasks/JsonSchemaFileWorkAction.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.jsonschema.tasks; 2 | 3 | import org.gradle.api.file.RegularFileProperty; 4 | 5 | import io.micronaut.jsonschema.generator.utils.SourceGeneratorConfigBuilder; 6 | 7 | public abstract class JsonSchemaFileWorkAction extends AbstractJsonSchemaWorkAction { 8 | protected interface FileParameters extends JsonSchemaParameters { 9 | RegularFileProperty getInputFile(); 10 | } 11 | 12 | @Override 13 | protected void configureBuilder(SourceGeneratorConfigBuilder builder) { 14 | var parameters = getParameters(); 15 | builder.withJsonFile(parameters.getInputFile().get().getAsFile()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/tasks/JsonSchemaFolderGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.jsonschema.tasks; 17 | 18 | import org.gradle.api.file.DirectoryProperty; 19 | import org.gradle.api.tasks.InputDirectory; 20 | 21 | public abstract class JsonSchemaFolderGenerator extends AbstractJsonSchemaGenerator { 22 | 23 | @InputDirectory 24 | public abstract DirectoryProperty getInputDirectory(); 25 | 26 | @Override 27 | protected Class getWorkerAction() { 28 | return JsonSchemaFolderWorkAction.class; 29 | } 30 | 31 | @Override 32 | protected void configureWorkerParameters(JsonSchemaFolderWorkAction.FolderParameters params) { 33 | params.getInputDirectory().set(getInputDirectory()); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/tasks/JsonSchemaFolderWorkAction.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.jsonschema.tasks; 2 | 3 | import org.gradle.api.file.DirectoryProperty; 4 | 5 | import io.micronaut.jsonschema.generator.utils.SourceGeneratorConfigBuilder; 6 | 7 | public abstract class JsonSchemaFolderWorkAction extends AbstractJsonSchemaWorkAction { 8 | protected interface FolderParameters extends JsonSchemaParameters { 9 | DirectoryProperty getInputDirectory(); 10 | } 11 | 12 | @Override 13 | protected void configureBuilder(SourceGeneratorConfigBuilder builder) { 14 | var parameters = getParameters(); 15 | builder.withInputFolder(parameters.getInputDirectory().get().getAsFile().toPath()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/tasks/JsonSchemaUrlGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.jsonschema.tasks; 17 | 18 | import org.gradle.api.provider.Property; 19 | import org.gradle.api.tasks.Input; 20 | 21 | public abstract class JsonSchemaUrlGenerator extends AbstractJsonSchemaGenerator { 22 | 23 | @Input 24 | public abstract Property getJsonURL(); 25 | 26 | @Override 27 | protected Class getWorkerAction() { 28 | return JsonSchemaUrlWorkAction.class; 29 | } 30 | 31 | @Override 32 | protected void configureWorkerParameters(JsonSchemaUrlWorkAction.UrlParameters params) { 33 | params.getJsonURL().set(getJsonURL()); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/main/java/io/micronaut/gradle/jsonschema/tasks/JsonSchemaUrlWorkAction.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.jsonschema.tasks; 2 | 3 | import org.gradle.api.provider.Property; 4 | 5 | import io.micronaut.jsonschema.generator.utils.SourceGeneratorConfigBuilder; 6 | 7 | public abstract class JsonSchemaUrlWorkAction extends AbstractJsonSchemaWorkAction { 8 | protected interface UrlParameters extends AbstractJsonSchemaWorkAction.JsonSchemaParameters { 9 | Property getJsonURL(); 10 | } 11 | 12 | @Override 13 | protected void configureBuilder(SourceGeneratorConfigBuilder builder) { 14 | var parameters = getParameters(); 15 | builder.withJsonUrl(parameters.getJsonURL().get()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jsonschema-plugin/src/test/resources/refFolder/ref/head.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://example.com/schemas/head.schema.json", 4 | "title": "Head", 5 | "description": "A top level schema.", 6 | "type": [ 7 | "object" 8 | ], 9 | "properties": { 10 | "cheatsheet": { 11 | "description": "Unique id for the animal.", 12 | "$ref": "types/cheatsheet.schema.json#/Cheatsheet" 13 | }, 14 | "CV": { 15 | "description": "The birthdate", 16 | "$ref": "https://raw.githubusercontent.com/hexagonkt/codecv/master/cv.schema.json#/$defs/Cv" 17 | }, 18 | "name": { 19 | "description": "The name", 20 | "type": "string", 21 | "minLength": 1 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /minimal-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | import io.micronaut.internal.build.sourcegen.WriteVersions 2 | 3 | plugins { 4 | id "io.micronaut.internal.build.gradle-plugin" 5 | id "java-test-fixtures" 6 | } 7 | 8 | description = "The main Micronaut Gradle plugin" 9 | 10 | micronautPlugins { 11 | register('component', 'io.micronaut.gradle.MicronautComponentPlugin', 'Micronaut Component Plugin') 12 | register('minimal.library', 'io.micronaut.gradle.MicronautMinimalLibraryPlugin', 'Micronaut Minimal Library Plugin') 13 | register('minimal.application', 'io.micronaut.gradle.MicronautMinimalApplicationPlugin', 'Micronaut Minimal Application Plugin') 14 | } 15 | 16 | dependencies { 17 | compileOnly libs.bundles.optionalPlugins 18 | compileOnly libs.shadowPlugin 19 | 20 | testFixturesImplementation gradleTestKit() 21 | testFixturesImplementation libs.groovy.core 22 | testFixturesImplementation libs.spock.core 23 | testFixturesImplementation libs.spock.junit4 24 | } 25 | 26 | var writeVersions = tasks.register("writeDefaultVersions", WriteVersions) { 27 | outputDirectory = layout.buildDirectory.dir("generated/default-versions") 28 | versions.put('test-resources', libs.versions.micronaut.testresources) 29 | versions.put('openapi', libs.versions.micronaut.openapi) 30 | versions.put('oraclelinux', libs.versions.oraclelinux) 31 | versions.put('amazonlinux', libs.versions.amazonlinux) 32 | versions.put('jsonschema', libs.versions.micronaut.jsonschema) 33 | packageName = 'io.micronaut.gradle' 34 | } 35 | 36 | sourceSets.main.java.srcDir(writeVersions) 37 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/AnnotationProcessingConfigBuilder.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle; 2 | 3 | import org.gradle.api.tasks.SourceSet; 4 | 5 | /** 6 | * Allows configuration of annotation processing. 7 | */ 8 | public interface AnnotationProcessingConfigBuilder { 9 | /** 10 | * Whether incremental processing is enabled. 11 | * @param incremental True if incremental processing is enabled 12 | * @return This builder 13 | */ 14 | AnnotationProcessingConfigBuilder incremental(boolean incremental); 15 | 16 | /** 17 | * The module name to use. Default to the gradle project name. 18 | * @param name The module name 19 | * @return This builder 20 | */ 21 | AnnotationProcessingConfigBuilder module(String name); 22 | 23 | /** 24 | * The group name being used. Defaults to the gradle group name. 25 | * @param name The group name 26 | * @return This builder 27 | */ 28 | AnnotationProcessingConfigBuilder group(String name); 29 | 30 | /** 31 | * The annotation patterns to include in processing. 32 | * @param annotations The annotation patterns 33 | * @return This builder 34 | */ 35 | AnnotationProcessingConfigBuilder annotations(String...annotations); 36 | 37 | /** 38 | * Additional source sets to apply processing to. 39 | * @param sourceSets The source sets 40 | * @return This builder 41 | */ 42 | AnnotationProcessingConfigBuilder sourceSets(SourceSet... sourceSets); 43 | } 44 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/AttributeUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle; 17 | 18 | import org.gradle.api.artifacts.Configuration; 19 | import org.gradle.api.attributes.Attribute; 20 | import org.gradle.api.attributes.AttributeContainer; 21 | import org.gradle.api.provider.ProviderFactory; 22 | 23 | import java.util.Set; 24 | 25 | /** 26 | * Utilities to deal with Gradle configuration attributes. 27 | */ 28 | public abstract class AttributeUtils { 29 | private AttributeUtils() { 30 | 31 | } 32 | 33 | /** 34 | * Copies attributes from a source configuration to a target configuration 35 | * @param from the source configuration 36 | * @param to the target configuration 37 | */ 38 | public static void copyAttributes(ProviderFactory providers, Configuration from, Configuration to) { 39 | from.attributes(attrs -> { 40 | AttributeContainer runtimeClasspathAttributes = to.getAttributes(); 41 | Set> keySet = runtimeClasspathAttributes.keySet(); 42 | for (Attribute attribute : keySet) { 43 | // noinspection unchecked 44 | attrs.attributeProvider((Attribute) attribute, providers.provider(() -> runtimeClasspathAttributes.getAttribute(attribute))); 45 | } 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/MicronautBasePlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle; 17 | 18 | import org.gradle.api.Plugin; 19 | import org.gradle.api.Project; 20 | 21 | import static io.micronaut.gradle.MicronautComponentPlugin.MICRONAUT_BOMS_CONFIGURATION; 22 | 23 | public class MicronautBasePlugin implements Plugin { 24 | @Override 25 | public void apply(Project project) { 26 | var registry = new SourceSetConfigurerRegistry(); 27 | project.getExtensions().add("micronautSourceSetConfigurer", registry); 28 | project.getExtensions().create("micronaut", MicronautExtension.class, registry); 29 | project.getConfigurations().create(MICRONAUT_BOMS_CONFIGURATION, conf -> { 30 | conf.setCanBeResolved(false); 31 | conf.setCanBeConsumed(false); 32 | conf.setDescription("BOMs which will be applied by the Micronaut plugins"); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/MicronautMinimalLibraryPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle; 17 | 18 | import org.gradle.api.Plugin; 19 | import org.gradle.api.Project; 20 | import org.gradle.api.plugins.JavaLibraryPlugin; 21 | import org.gradle.api.plugins.PluginManager; 22 | 23 | /** 24 | * A plugin to build a Micronaut library. It is the base plugin for all Micronaut libraries, 25 | * and applies the _minimal_ amount of plugins to make it work. 26 | */ 27 | public class MicronautMinimalLibraryPlugin implements Plugin { 28 | @Override 29 | public void apply(Project project) { 30 | PluginManager plugins = project.getPluginManager(); 31 | plugins.apply(JavaLibraryPlugin.class); 32 | plugins.apply(MicronautComponentPlugin.class); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/MicronautRuntime.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle; 2 | 3 | import io.micronaut.gradle.docker.DockerBuildStrategy; 4 | 5 | /** 6 | * The packaging kind of the application. 7 | * 8 | * @author graemerocher 9 | * @since 1.0 10 | */ 11 | public enum MicronautRuntime { 12 | /** 13 | * No specific runtime specified. 14 | */ 15 | NONE(), 16 | /** 17 | * Default packaging. 18 | */ 19 | NETTY, 20 | /** 21 | * Tomcat server. 22 | */ 23 | TOMCAT, 24 | /** 25 | * Jetty server. 26 | */ 27 | JETTY, 28 | /** 29 | * Undertow server. 30 | */ 31 | UNDERTOW, 32 | 33 | /** 34 | * AWS lambda packaged as a Jar file and deploy to a Java runtime. 35 | */ 36 | LAMBDA_JAVA, 37 | 38 | /** 39 | * AWS lambda deployed to a Provided runtime. 40 | */ 41 | LAMBDA_PROVIDED(DockerBuildStrategy.LAMBDA), 42 | 43 | /** 44 | * Oracle Cloud Function, packaged as a docker container. 45 | */ 46 | ORACLE_FUNCTION(DockerBuildStrategy.ORACLE_FUNCTION), 47 | /** 48 | * Google Cloud Function, packaged as a Fat JAR. 49 | */ 50 | GOOGLE_FUNCTION, 51 | /** 52 | * Azure Cloud Function. 53 | */ 54 | AZURE_FUNCTION, 55 | /** 56 | * Plain old Java application based on Apache libraries. 57 | */ 58 | HTTP_POJA; 59 | 60 | private final DockerBuildStrategy buildStrategy; 61 | 62 | MicronautRuntime() { 63 | this.buildStrategy = DockerBuildStrategy.DEFAULT; 64 | } 65 | 66 | MicronautRuntime(DockerBuildStrategy buildStrategy) { 67 | this.buildStrategy = buildStrategy; 68 | } 69 | 70 | /** 71 | * @return The docker build strategy 72 | */ 73 | public DockerBuildStrategy getBuildStrategy() { 74 | return buildStrategy; 75 | } 76 | 77 | public boolean isLambda() { 78 | return this == LAMBDA_JAVA || isLambdaProvided(); 79 | } 80 | public boolean isLambdaProvided() { 81 | return this == LAMBDA_PROVIDED; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/SourceSetConfigurer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle; 17 | 18 | import org.gradle.api.tasks.SourceSet; 19 | 20 | public interface SourceSetConfigurer { 21 | void onSourceSet(SourceSet sourceSet); 22 | } 23 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/SourceSetConfigurerRegistry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle; 17 | 18 | import org.gradle.api.tasks.SourceSet; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | public class SourceSetConfigurerRegistry implements SourceSetConfigurer { 24 | private final List configurers = new ArrayList<>(); 25 | 26 | public void register(SourceSetConfigurer configurer) { 27 | configurers.add(configurer); 28 | } 29 | 30 | 31 | @Override 32 | public void onSourceSet(SourceSet sourceSet) { 33 | for (SourceSetConfigurer configurer : configurers) { 34 | configurer.onSourceSet(sourceSet); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/Strings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle; 17 | 18 | import java.io.File; 19 | import java.net.URI; 20 | import java.net.URISyntaxException; 21 | 22 | import static java.util.Locale.ENGLISH; 23 | 24 | public abstract class Strings { 25 | 26 | private Strings() { 27 | } 28 | 29 | public static String capitalize(String name) { 30 | if (name == null || name.isEmpty()) { 31 | return name; 32 | } 33 | return name.substring(0, 1).toUpperCase(ENGLISH) + name.substring(1); 34 | } 35 | 36 | public static String clickableUrl(File file) { 37 | try { 38 | return new URI("file", "", file.toURI().getPath(), null, null).toString(); 39 | } catch (URISyntaxException e) { 40 | return file.toString(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/docker/DockerBuildStrategy.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.docker; 2 | 3 | /** 4 | * Different strategies for building docker images. 5 | * 6 | * @author graemerocher 7 | * @since 1.0.0 8 | * 9 | */ 10 | public enum DockerBuildStrategy { 11 | /** 12 | * An oracle function 13 | */ 14 | ORACLE_FUNCTION, 15 | /** 16 | * An AWS Lambda 17 | */ 18 | LAMBDA, 19 | /** 20 | * Default docker build strategy 21 | */ 22 | DEFAULT 23 | } 24 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/graalvm/GraalUtil.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.graalvm; 2 | 3 | import java.util.Locale; 4 | 5 | /** 6 | * Utilities for GraalVM. 7 | */ 8 | public final class GraalUtil { 9 | 10 | private GraalUtil() { 11 | } 12 | 13 | /** 14 | * @return Return whether the JVM in use a GraalVM JVM. 15 | */ 16 | public static boolean isGraalJVM() { 17 | return isGraal("jvmci.Compiler", "java.vendor.version", "java.vendor"); 18 | } 19 | 20 | private static boolean isGraal(String... props) { 21 | for (String prop : props) { 22 | String vv = System.getProperty(prop); 23 | if (vv != null && vv.toLowerCase(Locale.ENGLISH).contains("graal")) { 24 | return true; 25 | } 26 | } 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/graalvm/NativeLambdaExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.graalvm; 17 | 18 | import org.gradle.api.provider.Property; 19 | 20 | /** 21 | * Allows configuring the native lambda specific parameters. 22 | */ 23 | public interface NativeLambdaExtension { 24 | /** 25 | * The native lambda runtime 26 | * @return the runtime 27 | */ 28 | Property getLambdaRuntime(); 29 | 30 | /** 31 | * The native lambda runtime main class. Defaults to the 32 | * {@link #getLambdaRuntime lambda runtime main class}. 33 | * @return the main class name 34 | */ 35 | Property getLambdaRuntimeClassName(); 36 | } 37 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/graalvm/NativeLambdaRuntime.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.graalvm; 17 | 18 | public enum NativeLambdaRuntime { 19 | API_GATEWAY_V1("io.micronaut.function.aws.runtime.MicronautLambdaRuntime"), 20 | API_GATEWAY_V2("io.micronaut.function.aws.runtime.APIGatewayV2HTTPEventMicronautLambdaRuntime"), 21 | ALB("io.micronaut.function.aws.runtime.ApplicationLoadBalancerMicronautLambdaRuntime"); 22 | 23 | private final String mainClassName; 24 | 25 | NativeLambdaRuntime(String mainClassName) { 26 | 27 | this.mainClassName = mainClassName; 28 | } 29 | 30 | public String getMainClassName() { 31 | return mainClassName; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /minimal-plugin/src/main/java/io/micronaut/gradle/internal/ConfigurableVersionProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.internal; 17 | 18 | import org.codehaus.groovy.runtime.StringGroovyMethods; 19 | 20 | /** 21 | * A configurable version property is a property which is found 22 | * in the DSL, as a type-safe accessor, allowing to override a 23 | * particular version of a dependency which is automatically 24 | * added by the Gradle plugin. 25 | * 26 | * @param name the simple name of the property 27 | * @param dslName the name in the DSL 28 | * @param gradlePropertyName the name of the gradle property 29 | */ 30 | public record ConfigurableVersionProperty( 31 | String name, 32 | String dslName, 33 | String gradlePropertyName, 34 | String platformCatalogName 35 | ) { 36 | public static ConfigurableVersionProperty of(String name) { 37 | return new ConfigurableVersionProperty( 38 | name, 39 | name + "Version", 40 | "micronaut" + StringGroovyMethods.capitalize(name) + "Version", 41 | "micronaut." + name 42 | ); 43 | } 44 | 45 | public ConfigurableVersionProperty withPlatformCatalogName(String platformCatalogName) { 46 | return new ConfigurableVersionProperty(name, dslName, gradlePropertyName, platformCatalogName); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /openapi-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | } 4 | 5 | description = "Micronaut OpenAPI Gradle plugin" 6 | 7 | micronautPlugins { 8 | register('openapi', 'io.micronaut.gradle.openapi.MicronautOpenAPIPlugin', 'Micronaut OpenAPI Plugin') 9 | } 10 | 11 | dependencies { 12 | compileOnly libs.micronaut.openapi.generator 13 | implementation projects.micronautMinimalPlugin 14 | testImplementation testFixtures(projects.micronautMinimalPlugin) 15 | } 16 | -------------------------------------------------------------------------------- /openapi-plugin/src/main/java/io/micronaut/gradle/openapi/OpenApiClientSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.openapi; 17 | 18 | import org.gradle.api.provider.ListProperty; 19 | import org.gradle.api.provider.Property; 20 | 21 | public interface OpenApiClientSpec extends OpenApiSpec { 22 | 23 | Property getClientId(); 24 | 25 | Property getClientPath(); 26 | 27 | Property getUseAuth(); 28 | 29 | Property getAuthorizationFilterPattern(); 30 | 31 | Property getBasePathSeparator(); 32 | 33 | ListProperty getAdditionalClientTypeAnnotations(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /openapi-plugin/src/main/java/io/micronaut/gradle/openapi/OpenApiServerSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.openapi; 17 | 18 | import org.gradle.api.provider.Property; 19 | 20 | public interface OpenApiServerSpec extends OpenApiSpec { 21 | 22 | Property getControllerPackage(); 23 | 24 | Property getUseAuth(); 25 | 26 | Property getAot(); 27 | } 28 | -------------------------------------------------------------------------------- /openapi-plugin/src/main/java/io/micronaut/gradle/openapi/tasks/OpenApiServerGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.openapi.tasks; 17 | 18 | import org.gradle.api.provider.Property; 19 | import org.gradle.api.tasks.CacheableTask; 20 | import org.gradle.api.tasks.Input; 21 | import org.gradle.api.tasks.Optional; 22 | 23 | @CacheableTask 24 | public abstract class OpenApiServerGenerator extends AbstractOpenApiGenerator { 25 | 26 | @Input 27 | public abstract Property getControllerPackage(); 28 | 29 | @Input 30 | public abstract Property getUseAuth(); 31 | 32 | @Optional 33 | @Input 34 | public abstract Property getAot(); 35 | 36 | @Override 37 | protected Class getWorkerAction() { 38 | return OpenApiServerWorkAction.class; 39 | } 40 | 41 | @Override 42 | protected void configureWorkerParameters(OpenApiServerWorkAction.ServerParameters params) { 43 | params.getControllerPackage().set(getControllerPackage()); 44 | params.getUseAuth().set(getUseAuth()); 45 | params.getAot().set(getAot()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /openapi-plugin/src/test/groovy/io/micronaut/openapi/gradle/AbstractOpenApiGeneratorSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.openapi.gradle 2 | 3 | import io.micronaut.gradle.AbstractGradleBuildSpec 4 | 5 | class AbstractOpenApiGeneratorSpec extends AbstractGradleBuildSpec { 6 | 7 | protected void withPetstore() { 8 | file("petstore.json").text = this.class.getResourceAsStream("/petstore.json").getText("UTF-8") 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /platform-catalog-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | } 4 | 5 | description = """Micronaut Platform Catalog Gradle plugin 6 | 7 | A plugin which will automatically make the Micronaut Platform version catalog 8 | available to your build scripts. 9 | """ 10 | 11 | micronautPlugins { 12 | register('platform.catalog', 'io.micronaut.gradle.catalog.MicronautCatalogSettingsPlugin', 'Micronaut Platform Catalog Plugin') 13 | } 14 | 15 | dependencies { 16 | implementation(libs.tomlj) 17 | testImplementation testFixtures(projects.micronautMinimalPlugin) 18 | } 19 | -------------------------------------------------------------------------------- /platform-catalog-plugin/src/main/java/io/micronaut/gradle/catalog/Library.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.catalog; 17 | 18 | import org.tomlj.TomlPosition; 19 | 20 | public record Library( 21 | String alias, 22 | String group, 23 | String name, 24 | VersionModel version, 25 | TomlPosition position 26 | ) { 27 | 28 | public String getModule() { 29 | return group + ":" + name; 30 | } 31 | 32 | @Override 33 | public boolean equals(Object o) { 34 | if (this == o) { 35 | return true; 36 | } 37 | if (o == null || getClass() != o.getClass()) { 38 | return false; 39 | } 40 | 41 | Library library = (Library) o; 42 | 43 | if (!group.equals(library.group)) { 44 | return false; 45 | } 46 | if (!name.equals(library.name)) { 47 | return false; 48 | } 49 | return version.equals(library.version); 50 | } 51 | 52 | @Override 53 | public int hashCode() { 54 | int result = group.hashCode(); 55 | result = 31 * result + name.hashCode(); 56 | result = 31 * result + (version != null ? version.hashCode() : 0); 57 | return result; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /platform-catalog-plugin/src/main/java/io/micronaut/gradle/catalog/RichVersionParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.catalog; 17 | 18 | import org.gradle.api.InvalidUserCodeException; 19 | 20 | import javax.annotation.Nullable; 21 | 22 | public class RichVersionParser { 23 | 24 | public RichVersion parse(@Nullable String version) { 25 | if (version == null) { 26 | return RichVersion.EMPTY; 27 | } 28 | int idx = version.indexOf("!!"); 29 | if (idx == 0) { 30 | throw new InvalidUserCodeException("The strict version modifier (!!) must be appended to a valid version number"); 31 | } 32 | if (idx > 0) { 33 | String strictly = version.substring(0, idx); 34 | String prefer = version.substring(idx+2); 35 | return new RichVersion(null, strictly, prefer, null, false); 36 | } 37 | return new RichVersion(version, null, null, null, false); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /platform-catalog-plugin/src/main/java/io/micronaut/gradle/catalog/VersionModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.catalog; 17 | 18 | import org.tomlj.TomlPosition; 19 | 20 | import javax.annotation.Nullable; 21 | import java.util.Objects; 22 | 23 | public record VersionModel( 24 | @Nullable 25 | String reference, 26 | @Nullable 27 | RichVersion version, 28 | TomlPosition position 29 | ) { 30 | 31 | @Override 32 | public boolean equals(Object o) { 33 | if (this == o) { 34 | return true; 35 | } 36 | if (o == null || getClass() != o.getClass()) { 37 | return false; 38 | } 39 | 40 | VersionModel that = (VersionModel) o; 41 | 42 | if (!Objects.equals(reference, that.reference)) { 43 | return false; 44 | } 45 | return Objects.equals(version, that.version); 46 | } 47 | 48 | @Override 49 | public int hashCode() { 50 | int result = reference != null ? reference.hashCode() : 0; 51 | result = 31 * result + (version != null ? version.hashCode() : 0); 52 | return result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/aot/app-startup-fixture/src/main/java/io/micronaut/aot/fixture/ApplicationStartupInterruption.java: -------------------------------------------------------------------------------- 1 | package io.micronaut.aot.fixture; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | 7 | import java.util.Map; 8 | import java.lang.reflect.Field; 9 | 10 | /** 11 | * A context configurer for tests which is simply aimed at shutting down 12 | * the application under test. 13 | */ 14 | @ContextConfigurer 15 | public class ApplicationStartupInterruption implements ApplicationContextConfigurer { 16 | @Override 17 | public int getOrder() { 18 | return LOWEST_PRECEDENCE; 19 | } 20 | 21 | public @Override 22 | void configure(ApplicationContextBuilder builder) { 23 | if (System.getProperty("io.micronaut.internal.test.interrupt.startup") != null) { 24 | System.out.println("Detected test, interrupting application startup"); 25 | try { 26 | Class clazz = Class.forName("io.micronaut.core.optim.StaticOptimizations"); 27 | Field field = clazz.getDeclaredField("OPTIMIZATIONS"); 28 | field.setAccessible(true); 29 | Map, Object> optimizations = (Map, Object>) field.get(null); 30 | optimizations.keySet().forEach(c -> System.out.println("Setting optimizations for " + c)); 31 | } catch (Exception ex) { 32 | // ignore 33 | } 34 | System.exit(0); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/aot/aws-function/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.library") 3 | id("io.micronaut.aot") 4 | id("com.gradleup.shadow") version "8.3.6" 5 | } 6 | 7 | version = "0.1" 8 | group = "example.micronaut" 9 | 10 | micronaut { 11 | runtime("lambda_provided") 12 | testRuntime("junit5") 13 | processing { 14 | incremental(true) 15 | annotations("example.micronaut.*") 16 | } 17 | aot { 18 | cacheEnvironment.set(true) 19 | optimizeServiceLoading.set(true) 20 | optimizeClassLoading.set(true) 21 | convertYamlToJava.set(true) 22 | precomputeOperations.set(true) 23 | } 24 | } 25 | 26 | dependencies { 27 | implementation("io.micronaut:micronaut-runtime") 28 | implementation("javax.annotation:javax.annotation-api") 29 | runtimeOnly("ch.qos.logback:logback-classic") 30 | implementation("io.micronaut.validation:micronaut-validation") 31 | 32 | implementation("io.micronaut.aws:micronaut-function-aws") 33 | runtimeOnly("org.yaml:snakeyaml") 34 | 35 | testImplementation("io.micronaut:micronaut-http-client") 36 | 37 | } 38 | 39 | 40 | java { 41 | sourceCompatibility = JavaVersion.toVersion("17") 42 | targetCompatibility = JavaVersion.toVersion("17") 43 | } 44 | 45 | tasks.named("assemble") { 46 | dependsOn(":shadowJar") 47 | } 48 | 49 | graalvmNative.binaries.all { verbose = true } 50 | -------------------------------------------------------------------------------- /samples/aot/aws-function/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=xxx 2 | -------------------------------------------------------------------------------- /samples/aot/aws-function/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'aws-function' 2 | -------------------------------------------------------------------------------- /samples/aot/aws-function/src/main/java/example/micronaut/Book.java: -------------------------------------------------------------------------------- 1 | package example.micronaut; 2 | import io.micronaut.core.annotation.NonNull; 3 | import io.micronaut.core.annotation.Introspected; 4 | import jakarta.validation.constraints.NotBlank; 5 | 6 | @Introspected 7 | public class Book { 8 | 9 | @NonNull 10 | @NotBlank 11 | private String name; 12 | 13 | public Book() { 14 | } 15 | 16 | @NonNull 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(@NonNull String name) { 22 | this.name = name; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/aot/aws-function/src/main/java/example/micronaut/BookRequestHandler.java: -------------------------------------------------------------------------------- 1 | package example.micronaut; 2 | import io.micronaut.core.annotation.Introspected; 3 | import io.micronaut.function.aws.MicronautRequestHandler; 4 | import java.util.UUID; 5 | 6 | @Introspected 7 | public class BookRequestHandler extends MicronautRequestHandler { 8 | 9 | @Override 10 | public BookSaved execute(Book input) { 11 | BookSaved bookSaved = new BookSaved(); 12 | bookSaved.setName(input.getName()); 13 | bookSaved.setIsbn(UUID.randomUUID().toString()); 14 | return bookSaved; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/aot/aws-function/src/main/java/example/micronaut/BookSaved.java: -------------------------------------------------------------------------------- 1 | package example.micronaut; 2 | import io.micronaut.core.annotation.NonNull; 3 | import io.micronaut.core.annotation.Introspected; 4 | 5 | import jakarta.validation.constraints.NotBlank; 6 | 7 | @Introspected 8 | public class BookSaved { 9 | 10 | @NonNull 11 | @NotBlank 12 | private String name; 13 | 14 | @NonNull 15 | @NotBlank 16 | private String isbn; 17 | 18 | public BookSaved() { 19 | 20 | } 21 | 22 | @NonNull 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(@NonNull String name) { 28 | this.name = name; 29 | } 30 | 31 | @NonNull 32 | public String getIsbn() { 33 | return isbn; 34 | } 35 | 36 | public void setIsbn(@NonNull String isbn) { 37 | this.isbn = isbn; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/aot/aws-function/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: micronautguide 4 | -------------------------------------------------------------------------------- /samples/aot/aws-function/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/aot/aws-function/src/test/java/example/micronaut/BookRequestHandlerTest.java: -------------------------------------------------------------------------------- 1 | package example.micronaut; 2 | import static org.junit.jupiter.api.Assertions.assertNotNull; 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.BeforeAll; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class BookRequestHandlerTest { 9 | 10 | private static BookRequestHandler bookRequestHandler; 11 | 12 | @BeforeAll 13 | public static void setupServer() { 14 | bookRequestHandler = new BookRequestHandler(); 15 | } 16 | 17 | @AfterAll 18 | public static void stopServer() { 19 | if (bookRequestHandler != null) { 20 | bookRequestHandler.getApplicationContext().close(); 21 | } 22 | } 23 | 24 | @Test 25 | public void testHandler() { 26 | Book book = new Book(); 27 | book.setName("Building Microservices"); 28 | BookSaved bookSaved = bookRequestHandler.execute(book); 29 | assertEquals(bookSaved.getName(),book.getName()); 30 | assertNotNull(bookSaved.getIsbn()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /samples/aot/basic-app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.application") 3 | id("io.micronaut.aot") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo.app" 8 | 9 | micronaut { 10 | runtime("netty") 11 | testRuntime("junit5") 12 | processing { 13 | incremental(true) 14 | annotations("demo.app.*") 15 | } 16 | aot { 17 | cacheEnvironment = true 18 | optimizeServiceLoading = true 19 | optimizeClassLoading = true 20 | convertYamlToJava = true 21 | precomputeOperations = true 22 | deduceEnvironment = true 23 | optimizeNetty = true 24 | replaceLogbackXml = true 25 | } 26 | } 27 | 28 | tasks.withType(Test).configureEach { 29 | useJUnitPlatform() 30 | } 31 | 32 | tasks.named("test", Test) { 33 | inputs.files(file("samples")) 34 | } 35 | 36 | dependencies { 37 | annotationProcessor("io.micronaut:micronaut-http-validation") 38 | implementation("io.micronaut:micronaut-http-client") 39 | implementation("jakarta.annotation:jakarta.annotation-api") 40 | runtimeOnly("ch.qos.logback:logback-classic") 41 | implementation("io.micronaut.validation:micronaut-validation") 42 | runtimeOnly("io.micronaut.serde:micronaut-serde-jackson") 43 | runtimeOnly("org.yaml:snakeyaml") 44 | } 45 | 46 | 47 | application { 48 | mainClass.set("demo.app.Application") 49 | } 50 | 51 | java { 52 | sourceCompatibility = JavaVersion.toVersion("17") 53 | targetCompatibility = JavaVersion.toVersion("17") 54 | } 55 | -------------------------------------------------------------------------------- /samples/aot/basic-app/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=xxx 2 | -------------------------------------------------------------------------------- /samples/aot/basic-app/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'basic-app' 2 | -------------------------------------------------------------------------------- /samples/aot/basic-app/src/main/java/demo/app/Application.java: -------------------------------------------------------------------------------- 1 | package demo.app; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | import io.micronaut.runtime.Micronaut; 7 | 8 | @ContextConfigurer 9 | public class Application implements ApplicationContextConfigurer { 10 | @Override 11 | public void configure(ApplicationContextBuilder builder) { 12 | System.out.println("Java configurer loaded"); 13 | builder.deduceEnvironment(false); 14 | } 15 | 16 | public static void main(String[] args) { 17 | Micronaut.run(Application.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/aot/basic-app/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/aot/with-shadow/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.aot") 4 | id("com.gradleup.shadow") version("8.3.6") 5 | } 6 | 7 | version = "0.1" 8 | group = "demo.app" 9 | 10 | micronaut { 11 | runtime("netty") 12 | testRuntime("junit5") 13 | processing { 14 | incremental(true) 15 | annotations("demo.app.*") 16 | } 17 | aot { 18 | cacheEnvironment = true 19 | optimizeServiceLoading = true 20 | optimizeClassLoading = true 21 | convertYamlToJava = true 22 | precomputeOperations = true 23 | deduceEnvironment = true 24 | } 25 | } 26 | 27 | tasks.withType(Test).configureEach { 28 | useJUnitPlatform() 29 | } 30 | 31 | tasks.named("test", Test) { 32 | inputs.files(file("samples")) 33 | } 34 | 35 | dependencies { 36 | annotationProcessor("io.micronaut:micronaut-http-validation") 37 | implementation("io.micronaut:micronaut-http-client") 38 | implementation("io.micronaut:micronaut-runtime") 39 | implementation("javax.annotation:javax.annotation-api") 40 | implementation("io.micronaut.validation:micronaut-validation") 41 | runtimeOnly("ch.qos.logback:logback-classic") 42 | runtimeOnly("org.yaml:snakeyaml") 43 | } 44 | 45 | 46 | application { 47 | mainClass.set("demo.app.Application") 48 | } 49 | 50 | java { 51 | sourceCompatibility = JavaVersion.toVersion("17") 52 | targetCompatibility = JavaVersion.toVersion("17") 53 | } 54 | -------------------------------------------------------------------------------- /samples/aot/with-shadow/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=xxx 2 | -------------------------------------------------------------------------------- /samples/aot/with-shadow/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'basic-app' 2 | -------------------------------------------------------------------------------- /samples/aot/with-shadow/src/main/java/demo/app/Application.java: -------------------------------------------------------------------------------- 1 | package demo.app; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | import io.micronaut.runtime.Micronaut; 7 | 8 | @ContextConfigurer 9 | public class Application implements ApplicationContextConfigurer { 10 | @Override 11 | public void configure(ApplicationContextBuilder builder) { 12 | System.out.println("Java configurer loaded"); 13 | builder.deduceEnvironment(false); 14 | } 15 | 16 | public static void main(String[] args) { 17 | Micronaut.run(Application.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.test-resources") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo" 8 | 9 | dependencies { 10 | annotationProcessor("io.micronaut:micronaut-http-validation") 11 | implementation("io.micronaut:micronaut-http-client") 12 | implementation("io.micronaut:micronaut-jackson-databind") 13 | implementation("io.micronaut:micronaut-runtime") 14 | implementation("jakarta.annotation:jakarta.annotation-api") 15 | implementation("io.micronaut.validation:micronaut-validation") 16 | runtimeOnly("ch.qos.logback:logback-classic") 17 | runtimeOnly("io.micronaut:micronaut-jackson-databind") 18 | runtimeOnly("org.yaml:snakeyaml") 19 | testResourcesImplementation("org.apache.commons:commons-lang3:3.17.0") 20 | } 21 | 22 | application { 23 | mainClass.set("demo.Application") 24 | } 25 | 26 | micronaut { 27 | runtime("netty") 28 | testRuntime("junit5") 29 | processing { 30 | incremental(true) 31 | annotations("demo.*") 32 | } 33 | testResources { 34 | // TEST_RESOURCES_MARKER 35 | } 36 | } 37 | 38 | dependencies { 39 | // TEST_DEPENDENCIES_MARKER 40 | } 41 | 42 | tasks.named("run") { 43 | if (System.getProperty("interruptStartup")) { 44 | systemProperty "interruptStartup", "true" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=3.5.1 2 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name="demo" 2 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | import io.micronaut.context.event.StartupEvent; 7 | import io.micronaut.context.annotation.Value; 8 | import io.micronaut.runtime.Micronaut; 9 | import io.micronaut.runtime.event.annotation.EventListener; 10 | import jakarta.inject.Inject; 11 | import jakarta.inject.Singleton; 12 | 13 | import java.util.Collections; 14 | 15 | @Singleton 16 | public class Application { 17 | 18 | private final String greeting; 19 | 20 | public Application(@Value("${greeting.message}") String greeting) { 21 | this.greeting = greeting; 22 | } 23 | 24 | @ContextConfigurer 25 | public static class Configurer implements ApplicationContextConfigurer { 26 | @Override 27 | public void configure(ApplicationContextBuilder builder) { 28 | builder.deduceEnvironment(false); 29 | builder.banner(false); 30 | } 31 | } 32 | 33 | public static void main(String[] args) { 34 | Micronaut.run(Application.class, args); 35 | if (System.getProperty("interruptStartup") != null) { 36 | System.exit(0); 37 | } 38 | } 39 | 40 | @EventListener 41 | public void onStart(StartupEvent event) { 42 | System.out.println(greeting); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: demo 4 | server: 5 | port: -1 6 | netty: 7 | default: 8 | allocator: 9 | max-order: 3 10 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/src/test/java/demo/DemoTest.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 4 | import jakarta.inject.Inject; 5 | import org.junit.jupiter.api.Test; 6 | import io.micronaut.context.annotation.Value; 7 | 8 | import java.util.List; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | import static org.junit.jupiter.api.Assertions.assertNotNull; 12 | 13 | // tag::test[] 14 | @MicronautTest 15 | class DemoTest { 16 | 17 | @Value("${greeting.message}") 18 | String greeting; 19 | 20 | @Test 21 | void testItWorks() { 22 | assertEquals("Hello from my test resource!", greeting); 23 | } 24 | 25 | } 26 | // end::test[] 27 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/src/testResources/java/demo/GreetingTestResource.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.testresources.core.TestResourcesResolver; 4 | 5 | import java.util.Collection; 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Optional; 10 | 11 | import org.apache.commons.lang3.StringUtils; 12 | 13 | public class GreetingTestResource implements TestResourcesResolver { 14 | 15 | public static final String PROPERTY = "greeting.message"; 16 | 17 | @Override 18 | public List getResolvableProperties(Map> propertyEntries, Map testResourcesConfig) { 19 | return Collections.singletonList(PROPERTY); 20 | } 21 | 22 | @Override 23 | public Optional resolve(String propertyName, Map properties, Map testResourcesConfiguration) { 24 | if (PROPERTY.equals(propertyName)) { 25 | return Optional.of(StringUtils.capitalize("hello from my test resource!")); 26 | } 27 | return Optional.empty(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /samples/test-resources/custom-test-resource/src/testResources/resources/META-INF/services/io.micronaut.testresources.core.TestResourcesResolver: -------------------------------------------------------------------------------- 1 | demo.GreetingTestResource 2 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.test-resources") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo" 8 | 9 | dependencies { 10 | annotationProcessor("io.micronaut:micronaut-http-validation") 11 | implementation("io.micronaut:micronaut-http-client") 12 | implementation("io.micronaut:micronaut-jackson-databind") 13 | implementation("io.micronaut:micronaut-runtime") 14 | implementation("jakarta.annotation:jakarta.annotation-api") 15 | implementation("io.micronaut.validation:micronaut-validation") 16 | runtimeOnly("ch.qos.logback:logback-classic") 17 | runtimeOnly("org.yaml:snakeyaml") 18 | } 19 | 20 | application { 21 | mainClass.set("demo.Application") 22 | } 23 | 24 | micronaut { 25 | runtime("netty") 26 | testRuntime("junit5") 27 | processing { 28 | incremental(true) 29 | annotations("demo.*") 30 | } 31 | testResources { 32 | // TEST_RESOURCES_MARKER 33 | } 34 | } 35 | 36 | dependencies { 37 | annotationProcessor("io.micronaut.data:micronaut-data-processor") 38 | implementation("io.micronaut.data:micronaut-data-jdbc") 39 | implementation("io.micronaut.sql:micronaut-jdbc-hikari") 40 | runtimeOnly("mysql:mysql-connector-java") 41 | runtimeOnly("io.micronaut:micronaut-jackson-databind") 42 | // TEST_DEPENDENCIES_MARKER 43 | } 44 | 45 | tasks.withType(JavaExec).configureEach { 46 | if (System.getProperty("interruptStartup")) { 47 | systemProperty "interruptStartup", "true" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=3.5.1 2 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name="demo" 2 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | import io.micronaut.context.event.StartupEvent; 7 | import io.micronaut.runtime.Micronaut; 8 | import io.micronaut.runtime.event.annotation.EventListener; 9 | import jakarta.inject.Inject; 10 | import jakarta.inject.Singleton; 11 | 12 | import java.util.Collections; 13 | 14 | @Singleton 15 | public class Application { 16 | 17 | @Inject 18 | private UserRepository userRepository; 19 | 20 | @Inject 21 | private BookRepository bookRepository; 22 | 23 | @ContextConfigurer 24 | public static class Configurer implements ApplicationContextConfigurer { 25 | @Override 26 | public void configure(ApplicationContextBuilder builder) { 27 | builder.deduceEnvironment(false); 28 | builder.banner(true); 29 | } 30 | } 31 | 32 | public static void main(String[] args) { 33 | Micronaut.run(Application.class, args); 34 | if (System.getProperty("interruptStartup") != null) { 35 | System.exit(0); 36 | } 37 | } 38 | 39 | @EventListener 40 | public void onStart(StartupEvent event) { 41 | if (userRepository.count() == 0) { 42 | User admin = new User(); 43 | admin.setName("Administrator"); 44 | userRepository.save(admin); 45 | } 46 | if (bookRepository.count() == 0) { 47 | Book book = new Book(); 48 | book.setTitle("The Hitchhiker's Guide to the Galaxy"); 49 | bookRepository.save(book); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/java/demo/Book.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class Book { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | 28 | private String title; 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public void setId(Long id) { 35 | this.id = id; 36 | } 37 | 38 | public String getTitle() { 39 | return title; 40 | } 41 | 42 | public void setTitle(String title) { 43 | this.title = title; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/java/demo/BookController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import jakarta.transaction.Transactional; 22 | import java.util.List; 23 | 24 | @Controller("/") 25 | @Transactional 26 | public class BookController { 27 | private final BookRepository bookRepository; 28 | 29 | public BookController(BookRepository bookRepository) { 30 | this.bookRepository = bookRepository; 31 | } 32 | 33 | @Get("/books") 34 | public List list() { 35 | return bookRepository.findAll(); 36 | } 37 | 38 | @Get("/books/add/{title}") 39 | public Book add(String title) { 40 | Book book = new Book(); 41 | book.setTitle(title); 42 | return bookRepository.save(book); 43 | } 44 | 45 | @Get("/books/{id}") 46 | public Book get(Long id) { 47 | return bookRepository.findById(id).orElse(null); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/java/demo/BookRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.Repository; 19 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 20 | import io.micronaut.data.model.query.builder.sql.Dialect; 21 | import io.micronaut.data.repository.CrudRepository; 22 | 23 | import java.util.List; 24 | 25 | @Repository("default") 26 | @JdbcRepository(dialect = Dialect.MYSQL) 27 | public interface BookRepository extends CrudRepository { 28 | @Override 29 | List findAll(); 30 | } 31 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/java/demo/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class User { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | private String name; 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public Long getId() { 38 | return id; 39 | } 40 | 41 | public void setId(Long id) { 42 | this.id = id; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/java/demo/UserController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import java.util.List; 22 | 23 | @Controller("/users") 24 | public class UserController { 25 | 26 | private final UserRepository userRepository; 27 | 28 | public UserController(UserRepository userRepository) { 29 | this.userRepository = userRepository; 30 | } 31 | 32 | @Get("/") 33 | public List list() { 34 | return userRepository.findAll(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/java/demo/UserRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 19 | import io.micronaut.data.model.query.builder.sql.Dialect; 20 | import io.micronaut.data.repository.CrudRepository; 21 | 22 | import java.util.List; 23 | 24 | //@Repository("users") 25 | @JdbcRepository(dialect = Dialect.MYSQL) 26 | public interface UserRepository extends CrudRepository { 27 | @Override 28 | List findAll(); 29 | } 30 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: demo 4 | server: 5 | port: -1 6 | netty: 7 | default: 8 | allocator: 9 | max-order: 3 10 | datasources: 11 | default: 12 | driverClassName: com.mysql.cj.jdbc.Driver 13 | schema-generate: CREATE 14 | dialect: MYSQL 15 | # users: 16 | # driverClassName: org.postgresql.Driver 17 | # schema-generate: CREATE_DROP 18 | # dialect: POSTGRES 19 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/test-resources/data-mysql/src/test/java/demo/DemoTest.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 4 | import jakarta.inject.Inject; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertNotNull; 11 | 12 | @MicronautTest 13 | class DemoTest { 14 | 15 | @Inject 16 | BookRepository bookRepository; 17 | 18 | @Test 19 | void testItWorks() { 20 | Book book = new Book(); 21 | book.setTitle("Yet Another Book"); 22 | Book saved = bookRepository.save(book); 23 | assertNotNull(saved.getId()); 24 | List books = bookRepository.findAll(); 25 | assertEquals(2, books.size()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/README.md: -------------------------------------------------------------------------------- 1 | This project demonstrates a setup where the test resources service is not shared between subprojects: each of them uses their own test resources service. 2 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.test-resources") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo" 8 | 9 | dependencies { 10 | annotationProcessor("io.micronaut:micronaut-http-validation") 11 | annotationProcessor("io.micronaut.data:micronaut-data-processor") 12 | implementation("io.micronaut:micronaut-http-client") 13 | implementation("io.micronaut:micronaut-jackson-databind") 14 | implementation("io.micronaut:micronaut-runtime") 15 | implementation("jakarta.annotation:jakarta.annotation-api") 16 | implementation("io.micronaut.validation:micronaut-validation") 17 | implementation("io.micronaut.data:micronaut-data-jdbc") 18 | implementation("io.micronaut.sql:micronaut-jdbc-hikari") 19 | runtimeOnly("mysql:mysql-connector-java") 20 | runtimeOnly("ch.qos.logback:logback-classic") 21 | runtimeOnly("io.micronaut:micronaut-jackson-databind") 22 | runtimeOnly("org.yaml:snakeyaml") 23 | 24 | } 25 | 26 | application { 27 | mainClass.set("demo.Application") 28 | } 29 | 30 | micronaut { 31 | runtime("netty") 32 | testRuntime("junit5") 33 | processing { 34 | incremental(true) 35 | annotations("demo.*") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | import io.micronaut.context.event.StartupEvent; 7 | import io.micronaut.runtime.Micronaut; 8 | import io.micronaut.runtime.event.annotation.EventListener; 9 | import jakarta.inject.Inject; 10 | import jakarta.inject.Singleton; 11 | 12 | import java.util.Collections; 13 | 14 | @Singleton 15 | public class Application { 16 | 17 | @Inject 18 | private UserRepository userRepository; 19 | 20 | @Inject 21 | private BookRepository bookRepository; 22 | 23 | @ContextConfigurer 24 | public static class Configurer implements ApplicationContextConfigurer { 25 | @Override 26 | public void configure(ApplicationContextBuilder builder) { 27 | builder.deduceEnvironment(false); 28 | builder.banner(true); 29 | } 30 | } 31 | 32 | public static void main(String[] args) { 33 | Micronaut.run(Application.class, args); 34 | if (System.getProperty("interruptStartup") != null) { 35 | System.exit(0); 36 | } 37 | } 38 | 39 | @EventListener 40 | public void onStart(StartupEvent event) { 41 | if (userRepository.count() == 0) { 42 | User admin = new User(); 43 | admin.setName("Administrator"); 44 | userRepository.save(admin); 45 | } 46 | if (bookRepository.count() == 0) { 47 | Book book = new Book(); 48 | book.setTitle("The Hitchhiker's Guide to the Galaxy"); 49 | bookRepository.save(book); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/java/demo/Book.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class Book { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | 28 | private String title; 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public void setId(Long id) { 35 | this.id = id; 36 | } 37 | 38 | public String getTitle() { 39 | return title; 40 | } 41 | 42 | public void setTitle(String title) { 43 | this.title = title; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/java/demo/BookController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import jakarta.transaction.Transactional; 22 | import java.util.List; 23 | 24 | @Controller("/") 25 | @Transactional 26 | public class BookController { 27 | private final BookRepository bookRepository; 28 | 29 | public BookController(BookRepository bookRepository) { 30 | this.bookRepository = bookRepository; 31 | } 32 | 33 | @Get("/books") 34 | public List list() { 35 | return bookRepository.findAll(); 36 | } 37 | 38 | @Get("/books/add/{title}") 39 | public Book add(String title) { 40 | Book book = new Book(); 41 | book.setTitle(title); 42 | return bookRepository.save(book); 43 | } 44 | 45 | @Get("/books/{id}") 46 | public Book get(Long id) { 47 | return bookRepository.findById(id).orElse(null); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/java/demo/BookRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.Repository; 19 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 20 | import io.micronaut.data.model.query.builder.sql.Dialect; 21 | import io.micronaut.data.repository.CrudRepository; 22 | 23 | import java.util.List; 24 | 25 | @Repository("default") 26 | @JdbcRepository(dialect = Dialect.MYSQL) 27 | public interface BookRepository extends CrudRepository { 28 | @Override 29 | List findAll(); 30 | } 31 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/java/demo/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class User { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | private String name; 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public Long getId() { 38 | return id; 39 | } 40 | 41 | public void setId(Long id) { 42 | this.id = id; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/java/demo/UserController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import java.util.List; 22 | 23 | @Controller("/users") 24 | public class UserController { 25 | 26 | private final UserRepository userRepository; 27 | 28 | public UserController(UserRepository userRepository) { 29 | this.userRepository = userRepository; 30 | } 31 | 32 | @Get("/") 33 | public List list() { 34 | return userRepository.findAll(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/java/demo/UserRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 19 | import io.micronaut.data.model.query.builder.sql.Dialect; 20 | import io.micronaut.data.repository.CrudRepository; 21 | 22 | import java.util.List; 23 | 24 | //@Repository("users") 25 | @JdbcRepository(dialect = Dialect.MYSQL) 26 | public interface UserRepository extends CrudRepository { 27 | @Override 28 | List findAll(); 29 | } 30 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: demo 4 | server: 5 | port: -1 6 | netty: 7 | default: 8 | allocator: 9 | max-order: 3 10 | datasources: 11 | default: 12 | schema-generate: CREATE_DROP 13 | dialect: MYSQL 14 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app1/src/test/java/demo/DemoTest.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 4 | import jakarta.inject.Inject; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertNotNull; 11 | 12 | @MicronautTest 13 | class DemoTest { 14 | 15 | @Inject 16 | BookRepository bookRepository; 17 | 18 | @Test 19 | void testItWorks() { 20 | Book book = new Book(); 21 | book.setTitle("Yet Another Book"); 22 | Book saved = bookRepository.save(book); 23 | assertNotNull(saved.getId()); 24 | List books = bookRepository.findAll(); 25 | assertEquals(2, books.size()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.test-resources") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo" 8 | 9 | dependencies { 10 | annotationProcessor("io.micronaut:micronaut-http-validation") 11 | annotationProcessor("io.micronaut.data:micronaut-data-processor") 12 | implementation("io.micronaut:micronaut-http-client") 13 | implementation("io.micronaut:micronaut-jackson-databind") 14 | implementation("io.micronaut:micronaut-runtime") 15 | implementation("jakarta.annotation:jakarta.annotation-api") 16 | implementation("io.micronaut.validation:micronaut-validation") 17 | implementation("io.micronaut.data:micronaut-data-jdbc") 18 | implementation("io.micronaut.sql:micronaut-jdbc-hikari") 19 | runtimeOnly("ch.qos.logback:logback-classic") 20 | runtimeOnly("io.micronaut:micronaut-jackson-databind") 21 | runtimeOnly("org.yaml:snakeyaml") 22 | runtimeOnly("org.postgresql:postgresql") 23 | } 24 | 25 | application { 26 | mainClass.set("demo.Application") 27 | } 28 | 29 | micronaut { 30 | runtime("netty") 31 | testRuntime("junit5") 32 | processing { 33 | incremental(true) 34 | annotations("demo.*") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | import io.micronaut.context.event.StartupEvent; 7 | import io.micronaut.runtime.Micronaut; 8 | import io.micronaut.runtime.event.annotation.EventListener; 9 | import jakarta.inject.Inject; 10 | import jakarta.inject.Singleton; 11 | 12 | import java.util.Collections; 13 | 14 | @Singleton 15 | public class Application { 16 | 17 | @Inject 18 | private UserRepository userRepository; 19 | 20 | @Inject 21 | private BookRepository bookRepository; 22 | 23 | @ContextConfigurer 24 | public static class Configurer implements ApplicationContextConfigurer { 25 | @Override 26 | public void configure(ApplicationContextBuilder builder) { 27 | builder.deduceEnvironment(false); 28 | builder.banner(true); 29 | } 30 | } 31 | 32 | public static void main(String[] args) { 33 | Micronaut.run(Application.class, args); 34 | if (System.getProperty("interruptStartup") != null) { 35 | System.exit(0); 36 | } 37 | } 38 | 39 | @EventListener 40 | public void onStart(StartupEvent event) { 41 | if (userRepository.count() == 0) { 42 | User admin = new User(); 43 | admin.setName("Administrator"); 44 | userRepository.save(admin); 45 | } 46 | if (bookRepository.count() == 0) { 47 | Book book = new Book(); 48 | book.setTitle("The Hitchhiker's Guide to the Galaxy"); 49 | bookRepository.save(book); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/java/demo/Book.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class Book { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | 28 | private String title; 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public void setId(Long id) { 35 | this.id = id; 36 | } 37 | 38 | public String getTitle() { 39 | return title; 40 | } 41 | 42 | public void setTitle(String title) { 43 | this.title = title; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/java/demo/BookController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import jakarta.transaction.Transactional; 22 | import java.util.List; 23 | 24 | @Controller("/") 25 | @Transactional 26 | public class BookController { 27 | private final BookRepository bookRepository; 28 | 29 | public BookController(BookRepository bookRepository) { 30 | this.bookRepository = bookRepository; 31 | } 32 | 33 | @Get("/books") 34 | public List list() { 35 | return bookRepository.findAll(); 36 | } 37 | 38 | @Get("/books/add/{title}") 39 | public Book add(String title) { 40 | Book book = new Book(); 41 | book.setTitle(title); 42 | return bookRepository.save(book); 43 | } 44 | 45 | @Get("/books/{id}") 46 | public Book get(Long id) { 47 | return bookRepository.findById(id).orElse(null); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/java/demo/BookRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.Repository; 19 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 20 | import io.micronaut.data.model.query.builder.sql.Dialect; 21 | import io.micronaut.data.repository.CrudRepository; 22 | 23 | import java.util.List; 24 | 25 | @Repository("default") 26 | @JdbcRepository(dialect = Dialect.POSTGRES) 27 | public interface BookRepository extends CrudRepository { 28 | @Override 29 | List findAll(); 30 | } 31 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/java/demo/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class User { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | private String name; 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public Long getId() { 38 | return id; 39 | } 40 | 41 | public void setId(Long id) { 42 | this.id = id; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/java/demo/UserController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import java.util.List; 22 | 23 | @Controller("/users") 24 | public class UserController { 25 | 26 | private final UserRepository userRepository; 27 | 28 | public UserController(UserRepository userRepository) { 29 | this.userRepository = userRepository; 30 | } 31 | 32 | @Get("/") 33 | public List list() { 34 | return userRepository.findAll(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/java/demo/UserRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 19 | import io.micronaut.data.model.query.builder.sql.Dialect; 20 | import io.micronaut.data.repository.CrudRepository; 21 | 22 | import java.util.List; 23 | 24 | //@Repository("users") 25 | @JdbcRepository(dialect = Dialect.POSTGRES) 26 | public interface UserRepository extends CrudRepository { 27 | @Override 28 | List findAll(); 29 | } 30 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: demo 4 | server: 5 | port: -1 6 | netty: 7 | default: 8 | allocator: 9 | max-order: 3 10 | datasources: 11 | default: 12 | schema-generate: CREATE_DROP 13 | dialect: POSTGRES 14 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app2/src/test/java/demo/DemoTest.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 4 | import jakarta.inject.Inject; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertNotNull; 11 | 12 | @MicronautTest 13 | class DemoTest { 14 | 15 | @Inject 16 | BookRepository bookRepository; 17 | 18 | @Test 19 | void testItWorks() { 20 | Book book = new Book(); 21 | book.setTitle("Yet Another Book"); 22 | Book saved = bookRepository.save(book); 23 | assertNotNull(saved.getId()); 24 | List books = bookRepository.findAll(); 25 | assertEquals(2, books.size()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app3/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.test-resources") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo" 8 | 9 | dependencies { 10 | annotationProcessor("io.micronaut:micronaut-http-validation") 11 | runtimeOnly("io.micronaut:micronaut-jackson-databind") 12 | runtimeOnly("org.yaml:snakeyaml") 13 | } 14 | 15 | micronaut { 16 | testRuntime("junit5") 17 | processing { 18 | incremental(true) 19 | annotations("demo.*") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app3/src/test/java/demo/DemoTest.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 4 | import jakarta.inject.Inject; 5 | import org.junit.jupiter.api.Test; 6 | import io.micronaut.context.annotation.Value; 7 | 8 | import java.util.List; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | import static org.junit.jupiter.api.Assertions.assertNotNull; 12 | 13 | @MicronautTest 14 | class DemoTest { 15 | 16 | @Value("${greeting.message}") 17 | String greeting; 18 | 19 | @Test 20 | void testItWorks() { 21 | assertEquals("Hello from my test resource!", greeting); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app3/src/testResources/java/demo/GreetingTestResource.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.testresources.core.TestResourcesResolver; 4 | 5 | import java.util.Collection; 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Optional; 10 | 11 | public class GreetingTestResource implements TestResourcesResolver { 12 | 13 | public static final String PROPERTY = "greeting.message"; 14 | 15 | @Override 16 | public List getResolvableProperties(Map> propertyEntries, Map testResourcesConfig) { 17 | return Collections.singletonList(PROPERTY); 18 | } 19 | 20 | @Override 21 | public Optional resolve(String propertyName, Map properties, Map testResourcesConfiguration) { 22 | if (PROPERTY.equals(propertyName)) { 23 | return Optional.of("Hello from my test resource!"); 24 | } 25 | return Optional.empty(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/app3/src/testResources/resources/META-INF/services/io.micronaut.testresources.core.TestResourcesResolver: -------------------------------------------------------------------------------- 1 | demo.GreetingTestResource 2 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=3.5.1 2 | -------------------------------------------------------------------------------- /samples/test-resources/isolated-multiproject/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'app1' 2 | include 'app2' 3 | include 'app3' 4 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/README.md: -------------------------------------------------------------------------------- 1 | This project demonstrates a setup where the test resources service is started in a separate project of a multi-project build. 2 | 3 | This can be useful when you want to share the same test resources between multiple projects of a single build. 4 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.test-resources-consumer") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo" 8 | 9 | dependencies { 10 | annotationProcessor("io.micronaut:micronaut-http-validation") 11 | annotationProcessor("io.micronaut.data:micronaut-data-processor") 12 | implementation("io.micronaut:micronaut-http-client") 13 | implementation("io.micronaut:micronaut-jackson-databind") 14 | implementation("io.micronaut:micronaut-runtime") 15 | implementation("jakarta.annotation:jakarta.annotation-api") 16 | implementation("io.micronaut.validation:micronaut-validation") 17 | implementation("io.micronaut.data:micronaut-data-jdbc") 18 | implementation("io.micronaut.sql:micronaut-jdbc-hikari") 19 | runtimeOnly("ch.qos.logback:logback-classic") 20 | runtimeOnly("io.micronaut:micronaut-jackson-databind") 21 | runtimeOnly("org.yaml:snakeyaml") 22 | runtimeOnly("mysql:mysql-connector-java") 23 | 24 | testResourcesService(project(":testresources")) 25 | } 26 | 27 | application { 28 | mainClass.set("demo.Application") 29 | } 30 | 31 | micronaut { 32 | runtime("netty") 33 | testRuntime("junit5") 34 | processing { 35 | incremental(true) 36 | annotations("demo.*") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | import io.micronaut.context.event.StartupEvent; 7 | import io.micronaut.runtime.Micronaut; 8 | import io.micronaut.runtime.event.annotation.EventListener; 9 | import jakarta.inject.Inject; 10 | import jakarta.inject.Singleton; 11 | 12 | import java.util.Collections; 13 | 14 | @Singleton 15 | public class Application { 16 | 17 | @Inject 18 | private UserRepository userRepository; 19 | 20 | @Inject 21 | private BookRepository bookRepository; 22 | 23 | @ContextConfigurer 24 | public static class Configurer implements ApplicationContextConfigurer { 25 | @Override 26 | public void configure(ApplicationContextBuilder builder) { 27 | builder.deduceEnvironment(false); 28 | builder.banner(true); 29 | } 30 | } 31 | 32 | public static void main(String[] args) { 33 | Micronaut.run(Application.class, args); 34 | if (System.getProperty("interruptStartup") != null) { 35 | System.exit(0); 36 | } 37 | } 38 | 39 | @EventListener 40 | public void onStart(StartupEvent event) { 41 | if (userRepository.count() == 0) { 42 | User admin = new User(); 43 | admin.setName("Administrator"); 44 | userRepository.save(admin); 45 | } 46 | if (bookRepository.count() == 0) { 47 | Book book = new Book(); 48 | book.setTitle("The Hitchhiker's Guide to the Galaxy"); 49 | bookRepository.save(book); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/java/demo/Book.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class Book { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | 28 | private String title; 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public void setId(Long id) { 35 | this.id = id; 36 | } 37 | 38 | public String getTitle() { 39 | return title; 40 | } 41 | 42 | public void setTitle(String title) { 43 | this.title = title; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/java/demo/BookController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import jakarta.transaction.Transactional; 22 | import java.util.List; 23 | 24 | @Controller("/") 25 | @Transactional 26 | public class BookController { 27 | private final BookRepository bookRepository; 28 | 29 | public BookController(BookRepository bookRepository) { 30 | this.bookRepository = bookRepository; 31 | } 32 | 33 | @Get("/books") 34 | public List list() { 35 | return bookRepository.findAll(); 36 | } 37 | 38 | @Get("/books/add/{title}") 39 | public Book add(String title) { 40 | Book book = new Book(); 41 | book.setTitle(title); 42 | return bookRepository.save(book); 43 | } 44 | 45 | @Get("/books/{id}") 46 | public Book get(Long id) { 47 | return bookRepository.findById(id).orElse(null); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/java/demo/BookRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.Repository; 19 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 20 | import io.micronaut.data.model.query.builder.sql.Dialect; 21 | import io.micronaut.data.repository.CrudRepository; 22 | 23 | import java.util.List; 24 | 25 | @Repository("default") 26 | @JdbcRepository(dialect = Dialect.MYSQL) 27 | public interface BookRepository extends CrudRepository { 28 | @Override 29 | List findAll(); 30 | } 31 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/java/demo/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class User { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | private String name; 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public Long getId() { 38 | return id; 39 | } 40 | 41 | public void setId(Long id) { 42 | this.id = id; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/java/demo/UserController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import java.util.List; 22 | 23 | @Controller("/users") 24 | public class UserController { 25 | 26 | private final UserRepository userRepository; 27 | 28 | public UserController(UserRepository userRepository) { 29 | this.userRepository = userRepository; 30 | } 31 | 32 | @Get("/") 33 | public List list() { 34 | return userRepository.findAll(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/java/demo/UserRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 19 | import io.micronaut.data.model.query.builder.sql.Dialect; 20 | import io.micronaut.data.repository.CrudRepository; 21 | 22 | import java.util.List; 23 | 24 | //@Repository("users") 25 | @JdbcRepository(dialect = Dialect.MYSQL) 26 | public interface UserRepository extends CrudRepository { 27 | @Override 28 | List findAll(); 29 | } 30 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: demo 4 | server: 5 | port: -1 6 | netty: 7 | default: 8 | allocator: 9 | max-order: 3 10 | datasources: 11 | default: 12 | schema-generate: CREATE_DROP 13 | dialect: MYSQL 14 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app1/src/test/java/demo/DemoTest.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 4 | import jakarta.inject.Inject; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertNotNull; 11 | 12 | @MicronautTest 13 | class DemoTest { 14 | 15 | @Inject 16 | BookRepository bookRepository; 17 | 18 | @Test 19 | void testItWorks() { 20 | Book book = new Book(); 21 | book.setTitle("Yet Another Book"); 22 | Book saved = bookRepository.save(book); 23 | assertNotNull(saved.getId()); 24 | List books = bookRepository.findAll(); 25 | assertEquals(2, books.size()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.test-resources-consumer") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo" 8 | 9 | dependencies { 10 | annotationProcessor("io.micronaut:micronaut-http-validation") 11 | annotationProcessor("io.micronaut.data:micronaut-data-processor") 12 | implementation("io.micronaut:micronaut-http-client") 13 | implementation("io.micronaut:micronaut-jackson-databind") 14 | implementation("io.micronaut:micronaut-runtime") 15 | implementation("jakarta.annotation:jakarta.annotation-api") 16 | implementation("io.micronaut.validation:micronaut-validation") 17 | implementation("io.micronaut.data:micronaut-data-jdbc") 18 | implementation("io.micronaut.sql:micronaut-jdbc-hikari") 19 | runtimeOnly("ch.qos.logback:logback-classic") 20 | runtimeOnly("io.micronaut:micronaut-jackson-databind") 21 | runtimeOnly("org.yaml:snakeyaml") 22 | runtimeOnly("org.postgresql:postgresql") 23 | 24 | testResourcesService(project(":testresources")) 25 | } 26 | 27 | application { 28 | mainClass.set("demo.Application") 29 | } 30 | 31 | micronaut { 32 | runtime("netty") 33 | testRuntime("junit5") 34 | processing { 35 | incremental(true) 36 | annotations("demo.*") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.context.ApplicationContextBuilder; 4 | import io.micronaut.context.ApplicationContextConfigurer; 5 | import io.micronaut.context.annotation.ContextConfigurer; 6 | import io.micronaut.context.event.StartupEvent; 7 | import io.micronaut.runtime.Micronaut; 8 | import io.micronaut.runtime.event.annotation.EventListener; 9 | import jakarta.inject.Inject; 10 | import jakarta.inject.Singleton; 11 | 12 | import java.util.Collections; 13 | 14 | @Singleton 15 | public class Application { 16 | 17 | @Inject 18 | private UserRepository userRepository; 19 | 20 | @Inject 21 | private BookRepository bookRepository; 22 | 23 | @ContextConfigurer 24 | public static class Configurer implements ApplicationContextConfigurer { 25 | @Override 26 | public void configure(ApplicationContextBuilder builder) { 27 | builder.deduceEnvironment(false); 28 | builder.banner(true); 29 | } 30 | } 31 | 32 | public static void main(String[] args) { 33 | Micronaut.run(Application.class, args); 34 | if (System.getProperty("interruptStartup") != null) { 35 | System.exit(0); 36 | } 37 | } 38 | 39 | @EventListener 40 | public void onStart(StartupEvent event) { 41 | if (userRepository.count() == 0) { 42 | User admin = new User(); 43 | admin.setName("Administrator"); 44 | userRepository.save(admin); 45 | } 46 | if (bookRepository.count() == 0) { 47 | Book book = new Book(); 48 | book.setTitle("The Hitchhiker's Guide to the Galaxy"); 49 | bookRepository.save(book); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/java/demo/Book.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class Book { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | 28 | private String title; 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public void setId(Long id) { 35 | this.id = id; 36 | } 37 | 38 | public String getTitle() { 39 | return title; 40 | } 41 | 42 | public void setTitle(String title) { 43 | this.title = title; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/java/demo/BookController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import jakarta.transaction.Transactional; 22 | import java.util.List; 23 | 24 | @Controller("/") 25 | @Transactional 26 | public class BookController { 27 | private final BookRepository bookRepository; 28 | 29 | public BookController(BookRepository bookRepository) { 30 | this.bookRepository = bookRepository; 31 | } 32 | 33 | @Get("/books") 34 | public List list() { 35 | return bookRepository.findAll(); 36 | } 37 | 38 | @Get("/books/add/{title}") 39 | public Book add(String title) { 40 | Book book = new Book(); 41 | book.setTitle(title); 42 | return bookRepository.save(book); 43 | } 44 | 45 | @Get("/books/{id}") 46 | public Book get(Long id) { 47 | return bookRepository.findById(id).orElse(null); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/java/demo/BookRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.Repository; 19 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 20 | import io.micronaut.data.model.query.builder.sql.Dialect; 21 | import io.micronaut.data.repository.CrudRepository; 22 | 23 | import java.util.List; 24 | 25 | @Repository("default") 26 | @JdbcRepository(dialect = Dialect.POSTGRES) 27 | public interface BookRepository extends CrudRepository { 28 | @Override 29 | List findAll(); 30 | } 31 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/java/demo/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.annotation.GeneratedValue; 19 | import io.micronaut.data.annotation.Id; 20 | import io.micronaut.data.annotation.MappedEntity; 21 | 22 | @MappedEntity 23 | public class User { 24 | @Id 25 | @GeneratedValue(GeneratedValue.Type.AUTO) 26 | private Long id; 27 | private String name; 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public Long getId() { 38 | return id; 39 | } 40 | 41 | public void setId(Long id) { 42 | this.id = id; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/java/demo/UserController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.http.annotation.Controller; 19 | import io.micronaut.http.annotation.Get; 20 | 21 | import java.util.List; 22 | 23 | @Controller("/users") 24 | public class UserController { 25 | 26 | private final UserRepository userRepository; 27 | 28 | public UserController(UserRepository userRepository) { 29 | this.userRepository = userRepository; 30 | } 31 | 32 | @Get("/") 33 | public List list() { 34 | return userRepository.findAll(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/java/demo/UserRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo; 17 | 18 | import io.micronaut.data.jdbc.annotation.JdbcRepository; 19 | import io.micronaut.data.model.query.builder.sql.Dialect; 20 | import io.micronaut.data.repository.CrudRepository; 21 | 22 | import java.util.List; 23 | 24 | //@Repository("users") 25 | @JdbcRepository(dialect = Dialect.POSTGRES) 26 | public interface UserRepository extends CrudRepository { 27 | @Override 28 | List findAll(); 29 | } 30 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: demo 4 | server: 5 | port: -1 6 | netty: 7 | default: 8 | allocator: 9 | max-order: 3 10 | datasources: 11 | default: 12 | schema-generate: CREATE_DROP 13 | dialect: POSTGRES 14 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app2/src/test/java/demo/DemoTest.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 4 | import jakarta.inject.Inject; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertNotNull; 11 | 12 | @MicronautTest 13 | class DemoTest { 14 | 15 | @Inject 16 | BookRepository bookRepository; 17 | 18 | @Test 19 | void testItWorks() { 20 | Book book = new Book(); 21 | book.setTitle("Yet Another Book"); 22 | Book saved = bookRepository.save(book); 23 | assertNotNull(saved.getId()); 24 | List books = bookRepository.findAll(); 25 | assertEquals(2, books.size()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app3/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.minimal.application") 3 | id("io.micronaut.test-resources-consumer") 4 | } 5 | 6 | version = "0.1" 7 | group = "demo" 8 | 9 | dependencies { 10 | annotationProcessor("io.micronaut:micronaut-http-validation") 11 | runtimeOnly("io.micronaut:micronaut-jackson-databind") 12 | runtimeOnly("org.yaml:snakeyaml") 13 | 14 | testResourcesService(project(":testresources")) 15 | } 16 | 17 | micronaut { 18 | testRuntime("junit5") 19 | processing { 20 | incremental(true) 21 | annotations("demo.*") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/app3/src/test/java/demo/DemoTest.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 4 | import jakarta.inject.Inject; 5 | import org.junit.jupiter.api.Test; 6 | import io.micronaut.context.annotation.Value; 7 | 8 | import java.util.List; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | import static org.junit.jupiter.api.Assertions.assertNotNull; 12 | 13 | @MicronautTest 14 | class DemoTest { 15 | 16 | @Value("${greeting.message}") 17 | String greeting; 18 | 19 | @Test 20 | void testItWorks() { 21 | assertEquals("Hello from my test resource!", greeting); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=3.5.1 2 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'app1' 2 | include 'app2' 3 | include 'app3' 4 | include 'testresources' 5 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/testresources/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.micronaut.test-resources") 3 | } 4 | 5 | version = "0.1" 6 | group = "demo" 7 | 8 | micronaut { 9 | testResources { 10 | // app1 uses MySQL 11 | additionalModules.add(JDBC_MYSQL) 12 | // app2 uses PostgreSQL 13 | additionalModules.add(JDBC_POSTGRESQL) 14 | // app3 uses the test resources resolver provided by this project 15 | } 16 | } 17 | 18 | dependencies { 19 | testResourcesService 'mysql:mysql-connector-java' 20 | testResourcesService 'org.postgresql:postgresql' 21 | } 22 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/testresources/src/testResources/java/demo/GreetingTestResource.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import io.micronaut.testresources.core.TestResourcesResolver; 4 | 5 | import java.util.Collection; 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Optional; 10 | 11 | public class GreetingTestResource implements TestResourcesResolver { 12 | 13 | public static final String PROPERTY = "greeting.message"; 14 | 15 | @Override 16 | public List getResolvableProperties(Map> propertyEntries, Map testResourcesConfig) { 17 | return Collections.singletonList(PROPERTY); 18 | } 19 | 20 | @Override 21 | public Optional resolve(String propertyName, Map properties, Map testResourcesConfiguration) { 22 | if (PROPERTY.equals(propertyName)) { 23 | return Optional.of("Hello from my test resource!"); 24 | } 25 | return Optional.empty(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /samples/test-resources/multiproject/testresources/src/testResources/resources/META-INF/services/io.micronaut.testresources.core.TestResourcesResolver: -------------------------------------------------------------------------------- 1 | demo.GreetingTestResource 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenCentral() 4 | gradlePluginPortal() 5 | // maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") } 6 | } 7 | //includeBuild("/home/cchampeau/DEV/PROJECTS/GITHUB/micronaut/micronaut-build") 8 | } 9 | 10 | plugins { 11 | id 'io.micronaut.build.shared.settings' version '7.4.0' 12 | } 13 | 14 | rootProject.name = 'micronaut-gradle-plugin-parent' 15 | 16 | include("platform-catalog-plugin") 17 | include("minimal-plugin") 18 | include("crac-plugin") 19 | include("docker-plugin") 20 | include("graalvm-plugin") 21 | include("aot-plugin") 22 | include("gradle-plugin") 23 | include("openapi-plugin") 24 | include("test-resources-plugin") 25 | include("functional-tests") 26 | include("jsonschema-plugin") 27 | 28 | enableFeaturePreview 'TYPESAFE_PROJECT_ACCESSORS' 29 | 30 | micronautBuild { 31 | useStandardizedProjectNames = true 32 | nonStandardProjectNamePrefixes.add("functional-tests") 33 | } 34 | -------------------------------------------------------------------------------- /test-resources-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.micronaut.internal.build.gradle-plugin" 3 | } 4 | 5 | description = "Micronaut Test Resources Gradle plugin" 6 | 7 | micronautPlugins { 8 | register('test-resources', 'io.micronaut.gradle.testresources.MicronautTestResourcesPlugin', 'Micronaut Test Resources Plugin') 9 | register('test-resources-consumer', 'io.micronaut.gradle.testresources.MicronautTestResourcesConsumerPlugin', 'Micronaut Test Resources Consumer Plugin') 10 | } 11 | 12 | dependencies { 13 | compileOnly libs.graalvmPlugin 14 | compileOnly projects.micronautAotPlugin 15 | 16 | implementation libs.micronaut.testresources 17 | implementation projects.micronautMinimalPlugin 18 | 19 | testImplementation testFixtures(projects.micronautMinimalPlugin) 20 | } 21 | -------------------------------------------------------------------------------- /test-resources-plugin/src/main/java/io/micronaut/gradle/testresources/StopTestResourcesService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.micronaut.gradle.testresources; 17 | 18 | import io.micronaut.testresources.buildtools.ServerUtils; 19 | import org.gradle.api.DefaultTask; 20 | import org.gradle.api.file.DirectoryProperty; 21 | import org.gradle.api.internal.file.FileOperations; 22 | import org.gradle.api.tasks.Destroys; 23 | import org.gradle.api.tasks.TaskAction; 24 | 25 | import javax.inject.Inject; 26 | import java.io.IOException; 27 | 28 | /** 29 | * A task to explicitly stop the test resources server. 30 | */ 31 | public abstract class StopTestResourcesService extends DefaultTask { 32 | @Destroys 33 | public abstract DirectoryProperty getSettingsDirectory(); 34 | 35 | @Inject 36 | protected abstract FileOperations getFileOperations(); 37 | 38 | @Inject 39 | public StopTestResourcesService() { 40 | setGroup(MicronautTestResourcesPlugin.GROUP); 41 | setDescription("Stops the test resources server"); 42 | } 43 | 44 | @TaskAction 45 | void stopServer() throws IOException { 46 | getLogger().lifecycle("Stopping test resources service"); 47 | ServerUtils.stopServer(getSettingsDirectory().get().getAsFile().toPath()); 48 | getFileOperations().delete(getSettingsDirectory()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test-resources-plugin/src/test/groovy/io/micronaut/gradle/testresources/CustomTestResourcePluginSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.testresources 2 | 3 | import io.micronaut.gradle.AbstractGradleBuildSpec 4 | import org.gradle.testkit.runner.TaskOutcome 5 | import spock.lang.Issue 6 | import spock.lang.Requires 7 | 8 | @Requires({ !os.windows }) 9 | class CustomTestResourcePluginSpec extends AbstractGradleBuildSpec { 10 | 11 | def "can implement a custom test resource using the testResources source set"() { 12 | withSample("test-resources/custom-test-resource") 13 | 14 | when: 15 | def result = build 'test', '-S' 16 | 17 | then: 18 | result.task(':test').outcome == TaskOutcome.SUCCESS 19 | result.output.contains "Loaded 2 test resources resolvers" 20 | result.output.contains "demo.GreetingTestResource" 21 | result.output.contains "io.micronaut.testresources.testcontainers.GenericTestContainerProvider" 22 | } 23 | 24 | @Issue("https://github.com/micronaut-projects/micronaut-gradle-plugin/issues/619") 25 | def "test task is not up-to-date when custom test resource is updated"() { 26 | withSample("test-resources/custom-test-resource") 27 | 28 | when: 29 | def result = build 'test' 30 | 31 | then: 32 | result.task(':test').outcome == TaskOutcome.SUCCESS 33 | result.output.contains "Loaded 2 test resources resolvers" 34 | result.output.contains "demo.GreetingTestResource" 35 | result.output.contains "io.micronaut.testresources.testcontainers.GenericTestContainerProvider" 36 | 37 | when: 38 | def ctr = file("src/testResources/java/demo/GreetingTestResource.java") 39 | ctr.text = ctr.text.replace("hello", "Hola") 40 | 41 | then: 42 | fails 'test' 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /test-resources-plugin/src/test/groovy/io/micronaut/gradle/testresources/MicronautTestResourcesPluginTest.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.testresources 2 | 3 | import spock.lang.Specification 4 | 5 | class MicronautTestResourcesPluginTest extends Specification { 6 | def "ignores appendix when testing versions"() { 7 | expect: 8 | MicronautTestResourcesPlugin.parseVersion(version) == expected 9 | 10 | where: 11 | version | expected 12 | '1.0' | [1, 0] 13 | '1.1.0' | [1, 1, 0] 14 | '1.1-SNAPSHOT' | [1, 1] 15 | '1.1-M3' | [1, 1] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test-resources-plugin/src/test/groovy/io/micronaut/gradle/testresources/MultiProjectTestResourcePluginSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.micronaut.gradle.testresources 2 | 3 | import io.micronaut.gradle.AbstractGradleBuildSpec 4 | import org.gradle.testkit.runner.TaskOutcome 5 | import spock.lang.Requires 6 | 7 | @Requires({ !os.windows }) 8 | class MultiProjectTestResourcePluginSpec extends AbstractGradleBuildSpec { 9 | 10 | def "can share a test resources service in a multiproject"() { 11 | withSample("test-resources/multiproject") 12 | 13 | when: 14 | def result = build 'test' 15 | 16 | then: 17 | result.task(':testresources:internalStartTestResourcesService').outcome == TaskOutcome.SUCCESS 18 | result.task(':app1:test').outcome == TaskOutcome.SUCCESS 19 | result.task(':app2:test').outcome == TaskOutcome.SUCCESS 20 | result.task(':app3:test').outcome == TaskOutcome.SUCCESS 21 | result.output.contains "Loaded 4 test resources resolvers" 22 | result.output.contains "demo.GreetingTestResource" 23 | result.output.contains "io.micronaut.testresources.testcontainers.GenericTestContainerProvider" 24 | result.output.contains "io.micronaut.testresources.mysql.MySQLTestResourceProvider" 25 | result.output.contains "io.micronaut.testresources.postgres.PostgreSQLTestResourceProvider" 26 | } 27 | 28 | def "can use independent test resource services"() { 29 | withSample("test-resources/isolated-multiproject") 30 | 31 | when: 32 | def result = build 'test' 33 | 34 | then: 35 | result.task(':app1:internalStartTestResourcesService').outcome == TaskOutcome.SUCCESS 36 | result.task(':app1:test').outcome == TaskOutcome.SUCCESS 37 | result.task(':app2:internalStartTestResourcesService').outcome == TaskOutcome.SUCCESS 38 | result.task(':app2:test').outcome == TaskOutcome.SUCCESS 39 | result.task(':app3:internalStartTestResourcesService').outcome == TaskOutcome.SUCCESS 40 | result.task(':app3:test').outcome == TaskOutcome.SUCCESS 41 | if (System.getenv("TESTCONTAINERS_RYUK_DISABLED") != "true") { 42 | assert result.output.count("Creating container for image: testcontainers/ryuk") == 2 43 | } 44 | } 45 | 46 | } 47 | --------------------------------------------------------------------------------