diff --git a/.travis.yml b/.travis.yml
index 4472d838d..8e71802d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,7 +24,6 @@ jdk:
matrix:
allow_failures:
- - jdk: openjdk12
- jdk: openjdk-ea
script:
diff --git a/pom.xml b/pom.xml
index d44b88d91..15dfe15a4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -606,7 +606,8 @@
1.21
benchmarks
- 0.8.2
+ 0.8.3
+ 3.0.0-M3
false
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index dddaaa7ee..aef34ab6d 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -46,6 +46,8 @@ The type attribute can be add,update,fix,remove.
+ FieldUtils.removeFinalModifier(Field, boolean), in java 12
+ throw exception because the final modifier is no longer mutable.
Switch coverage from cobertura to jacoco.
Javadoc pointing to Commons RNG.
Add more SystemUtils.IS_JAVA_XX variants.
diff --git a/src/main/java/org/apache/commons/lang3/reflect/FieldUtils.java b/src/main/java/org/apache/commons/lang3/reflect/FieldUtils.java
index 68146b165..08fcdc2b4 100644
--- a/src/main/java/org/apache/commons/lang3/reflect/FieldUtils.java
+++ b/src/main/java/org/apache/commons/lang3/reflect/FieldUtils.java
@@ -17,7 +17,9 @@
package org.apache.commons.lang3.reflect;
import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.JavaVersion;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang3.Validate;
import java.lang.annotation.Annotation;
@@ -712,8 +714,12 @@ public class FieldUtils {
* match {@code public} fields.
* @throws IllegalArgumentException
* if the field is {@code null}
+ * @deprecated As of java 12.0, we can no longer drop the final
modifier, thus
+ * rendering this method obsolete. The JDK discussion about this change can be found
+ * here: http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-November/056486.html
* @since 3.3
*/
+ @Deprecated
public static void removeFinalModifier(final Field field, final boolean forceAccess) {
Validate.isTrue(field != null, "The field must not be null");
@@ -734,7 +740,13 @@ public class FieldUtils {
}
}
} catch (final NoSuchFieldException | IllegalAccessException ignored) {
- // The field class contains always a modifiers field
+ if (SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_12)) {
+ throw new UnsupportedOperationException(
+ "In java 12+ final cannot be removed.",
+ ignored
+ );
+ }
+ // else no exception is thrown because we can modify final.
}
}
diff --git a/src/test/java/org/apache/commons/lang3/reflect/FieldUtilsTest.java b/src/test/java/org/apache/commons/lang3/reflect/FieldUtilsTest.java
index 8217a8992..39239efce 100644
--- a/src/test/java/org/apache/commons/lang3/reflect/FieldUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/reflect/FieldUtilsTest.java
@@ -18,6 +18,8 @@ package org.apache.commons.lang3.reflect;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.JavaVersion;
+import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang3.reflect.testbed.Ambig;
import org.apache.commons.lang3.reflect.testbed.Annotated;
import org.apache.commons.lang3.reflect.testbed.Foo;
@@ -43,6 +45,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
/**
@@ -993,10 +996,11 @@ public class FieldUtilsTest {
final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
assertFalse(field.isAccessible());
assertTrue(Modifier.isFinal(field.getModifiers()));
- FieldUtils.removeFinalModifier(field);
- // The field is no longer final
- assertFalse(Modifier.isFinal(field.getModifiers()));
- assertFalse(field.isAccessible());
+ callRemoveFinalModifierCheckForException(field, true);
+ if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
+ assertFalse(Modifier.isFinal(field.getModifiers()));
+ assertFalse(field.isAccessible());
+ }
}
@Test
@@ -1004,10 +1008,11 @@ public class FieldUtilsTest {
final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
assertFalse(field.isAccessible());
assertTrue(Modifier.isFinal(field.getModifiers()));
- FieldUtils.removeFinalModifier(field, true);
- // The field is no longer final
- assertFalse(Modifier.isFinal(field.getModifiers()));
- assertFalse(field.isAccessible());
+ callRemoveFinalModifierCheckForException(field, true);
+ if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
+ assertFalse(Modifier.isFinal(field.getModifiers()));
+ assertFalse(field.isAccessible());
+ }
}
@Test
@@ -1015,10 +1020,11 @@ public class FieldUtilsTest {
final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
assertFalse(field.isAccessible());
assertTrue(Modifier.isFinal(field.getModifiers()));
- FieldUtils.removeFinalModifier(field, false);
- // The field is STILL final because we did not force access
- assertTrue(Modifier.isFinal(field.getModifiers()));
- assertFalse(field.isAccessible());
+ callRemoveFinalModifierCheckForException(field, false);
+ if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
+ assertTrue(Modifier.isFinal(field.getModifiers()));
+ assertFalse(field.isAccessible());
+ }
}
@Test
@@ -1026,10 +1032,32 @@ public class FieldUtilsTest {
final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PACKAGE");
assertFalse(field.isAccessible());
assertTrue(Modifier.isFinal(field.getModifiers()));
- FieldUtils.removeFinalModifier(field, false);
- // The field is no longer final AND we did not need to force access
- assertTrue(Modifier.isFinal(field.getModifiers()));
- assertFalse(field.isAccessible());
+ callRemoveFinalModifierCheckForException(field, false);
+ if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
+ assertTrue(Modifier.isFinal(field.getModifiers()));
+ assertFalse(field.isAccessible());
+ }
+ }
+
+ /**
+ * Read the @deprecated
notice on
+ * {@link FieldUtils#removeFinalModifier(Field, boolean)}.
+ *
+ * @param field {@link Field} to be curried into
+ * {@link FieldUtils#removeFinalModifier(Field, boolean)}.
+ * @param forceAccess {@link Boolean} to be curried into
+ * {@link FieldUtils#removeFinalModifier(Field, boolean)}.
+ */
+ private void callRemoveFinalModifierCheckForException(Field field, Boolean forceAccess) {
+ try {
+ FieldUtils.removeFinalModifier(field, forceAccess);
+ } catch (UnsupportedOperationException exception) {
+ if(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_12)) {
+ assertTrue(exception.getCause() instanceof NoSuchFieldException);
+ } else {
+ fail("No exception should be thrown for java prior to 12.0");
+ }
+ }
}
}