Annotation Type Dynamic


  • @Target({METHOD,FIELD})
    @Retention(CLASS)
    public @interface Dynamic
    Decorator annotation for mixin elements whose targets are not available in the original class and are either fabricated or transformed at runtime. This annotation is purely for decoration purposes and has no semantic implications of any kind.

    Its use on mixin elements is encouraged because it yields the following benefits:

    1. Aids mixin maintainers by providing context for seemingly-pointless injections. An injector or overwrite whose target does not appear to exist can be given context by decorating it with this annotation.
    2. Allowing mixin tooling such as IDE plugins to gain awareness that a particular target can be allowed to fail validation from static analysis. In the case where tooling might flag the target as invalid, this annotation can provide context to suppress or enhance generated warnings.
    3. Provide additional context when an injection fails. For example if an injector decorated with @Dynamic fails to locate a valid target, mixin will include the contents of the @Dynamic annotation with the error message, providing additional debugging information to end users. This might, for example, be used to identify when an upstream transformation is disabled or changed.

    Because of the possible inclusion in error messages, it is suggested that the description provided via @Dynamic provides as much information in as terse a manner possible. Good examples of text descriptions to include might be:

    • "Method Foo.bar is added at runtime by mod X"
    • "All calls to Foo.bar are replaced at runtime by mod Y with a calls to Baz.flop"
    • "Added by SomeOtherUpstreamMixin"

    In other words, the contents of the @Dynamic should try to provide as much useful context for the decorated method without being overly verbose.

    In the case where the target method or field is added by an upstream mixin, and the mixin in question is on the classpath of the project, it is also possible to use the mixin() value to specify the mixin which contributes the target member. This provides both a useful navigable link in IDEs, and useful context for mixin tooling such as IDE plugins.

    If the target member is contributed by an upstream mixin but the mixin is not on the classpath of the current project, using the fully- qualified name of the upstream mixin as the value() is a useful fallback, since developers reading the source code can still use the string value as a search term in their IDE or on Github.

    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element Description
      java.lang.Class<?> mixin
      If the target member is added by an upstream mixin, and the mixin in question is on the classpath, specify the mixin class here in order to provide useful context for the annotated member.
      java.lang.String value
      Description of this @Dynamic member.
    • Element Detail

      • value

        java.lang.String value
        Description of this @Dynamic member. See the notes above. Can be omitted if mixin() is specified instead.
        Returns:
        description of the member
        Default:
        ""
      • mixin

        java.lang.Class<?> mixin
        If the target member is added by an upstream mixin, and the mixin in question is on the classpath, specify the mixin class here in order to provide useful context for the annotated member.
        Returns:
        upstream mixin reference
        Default:
        void.class