Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
I've found a way to set the private field without exposing it or giving it a setter: Reflection. Using external event listeners, I can get ahold of the File object. Then, inside the beforeUnmarsha...
Answer
#1: Initial revision
I've found a way to set the private field without exposing it or giving it a setter: [Reflection](http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html). Using external event listeners, I can get ahold of the `File` object. Then, inside the `beforeUnmarshal` method, and after checking that I got the correct object, I use reflection to get the private field, and with the `setAccessible` method, I can now control when I get access to the field _using reflection only_. After lifting the access checks, it's only a matter of editing the value via `set`ting it, and reinstating the checks after that. # Relevant changes The following snippet includes the relevant changes: unmarshallerObj.setListener(new Unmarshaller.Listener() { @Override public void beforeUnmarshal(Object target, Object parent) { if (!(target instanceof MarshalMe)) return; MarshalMe me = (MarshalMe) target; try { Field meBackingFile = MarshalMe.class.getDeclaredField("backingFile"); meBackingFile.setAccessible(true); meBackingFile.set(me, xml); meBackingFile.setAccessible(false); } catch (NoSuchFieldException | IllegalAccessException ex) { // Intentionally left blank. } } }); # Including the edit in the sample program Edit the file `JAXBDemo.java` by adding the following code: // Add to the import section import java.lang.reflect.Field; // Under this function public static MarshalMe readXML(File xml) { MarshalMe me = null; try { JAXBContext contextObj = JAXBContext.newInstance(MarshalMe.class); Unmarshaller unmarshallerObj = contextObj.createUnmarshaller(); /* Add this code vvv */ unmarshallerObj.setListener(new Unmarshaller.Listener() { @Override public void beforeUnmarshal(Object target, Object parent) { if (!(target instanceof MarshalMe)) return; MarshalMe me = (MarshalMe) target; try { Field meBackingFile = MarshalMe.class.getDeclaredField("backingFile"); meBackingFile.setAccessible(true); meBackingFile.set(me, xml); meBackingFile.setAccessible(false); } catch (NoSuchFieldException | IllegalAccessException ex) { // Intentionally left blank. } } }); /* Add this code ^^^ */ me = (MarshalMe) unmarshallerObj.unmarshal(xml); } catch (JAXBException jaxbe) { jaxbe.printStackTrace(); } return me; } After adding the `import` and the code between the `/* Add this code */` lines, running the program again now outputs: dummy.hai me.xml as expected.