{"id":20875226,"url":"https://github.com/smallrye/smallrye-safer-annotations","last_synced_at":"2025-07-30T16:33:53.348Z","repository":{"id":37964735,"uuid":"340097190","full_name":"smallrye/smallrye-safer-annotations","owner":"smallrye","description":"Safer annotation constraints","archived":false,"fork":false,"pushed_at":"2023-04-05T12:58:16.000Z","size":55,"stargazers_count":3,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2023-07-28T18:09:35.515Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smallrye.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null}},"created_at":"2021-02-18T15:43:29.000Z","updated_at":"2023-07-16T07:56:58.000Z","dependencies_parsed_at":"2023-02-17T19:25:20.069Z","dependency_job_id":null,"html_url":"https://github.com/smallrye/smallrye-safer-annotations","commit_stats":null,"previous_names":[],"tags_count":3,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallrye%2Fsmallrye-safer-annotations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallrye%2Fsmallrye-safer-annotations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallrye%2Fsmallrye-safer-annotations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallrye%2Fsmallrye-safer-annotations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smallrye","download_url":"https://codeload.github.com/smallrye/smallrye-safer-annotations/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225140481,"owners_count":17427122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-18T06:43:17.855Z","updated_at":"2024-11-18T06:43:18.531Z","avatar_url":"https://github.com/smallrye.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Safer Annotations helps you define constraints on your annotations that are richer than the\nstock Java constraints (type, method, field…).\n\n# Usage, for library authors\n\nImport the Safer Annotations module in your `pom.xml`:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.smallrye\u003c/groupId\u003e\n    \u003cartifactId\u003esmallrye-safer-annotations\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nAnd start annotating your library annotations with safer constraints:\n\n```java\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD)\n// Restrict the type signature of target methods\n@TargetMethod(\n  /* set of allowed return types */\n  returnTypes = { void.class, Response.class, UniResponse.class, OptionalResponse.class }, \n  /* set of allowed parameter types */\n  parameterTypes = { ContainerRequestContext.class, ContainerResponseContext.class, ResourceInfo.class, SimpleResourceInfo.class, ThrowableSubtype.class}\n)\npublic @interface ServerResponseFilter {\n}\n\n// Allows us to pass generic types to the @TargetMethod annotation\nclass UniResponse extends TargetMethod.GenericType\u003cUni\u003cResponse\u003e\u003e {\n}\n\nclass OptionalResponse extends TargetMethod.GenericType\u003cOptional\u003cResponse\u003e\u003e {\n}\n\n// Allows us to declare parameter types that can be any subtype of Throwable\nclass ThrowableSubtype extends TargetMethod.Subtype\u003cThrowable\u003e {\n}\n```\n\n# Usage, for your library's users\n\nTell your build tool to invoke our compiler plugin:\n\n```xml\n\u003cbuild\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n            \u003cversion\u003e${compiler-plugin.version}\u003c/version\u003e\n            \u003cconfiguration\u003e\n                \u003cannotationProcessorPaths\u003e\n                    \u003cannotationProcessorPath\u003e\n                        \u003cgroupId\u003eio.smallrye\u003c/groupId\u003e\n                        \u003cartifactId\u003esmallrye-safer-annotations\u003c/artifactId\u003e\n                        \u003cversion\u003e1.0.2\u003c/version\u003e\n                    \u003c/annotationProcessorPath\u003e\n                \u003c/annotationProcessorPaths\u003e\n            \u003c/configuration\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\nNow your users can get compile-time errors if they misplace your annotations:\n\n```java\n@ServerResponseFilter\n// ERROR: Invalid parameter type: must be one of: […]\npublic void myFilter(NonSupportedType something){\n}\n```\n\n# Supported annotation constraints\n\n- `@TargetAccessor`: annotated method must be a Java Bean getter or setter\n- `@TargetMethod`: annotated method must have a compatible method signature\n\n# Declaring or overriding annotation constraints on external annotations\n\nIf you cannot annotate the contained annotation directly, because it is external to your project,\nyou can declare a `DefinitionOverride` implementation and place the constaints on it instead.\n\nFirst, create a `META-INF/services/io.smallrye.safer.annotations.DefinitionOverride` file containing\nthe list of override class names:\n\n```\ncom.example.foo.MyOverride\n```\n\nAnd place your constraints on your override class:\n\n```java\npackage com.example.foo;\n\nimport io.smallrye.safer.annotations.DefinitionOverride;\nimport io.smallrye.safer.annotations.OverrideTarget;\nimport io.smallrye.safer.annotations.TargetMethod;\n\n\n// Designate which external annotation we are targeting\n@OverrideTarget(ServerExceptionMapper.class)\n\n// Restrict the type signature of target methods\n@TargetMethod(\n  /* set of allowed return types */\n  returnTypes = { void.class, Response.class, UniResponse.class, OptionalResponse.class }, \n  /* set of allowed parameter types */\n  parameterTypes = { ContainerRequestContext.class, ContainerResponseContext.class, ResourceInfo.class, SimpleResourceInfo.class, ThrowableSubtype.class}\n)\npublic class MyOverride implements DefinitionOverride {\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmallrye%2Fsmallrye-safer-annotations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmallrye%2Fsmallrye-safer-annotations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmallrye%2Fsmallrye-safer-annotations/lists"}