Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ComponentModel writeExternal does not support private fields #914

Open
Joshua-Barclay opened this issue Sep 13, 2016 · 3 comments
Open

ComponentModel writeExternal does not support private fields #914

Joshua-Barclay opened this issue Sep 13, 2016 · 3 comments
Assignees
Labels

Comments

@Joshua-Barclay
Copy link
Contributor

Joshua-Barclay commented Sep 13, 2016

Serializing ComponentModel can have issues due to the writeExternal method.

public class ComponentModel implements WebModel, Externalizable 

       @Override
       public void writeExternal(final ObjectOutput out) throws IOException {
              Field[] fields = getFields(this);

              for (Field field : fields) {
                     try {
                           if (sharedModel == null) {
                                  // Support serialization of the static model,
                                  // even though this should not occur.
                                  Object value = field.get(this);
                                  out.writeObject(value);
                           } else if (unsetFields != null && unsetFields.contains(field)) {
                                  // Support the unlikely case being deserialized/serialized
                                  // in short succession without the shared model being set.
                                  out.writeObject(NoOverride.INSTANCE);
                           } else {
                                  Object sharedValue = field.get(sharedModel);
                                  Object value = field.get(this);
...

The field.get throws java.lang.IllegalArgumentException: Possible if it is accessing a private field. Should we be calling field.setAccessible(true) first?

The exception is:

java.lang.IllegalArgumentException: Can not set f.q.c.n.Class field f.q.c.n.Class$Model.formShell to com.github.bordertech.wcomponents.WPanel$PanelModel
       at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:176)
       at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:180)
       at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:67)
       at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:48)
       at java.lang.reflect.Field.get(Field.java:391)
@ghost ghost added the bug label Sep 13, 2016
@ghost ghost added this to the V2 milestone Oct 11, 2016
@jonathanaustin jonathanaustin self-assigned this Jul 17, 2018
@ghost ghost added this to To do in API clean up Jul 30, 2018
@ghost ghost removed this from To do in API clean up Jul 30, 2018
@kandula-aswin
Copy link
Member

Added a Unit test and executed using Java 8, but couldn't reproduce the exception
kandula-aswin/wcomponents@5e97ea0

Is the test correct?

@ghost
Copy link

ghost commented Mar 5, 2019

@jonathanaustin could you please take a look at the test @kandula-aswin created?

@kandula-aswin
Copy link
Member

Currently writeExternal excludes ComponentModel's static and transient fields. So unsetFields field is excluded from serialisation.

But when transient fields are included, this test fails with a different error:

java.io.NotSerializableException: java.lang.reflect.Field
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1378)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at com.github.bordertech.wcomponents.ComponentModel.writeExternal(ComponentModel.java:747)
	at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1459)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1430)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at com.github.bordertech.wcomponents.ComponentModel.writeExternal(ComponentModel.java:759)
	at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1459)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1430)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at com.github.bordertech.wcomponents.ComponentModel_Test.testWriteExternal(ComponentModel_Test.java:69)

@ghost ghost removed this from the Next major version milestone Jul 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants