Description:
|
From the mailing list:
Hi,
lately I’ve been spending some time trying to figure out why users keep on reporting,
every now and then, about CatalogInfo subclasses throwing NullPointerException
related to the catalog field in them being null.
Now, generally speaking, we know two things about that field:
- it gets populated as we create new objects
- the field is however not serializable
This means that if a CatalogInfo object holding a reference to the catalog gets serialized
and then deserialized, it won’t have a reference to the catalog anymore.
We do compensate for that in some places, like in LayerModel for example, calling
CatalogBuilder.attach(LayerInfo).
However, there are several places which are not doing that, and keeping tabs with
everything, with a moving target such as GeoServer, with new people going in
all the time, it’s not a winning move (imho).
Actually I’ve found a simple way to replicate one of the NPE issues:
- open topp:states
- in a separate tab, go to layers, new, republish topp:states as topp:states2,
but don’t save
- go back into topp:states, change tabs a bit, save
- go back to topp:states2, save
- go previewing topp:states2, ka-blam, NPE while the StyleInfo attached to that
layer tries to fetch the SLD
Why is this happening? It happens because the Wicket state is managed server side,
and if you are trying to use the same session with separate pages it will eventually
serialize the state of the other page in disk.
When it needs it, it will deserialize it, and that’s where the problem happens,
as the de-serialized CatalogInfo objects will miss their reference to Catalog.
They get saved that way, and when you try to use them, boom.
Now, the GUI never uses the CatalogInfo directly, is has references through the ModificationProxy,
so I’ve tried a simple patch to reattach them as they are de-serialized, by adding a readResolve
to ModificationProxy (see attachment).
That seems to do the trick, no more NPE, however I’m not so sure it’s the real solution.
The thing is, the de-serialized object is still a copy of the CatalogInfo object the catalog
is maintaining, the information has been duplicated: what I’m concerned about is that,
modifying one, the other will not be touched.
An alternative solution may be not to restore the catalog reference, but to replace
the proxied object (the proxyObject field in ModificationProxy) with a reference to
the actual bean managed by the catalog.
This would require us to save in ModificationProxy not only the proxyObject, but also
the interface it was proxied for, so that we can call:
public <T extends CatalogInfo> T get(Class<T> type, Filter filter)
with, I guess, a filter matching the id of the object that we serialized.
Opinions?
This is something I’d really like to have fixed by 2.3, but it’s not the end of the world
if we don’t: after all, this bug has been in GeoServer since 2.0, that is, for well over 2 years.
The above issue explains several problems that have been reported in Jira with NPE being thrown by objects having a null reference to the Catalog.
|