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");
+            }
+        }
     }
 
 }

Reply via email to