Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

1. In this approach, instead of deploying a system.bundle extension fragment, you package all the shared jars in an OSGI bundle and export all the shared packages from that bundle.
2. This seems to resolve classes only in JSPs in sling but fails in Sling servlets with ClassCastException.
The reason for this is as following.
Weblogic uses context classloader of the thread to resolve classes while deserializing session objects. When JSP is processed in Sling, the context classloader is set to org.apache.sling.commons.classloader.impl.ClassLoaderFacade
This classloader can find all the classes ex ported from OSGI bundles loaded in felix.
So, when session attributes are accessed from migrated JSPs in CQSling, the objects used to get serialized, and then deserialized. While deserializing, the classes were resolved by org.apache.sling.commons.classloader.impl.ClassLoaderFacade.

Even if it appeared to work fine, this is not the right solution for the problem at all. The worst part here is that, once the object is deserialized, weblogic replaces original object reference to the deserialized object. So if any other WAR needs the object again, it needs to be serialized/deserialized again. But that works only if original object is loaded with weblogic classloader. So once object is serialized/deserialized with Sling classloader, it will never be serialized/deserialized for other WARs and you will always get ClassCastException. e.g. If CustomerDetailVO is once accessed from CQ JSP component, any other WAR, like OnlineCustomerDetail.war, trying to get CustomerDetailVO from session will get ClassCastException. This happens because, when CustomerDetailVO is accessed by CQ component JSP, it is serialized/deserialized and resolved using org.apache.sling.commons.classloader.impl.ClassLoaderFacade. If its accessed in any other WAR after that, it will not be serialized again and we will get ClassCastException.

It did not work with Sling Servlets because, when servlet is executed, the context classloader is weblogic.utils.classloaders.ChangeAwareClassLoader. This classloader finds classes in EAR or classpath, so we get ClassCastException. Even here, some weblogic classloader magic is going on. The context classloader here, is the classloader for launchpad.war. This is the WAR file for CQSling. The classes referred by servlet can not be loaded by this classloader, because classes exported from OSGI bundles are not visible to this classloader. So welogic, seeing the ClassNotFoundException from context classloader, uses the WAR classloader of the WAR which set the object in the session. Obviously, we get ClassCastException in the sling servlet.

...