这是indexloc提供的服务,不要输入任何密码
Skip to content

AnnotationBundleKey equality fails for Parameter Annotations #111

@jvmccarthy

Description

@jvmccarthy

First post here, so let me thank you for sharing Jackson with us all. It's a great library and a wonderful asset to the Java community. 👍

AnnotationBundleKey._equals uses == instead of .equals() to compare annotations. This approach does not work with method parameter annotations, which are not cached and not guaranteed to be the same. I was going to submit a PR using .equals(), but it looks like this behavior is intentional from a comment in the test. I'm not sure if this will break anything else but wanted to raise it to your attention.

This issue was discovered because AnnotationBundleKey is used by RestEasy as part of a key to a ConcurrentHashMap in ResteasyJackson2Provider. Because RestEasy used this class with parameter annotations, object equality was failing with the same hash code, leading to lock contention and performance issues. I've submitted a PR with RestEasy to fix the issue there but wanted you to be aware as well.

Here's a snippet which shows the issue.

import com.fasterxml.jackson.jaxrs.cfg.AnnotationBundleKey;

import javax.annotation.Nonnull;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationEqualitySnippet {
  @Nonnull
  public void annotatedMethod(@Nonnull String a) {}

  public static void main(String[] args) throws Exception {
    Method method = AnnotationEqualitySnippet.class.getMethod("annotatedMethod", String.class);

    Annotation[] ann1 = method.getParameterAnnotations()[0];
    Annotation[] ann2 = method.getParameterAnnotations()[0];
    AnnotationBundleKey key1 = new AnnotationBundleKey(ann1, Object.class);
    AnnotationBundleKey key2 = new AnnotationBundleKey(ann2, Object.class);

    System.out.println(key1.equals(key2)); // outputs "false" ("true" expected)
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions