Merge branch 'master' of github.com:apache/commons-lang into 3.9

This commit is contained in:
Rob Tompkins 2019-04-10 15:29:23 -04:00
commit 838d7ebefb
5 changed files with 61 additions and 19 deletions

View File

@ -24,7 +24,6 @@ jdk:
matrix: matrix:
allow_failures: allow_failures:
- jdk: openjdk12
- jdk: openjdk-ea - jdk: openjdk-ea
script: script:

View File

@ -606,7 +606,8 @@
<jmh.version>1.21</jmh.version> <jmh.version>1.21</jmh.version>
<uberjar.name>benchmarks</uberjar.name> <uberjar.name>benchmarks</uberjar.name>
<commons.jacoco.version>0.8.2</commons.jacoco.version> <commons.jacoco.version>0.8.3</commons.jacoco.version>
<commons.surefire.version>3.0.0-M3</commons.surefire.version>
<!-- generate report even if there are binary incompatible changes --> <!-- generate report even if there are binary incompatible changes -->
<commons.japicmp.breakBuildOnBinaryIncompatibleModifications>false</commons.japicmp.breakBuildOnBinaryIncompatibleModifications> <commons.japicmp.breakBuildOnBinaryIncompatibleModifications>false</commons.japicmp.breakBuildOnBinaryIncompatibleModifications>

View File

@ -46,6 +46,8 @@ The <action> type attribute can be add,update,fix,remove.
<body> <body>
<release version="3.9" date="2019-04-09" description="New features and bug fixes. Requires Java 8, supports Java 9, 10, 11"> <release version="3.9" date="2019-04-09" description="New features and bug fixes. Requires Java 8, supports Java 9, 10, 11">
<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-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-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> <action issue="LANG-1416" type="update" dev="britter">Add more SystemUtils.IS_JAVA_XX variants.</action>

View File

@ -17,7 +17,9 @@
package org.apache.commons.lang3.reflect; package org.apache.commons.lang3.reflect;
import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.JavaVersion;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
@ -712,8 +714,12 @@ public class FieldUtils {
* match {@code public} fields. * match {@code public} fields.
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the field is {@code null} * 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 * @since 3.3
*/ */
@Deprecated
public static void removeFinalModifier(final Field field, final boolean forceAccess) { public static void removeFinalModifier(final Field field, final boolean forceAccess) {
Validate.isTrue(field != null, "The field must not be null"); Validate.isTrue(field != null, "The field must not be null");
@ -734,7 +740,13 @@ public class FieldUtils {
} }
} }
} catch (final NoSuchFieldException | IllegalAccessException ignored) { } 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.
} }
} }

View File

@ -18,6 +18,8 @@ package org.apache.commons.lang3.reflect;
import org.apache.commons.lang3.ArrayUtils; 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.Ambig;
import org.apache.commons.lang3.reflect.testbed.Annotated; import org.apache.commons.lang3.reflect.testbed.Annotated;
import org.apache.commons.lang3.reflect.testbed.Foo; 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.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue;
/** /**
@ -993,43 +996,68 @@ public class FieldUtilsTest {
final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2"); final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
assertFalse(field.isAccessible()); assertFalse(field.isAccessible());
assertTrue(Modifier.isFinal(field.getModifiers())); assertTrue(Modifier.isFinal(field.getModifiers()));
FieldUtils.removeFinalModifier(field); callRemoveFinalModifierCheckForException(field, true);
// The field is no longer final if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
assertFalse(Modifier.isFinal(field.getModifiers())); assertFalse(Modifier.isFinal(field.getModifiers()));
assertFalse(field.isAccessible()); assertFalse(field.isAccessible());
} }
}
@Test @Test
public void testRemoveFinalModifierWithAccess() throws Exception { public void testRemoveFinalModifierWithAccess() throws Exception {
final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2"); final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
assertFalse(field.isAccessible()); assertFalse(field.isAccessible());
assertTrue(Modifier.isFinal(field.getModifiers())); assertTrue(Modifier.isFinal(field.getModifiers()));
FieldUtils.removeFinalModifier(field, true); callRemoveFinalModifierCheckForException(field, true);
// The field is no longer final if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
assertFalse(Modifier.isFinal(field.getModifiers())); assertFalse(Modifier.isFinal(field.getModifiers()));
assertFalse(field.isAccessible()); assertFalse(field.isAccessible());
} }
}
@Test @Test
public void testRemoveFinalModifierWithoutAccess() throws Exception { public void testRemoveFinalModifierWithoutAccess() throws Exception {
final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2"); final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
assertFalse(field.isAccessible()); assertFalse(field.isAccessible());
assertTrue(Modifier.isFinal(field.getModifiers())); assertTrue(Modifier.isFinal(field.getModifiers()));
FieldUtils.removeFinalModifier(field, false); callRemoveFinalModifierCheckForException(field, false);
// The field is STILL final because we did not force access if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
assertTrue(Modifier.isFinal(field.getModifiers())); assertTrue(Modifier.isFinal(field.getModifiers()));
assertFalse(field.isAccessible()); assertFalse(field.isAccessible());
} }
}
@Test @Test
public void testRemoveFinalModifierAccessNotNeeded() throws Exception { public void testRemoveFinalModifierAccessNotNeeded() throws Exception {
final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PACKAGE"); final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PACKAGE");
assertFalse(field.isAccessible()); assertFalse(field.isAccessible());
assertTrue(Modifier.isFinal(field.getModifiers())); assertTrue(Modifier.isFinal(field.getModifiers()));
FieldUtils.removeFinalModifier(field, false); callRemoveFinalModifierCheckForException(field, false);
// The field is no longer final AND we did not need to force access if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
assertTrue(Modifier.isFinal(field.getModifiers())); assertTrue(Modifier.isFinal(field.getModifiers()));
assertFalse(field.isAccessible()); 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.isJavaVersionAtLeast(JavaVersion.JAVA_12)) {
assertTrue(exception.getCause() instanceof NoSuchFieldException);
} else {
fail("No exception should be thrown for java prior to 12.0");
}
}
}
} }