While ClpSerializer translates *Impl classes from the same package into *Clp objects properly, (already translated) *Clp objects from other packages (portlets) are simply passed as they are. This can cause ClassCastException.
Let's assume that we have 3 portlets: Foo, Bar & Baz (attached to this LPS). Foo exposes a public service that returns FooImpl objects. Bar has another service that wraps Foo's one. Finally, Baz portlet calls Bar's service to get some Foo instances. Although the service call itself succeeds, assigning the return value fails.
Despite they are called the same, the classes of the return value and the assigned variable are actually different. This is due to the different class loaders used by different portlets.
FooImpl objects originate from the foo context. After translation took place, Bar portlet receives objects of the FooClp class which has been loaded into the bar context. When Baz portlet calls Bar's service, these FooClp objects aren't translated into the baz context. So, they are incompatible with FooClp (and Foo) classes in the baz context.
A possible solution can be:
- Saving the original ClpSerializer for every singe *Clp object
- Extending translators by calling the original serializer when *Clp objects are encountered
- Set up a working Portal and a corresponding liferay-plugins repo or Plugins SDK
- Install the attached portlets from source
- Unzip the package into the portlets folder of your plugins repo or SDK
- Call ant build-service for foo-portlet and bar-portlet
- Build and deploy all 3 portlets into the Portal bundle
- Add Baz (Sample section) to the page
- Actual result: portlet fails to add, ClassCastException appears in the log
Expected result: the Baz portlet is added with no error.