Inner class throwing a "no-argument constructor not found" exception, when it has a no-argument constructor

I have declared an inner class, which has a no-argument constructor, within another serializable class that also has a no-argument constructor, as follows:

@Serializable
public class Path extends LinkedList<Spot>

When I go to register it I get a “no-argument constructor not found in” the inner class error. Am I missing something or is this a bug?

To clarify, both the inner and outer classes have no-argument constructors. The inner one is declared public, just in care that was the problem (it’s not).

I suspect that it has something to do with the fact that it extends LinkedList.

For serialization you need to have at least the “no-argument constructor”! Declare it and try it again.

Sorry if I was unclear. The class does have a no-argument constructor. I mentioned that in the thread title, but forgot to state it explicitly in the post.

Non-static inner classes do not really have a no-argument constructor because they can’t really be constructed without the outer instance.

To make inner classes compatible with serialization they MUST BE static. Else, SM has no idea which instance to instantiate your child for.

1 Like

But before I go and try it, I should be able to overcome this with a custom serializer for the enclosing class, correct?

You cannot instantiate a non-static inner class without the outer instance. You probably want a STATIC inner class. Just add the STATIC keyword to your inner class and things will probably work if you add STATIC to your inner class definition.

Only STATIC inner classes make sense if you are going to have an inner class because only STATIC inner classes can be instantiated without the outer class.

Try it. In some Java code in a different class try to instantiate your non-static inner class. You can’t easily do it without some weird syntax and only after you’ve instantiated the outer class.

Sure, but I’m not trying to instantiate the inner class without the outer class. This whole problem’s coming up when the outer class is being serialized.

Seems like a case that should be covered, but, whatever, I’ll just do a workaround.

But the Serializer IS. That’s the whole point.

public class Outer {
    public class Inner {
    }
}

Now. Instantiate the inner class.

Inner i = new Inner();

Nope. Can’t do that. What’s SpiderMonkey’s serializer supposed to do then to create the object?

It’s supposed to note that the inner object being sent is being sent as part of its outer object and instantiate it that way. At least, that’s what I would think it should do in these situations.

More specifically, when a class is registered, the register should note what class it’s an inner class of, if any, and then when the deserializer is recursively deserializing the fields of an object, it should pass the fields that are inner classes to a special field deserializer that also takes the outer class as an argument.

You could be even more robust than that, but that’s a start.

When I am done with this project, I might try and implement that as a patch, along with an EnumSet and EnumMap serializer, and a fix for circular object references. But nobody should hold their breath.

EDIT: And handling of nulls.

If you don’t really care about the size of your messages (and it seems like efficiency is not really a priority in your networking design) then you could just use standard Java serialization, too.

1 Like