Skip to content

Commit 37d6965

Browse files
committed
fix review comments
1 parent de8c4e2 commit 37d6965

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

src/main/java/org/apache/commons/lang3/AnnotationUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,9 @@ public static boolean equals(final Annotation a1, final Annotation a2) {
212212
for (final Method m : type1.getDeclaredMethods()) {
213213
if (m.getParameterTypes().length == 0
214214
&& isValidAnnotationMemberType(m.getReturnType())) {
215-
m.setAccessible(true);
215+
if (!m.isAccessible()) {
216+
m.setAccessible(true);
217+
}
216218
final Object v1 = m.invoke(a1);
217219
final Object v2 = m.invoke(a2);
218220
if (!memberEquals(m.getReturnType(), v1, v2)) {

src/test/java/org/apache/commons/lang3/external/AnnotationEqualsTest.java

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,54 @@
1717
package org.apache.commons.lang3.external;
1818

1919
import org.apache.commons.lang3.AnnotationUtils;
20-
import org.junit.jupiter.api.Assertions;
2120
import org.junit.jupiter.api.Test;
2221

22+
import java.lang.annotation.Annotation;
2323
import java.lang.annotation.Retention;
2424
import java.lang.annotation.RetentionPolicy;
25+
import java.lang.reflect.InvocationTargetException;
2526

26-
// CAUTION: in order to reproduce https://issues.apache.org/jira/browse/LANG-1815,
27-
// this test MUST be located OUTSIDE org.apache.commons.lang3 package.
28-
// Do NOT move it to the org.apache.commons.lang3 package!
27+
import static org.junit.jupiter.api.Assertions.assertEquals;
28+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
29+
import static org.junit.jupiter.api.Assertions.assertThrows;
30+
import static org.junit.jupiter.api.Assertions.assertTrue;
31+
32+
/**
33+
* Regression test for <a href="https://issues.apache.org/jira/browse/LANG-1815">LANG-1815</a>.
34+
* <p>
35+
* Verifies that {@code AnnotationUtils.equals(Annotation, Annotation)} treats two equal
36+
* package-private annotations as equal, and also wraps a possible ReflectiveOperationException.
37+
* </p>
38+
*
39+
* <h2>Important</h2>
40+
* <p>
41+
* This test relies on reflective access rules that differ depending on the caller's package.
42+
* To reproduce the original bug, this class <strong>must remain outside</strong> the
43+
* {@code org.apache.commons.lang3} package.
44+
* </p>
45+
* <p>
46+
* Do <strong>not</strong> move this class into {@code org.apache.commons.lang3},
47+
* otherwise the test may no longer exercise the failing scenario from LANG-1815.
48+
* </p>
49+
*/
2950
public class AnnotationEqualsTest {
3051
@Retention(RetentionPolicy.RUNTIME)
3152
@interface Tag {
3253
String value();
3354
}
3455

56+
static class ThrowingTag implements Tag {
57+
@Override
58+
public String value() {
59+
throw new IllegalArgumentException("boom");
60+
}
61+
62+
@Override
63+
public Class<? extends Annotation> annotationType() {
64+
return Tag.class;
65+
}
66+
}
67+
3568
@Tag("value")
3669
private final Object a = new Object();
3770
@Tag("value")
@@ -41,6 +74,19 @@ public class AnnotationEqualsTest {
4174
void equalsWorksOnPackagePrivateAnnotations() throws Exception {
4275
Tag tagA = getClass().getDeclaredField("a").getAnnotation(Tag.class);
4376
Tag tagB = getClass().getDeclaredField("b").getAnnotation(Tag.class);
44-
Assertions.assertTrue(AnnotationUtils.equals(tagA, tagB));
77+
assertTrue(AnnotationUtils.equals(tagA, tagB));
4578
}
79+
80+
@Test
81+
void equalsWrapsReflectiveOperationException() throws Exception {
82+
// Proxy annotation instances: calling Tag#value() will throw at runtime
83+
final Tag tagA = new ThrowingTag();
84+
final Tag tagB = getClass().getDeclaredField("b").getAnnotation(Tag.class);
85+
86+
final IllegalStateException ex =
87+
assertThrows(IllegalStateException.class, () -> AnnotationUtils.equals(tagA, tagB));
88+
assertInstanceOf(InvocationTargetException.class, ex.getCause());
89+
assertEquals("boom", ((InvocationTargetException) ex.getCause()).getTargetException().getMessage());
90+
}
91+
4692
}

0 commit comments

Comments
 (0)