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

Unable to serialize AtomicBoolean on Java 17 #308

Closed
basil opened this issue Sep 14, 2022 · 2 comments
Closed

Unable to serialize AtomicBoolean on Java 17 #308

basil opened this issue Sep 14, 2022 · 2 comments
Assignees
Milestone

Comments

@basil
Copy link
Contributor

basil commented Sep 14, 2022

Context

See jenkinsci/docker-plugin#905. When running Jenkins on Java 17 with X-Stream 1.4.19, we see:

java.lang.reflect.InaccessibleObjectException: Unable to make field private static final long java.util.concurrent.atomic.AtomicBoolean.serialVersionUID accessible: module java.base does not "opens java.util.concurrent.atomic" to unnamed module @be35cd9
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
	at com.thoughtworks.xstream.converters.reflection.FieldDictionary.buildDictionaryEntryForClass(FieldDictionary.java:176)
	at com.thoughtworks.xstream.converters.reflection.FieldDictionary.buildMap(FieldDictionary.java:142)
	at com.thoughtworks.xstream.converters.reflection.FieldDictionary.fieldsFor(FieldDictionary.java:80)
	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:167)
	at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:206)
	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:163)
	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:83)
	at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:283)
	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:270)
Caused: java.lang.RuntimeException: Failed to serialize io.jenkins.docker.DockerTransientNode#acceptingTasks for class io.jenkins.docker.DockerTransientNode
	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:274)
	at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:241)
	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:174)
	at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:226)
	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:163)
	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:44)
	at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:83)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
	at com.thoughtworks.xstream.XStream.marshal(XStream.java:1266)
	at com.thoughtworks.xstream.XStream.marshal(XStream.java:1255)
	at com.thoughtworks.xstream.XStream.toXML(XStream.java:1228)
	at hudson.XmlFile.write(XmlFile.java:213)

Steps to reproduce

Create xstream/src/test/com/thoughtworks/xstream/converters/extended/AtomicBooleanFieldsTest.java with

package com.thoughtworks.xstream.converters.extended;

import com.thoughtworks.acceptance.AbstractAcceptanceTest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

public class AtomicBooleanFieldsTest extends AbstractAcceptanceTest {

    public static class Musican {
        public String name;
        public String genre;
        public AtomicBoolean alive;

        public Musican(final String name, final String genre, final AtomicBoolean alive) {
            this.name = name;
            this.genre = genre;
            this.alive = alive;
        }
    }

    public void testAtomicBooleanFields() {
        final List<Musican> jazzIcons = new ArrayList<>();
        jazzIcons.add(new Musican("Miles Davis", "jazz", new AtomicBoolean(false)));
        jazzIcons.add(new Musican("Wynton Marsalis", "jazz", new AtomicBoolean(true)));

        xstream.alias("musician", Musican.class);

        final String expectedXml =
                "<list>\n"
                        + "  <musician>\n"
                        + "    <name>Miles Davis</name>\n"
                        + "    <genre>jazz</genre>\n"
                        + "    <alive>\n"
                        + "      <value>0</value>\n"
                        + "    </alive>\n"
                        + "  </musician>\n"
                        + "  <musician>\n"
                        + "    <name>Wynton Marsalis</name>\n"
                        + "    <genre>jazz</genre>\n"
                        + "    <alive>\n"
                        + "      <value>1</value>\n"
                        + "    </alive>\n"
                        + "  </musician>\n"
                        + "</list>";

        assertBothWays(jazzIcons, expectedXml);
    }
}

and run mvn clean verify -Dtest=com.thoughtworks.xstream.converters.extended.AtomicBooleanFieldsTest,com.thoughtworks.acceptance.BooleanFieldsTest -DfailIfNoTests=false on Java 17.

Expected results

Note: These are the actual results when running on Java 8 or Java 11.

The tests pass.

Actual results

AtomicBooleanFieldsTest fails with the same error from the production use case:

[ERROR] testAtomicBooleanFields(com.thoughtworks.xstream.converters.extended.AtomicBooleanFieldsTest)  Time elapsed: 0.001 s  <<< ERROR!
com.thoughtworks.xstream.converters.ConversionException: 
No converter available
---- Debugging information ----
message             : No converter available
type                : java.util.concurrent.atomic.AtomicBoolean
converter           : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
message[1]          : Unable to make field private static final long java.util.concurrent.atomic.AtomicBoolean.serialVersionUID accessible: module java.base does not "opens java.util.concurrent.atomic" to unnamed module @3bd94634
-------------------------------
	at com.thoughtworks.xstream.core.DefaultConverterLookup.lookupConverterForType(DefaultConverterLookup.java:78)
	at com.thoughtworks.xstream.XStream$1.lookupConverterForType(XStream.java:542)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:50)
	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:269)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:173)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:262)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:92)
	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:44)
	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:93)
	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeBareItem(AbstractCollectionConverter.java:98)
	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:70)
	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeCompleteItem(AbstractCollectionConverter.java:85)
	at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:78)
	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:44)
	at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:81)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:41)
	at com.thoughtworks.xstream.XStream.marshal(XStream.java:1197)
	at com.thoughtworks.xstream.XStream.marshal(XStream.java:1186)
	at com.thoughtworks.xstream.XStream.toXML(XStream.java:1158)
	at com.thoughtworks.xstream.XStream.toXML(XStream.java:1144)
	at com.thoughtworks.acceptance.AbstractAcceptanceTest.toXML(AbstractAcceptanceTest.java:173)
	at com.thoughtworks.acceptance.AbstractAcceptanceTest.assertBothWays(AbstractAcceptanceTest.java:98)
	at com.thoughtworks.xstream.converters.extended.AtomicBooleanFieldsTest.testAtomicBooleanFields(AtomicBooleanFieldsTest.java:47)
@joehni
Copy link
Member

joehni commented Nov 15, 2022

You have to open the package for XStream to use reflection.

@basil
Copy link
Contributor Author

basil commented Nov 15, 2022

@joehni joehni added the question label Nov 14, 2022

This is not a question, @joehni. As demonstrated in #262 (comment) I already know that you have to open the package for XStream to use reflection. But I think this use case should be supported by X-Stream without having to resort to reflection or any custom --add-opens directives. That is what I have implemented in #309 (and indeed, already delivered to Jenkins users in jenkinsci/jenkins#7270).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants