dimanche 18 août 2019

Changing unboxed of primitive typed (e.g. long, not Long) by reflection

I'm trying to change a value of following variable by java reflection: public final static Long DEFAULT_TIMEOUT = 100000L;

There is no exception or errors but value remains.

JDK: Oracle 8 JDK.

There is simple class to reproduce the problem.

package testpackage;

public class LibraryClass {
  // Changing long to Long fixes the issue
  public final static long DEFAULT_TIMEOUT = 100000L; 
}

Simple test-case. I'm using org.apache.commons.lang3.reflect.FieldUtils to remove finale/making the field accessible. I also tried to work with FieldUtils/and class object (because of staticness of the filed= to change value. But every approach failed.

public class FinalStaticVariableChangeCheck {

  private static Logger LOG = LoggerFactory.getLogger(FinalStaticVariableChangeCheck.class);

  @Test
  public void testLChangingLibraryClass()
      throws NoSuchFieldException, IllegalAccessException, InterruptedException, InstantiationException {
    LibraryClass sampleClass = new LibraryClass();
    final Class<?> clazz;
    final Field    field;

    clazz = sampleClass.getClass();
    field = clazz.getDeclaredField("DEFAULT_TIMEOUT");

    FieldUtils.removeFinalModifier(field, true);
    field.set(sampleClass, 1234L);

    LOG.info("Output: " + sampleClass.DEFAULT_TIMEOUT);
    Assert.assertEquals(1234L, sampleClass.DEFAULT_TIMEOUT);


  }

}

The output is 100000.

However, by changing public final static long DEFAULT_TIMEOUT = 100000L; to public final static Long DEFAULT_TIMEOUT = 100000L; solves the problem

Expected: output 1234 and the test-case is not failing.

The issue seems to be related to the unboxed type. Any Ideas how to workaround the problem? Unfortunately the code resides in an external library and my PRs to solve the problem in more elegant way are currently "ignored".





Aucun commentaire:

Enregistrer un commentaire