Specifically, I’m trying to create a unit test for a method which requires uses File.separatorChar to build paths on windows and unix. The code must run on both platforms, and yet I get errors with JUnit when I attempt to change this static final field.
Anyone have any idea what’s going on?
Field field = java.io.File.class.getDeclaredField( "separatorChar" );
field.setAccessible(true);
field.setChar(java.io.File.class,'/');
When I do this, I get
IllegalAccessException: Can not set static final char field java.io.File.separatorChar to java.lang.Character
Thoughts?
From the documentation for
Field.set:So at first it seems that you are out of luck, since
File.separatorCharisstatic. Surprisingly, there is a way to get around this: simply make thestaticfield no longerfinalthrough reflection.I adapted this solution from javaspecialist.eu:
I’ve tested it and it works:
Do exercise extreme caution with this technique. Devastating consequences aside, the following actually works:
Important update: the above solution does not work in all cases. If the field is made accessible and read through Reflection before it gets reset, an
IllegalAccessExceptionis thrown. It fails because the Reflection API creates internalFieldAccessorobjects which are cached and reused (see the java.lang.reflect.Field#acquireFieldAccessor(boolean) implementation).Example test code which fails: