The test will fail on Java 14 and above when it comes out. We do not want to update this method with each new release. We need a "if java is >= 12" test IMO.
Gary On Wed, Apr 10, 2019, 14:46 <chtom...@apache.org> wrote: > This is an automated email from the ASF dual-hosted git repository. > > chtompki pushed a commit to branch master > in repository https://gitbox.apache.org/repos/asf/commons-lang.git > > > The following commit(s) were added to refs/heads/master by this push: > new 5f7812e LANG-1447: java 12 final modifier is no longer mutable > 5f7812e is described below > > commit 5f7812ee1c2f583e1a1902c96b5b519e86699250 > Author: Tompkins <chtom...@apache.org> > AuthorDate: Wed Apr 10 14:46:12 2019 -0400 > > LANG-1447: java 12 final modifier is no longer mutable > --- > src/changes/changes.xml | 2 + > .../apache/commons/lang3/reflect/FieldUtils.java | 13 ++++- > .../commons/lang3/reflect/FieldUtilsTest.java | 59 > ++++++++++++++++------ > 3 files changed, 57 insertions(+), 17 deletions(-) > > diff --git a/src/changes/changes.xml b/src/changes/changes.xml > index 6138bd4..4668d5b 100644 > --- a/src/changes/changes.xml > +++ b/src/changes/changes.xml > @@ -46,6 +46,8 @@ The <action> type attribute can be add,update,fix,remove. > <body> > > <release version="3.9" date="????-??-??" description="??"> > + <action issue="LANG-1447" type="update" > dev="chtompki">FieldUtils.removeFinalModifier(Field, boolean), in java 12 > + throw exception because the final modifier is no longer > mutable.</action> > <action issue="LANG-1446" type="add" dev="chtompki">Switch coverage > from cobertura to jacoco.</action> > <action issue="LANG-1442" type="add" dev="chtompki">Javadoc pointing > to Commons RNG.</action> > <action issue="LANG-1416" type="update" dev="britter">Add more > SystemUtils.IS_JAVA_XX variants.</action> > 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 68146b1..99148a8 100644 > --- a/src/main/java/org/apache/commons/lang3/reflect/FieldUtils.java > +++ b/src/main/java/org/apache/commons/lang3/reflect/FieldUtils.java > @@ -18,6 +18,7 @@ package org.apache.commons.lang3.reflect; > > import org.apache.commons.lang3.ClassUtils; > 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 +713,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 > <code>final</code> 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 +739,13 @@ public class FieldUtils { > } > } > } catch (final NoSuchFieldException | IllegalAccessException > ignored) { > - // The field class contains always a modifiers field > + if (SystemUtils.IS_JAVA_12 || SystemUtils.IS_JAVA_13) { > + 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 8217a89..839e89d 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,7 @@ package org.apache.commons.lang3.reflect; > > import org.apache.commons.lang3.ArrayUtils; > > +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 +44,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 +995,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.IS_JAVA_12 && !SystemUtils.IS_JAVA_13) { > + assertFalse(Modifier.isFinal(field.getModifiers())); > + assertFalse(field.isAccessible()); > + } > } > > @Test > @@ -1004,10 +1007,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.IS_JAVA_12 && !SystemUtils.IS_JAVA_13) { > + assertFalse(Modifier.isFinal(field.getModifiers())); > + assertFalse(field.isAccessible()); > + } > } > > @Test > @@ -1015,10 +1019,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.IS_JAVA_12 && !SystemUtils.IS_JAVA_13) { > + assertTrue(Modifier.isFinal(field.getModifiers())); > + assertFalse(field.isAccessible()); > + } > } > > @Test > @@ -1026,10 +1031,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.IS_JAVA_12 && !SystemUtils.IS_JAVA_13) { > + assertTrue(Modifier.isFinal(field.getModifiers())); > + assertFalse(field.isAccessible()); > + } > + } > + > + /** > + * Read the <code>@deprecated</code> 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.IS_JAVA_12 || SystemUtils.IS_JAVA_13) { > + assertTrue(exception.getCause() instanceof > NoSuchFieldException); > + } else { > + fail("No exception should be thrown for java prior to > 12.0"); > + } > + } > } > > } > >