ClassLoader problem using JPA with Native Eclipselink project filehttps://www.eclipse.org/forums/index.php/mv/msg/450766/1003363/#msg_1003363
I am testing my application with WebSphere 8 and there is only one copy of eclipselink.jar file (V2.4.1) in the lib directory of my EAR file / application. The eclipselink.jar is in turn referenced from the Manifest.mf file for my EJB project. Anyway, when I start my Enterprise Application, I get a Class cast exception:

Given that my ProgressProject was generated from the Mapping Workbench, and that it directly subclasses org.eclipse.persistence.sessions.Project, the problem must be with class loaders. So... I used the WebSphere debugger and located the problem code inside org.eclipse.persistence.internal.sessions.factories.SessionsFactory:

During initialization, Eclipselink hits the second project = assignment and throws the exception. Under closer examination, m_classLoader is identified as 'com.ibm.ws.classloader.CompoundClassLoader@9ab7dd4[jpatemp:app:YMUSWebApplications]' and has a different java id to the SessionFactory instance's class loader. This SessionFactory Class Loader (derived from evaluating this.getClass().getClassLoader()) is identified as com.ibm.ws.classloader.CompoundClassLoader@95b78cf[app:YMUSWebApplications]. In both cases the actual class path is identical, but clearly they are different class loaders.

Just to be sure, when I place the eclipselink.jar file in the WebSphere Application Server classpath (not a good idea for a prroduction deployment:-)), the problem goes away, and my mappings work just fine.

I am using the default WebSphere class loading policy(s), namely One class loader per enterprise app and delegation to PARENT_FIRST.

What am I doing wrong? Is there some additional configuration property that I need to set for eclipselink, OR for WebSphere?
]]>Roger Spall2013-01-21T03:30:01-00:00Re: ClassLoader problem using JPA with Native Eclipselink project filehttps://www.eclipse.org/forums/index.php/mv/msg/450766/1063975/#msg_1063975
Code snippet from the org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl

if (isSessionLoadedFromSessionsXML) {
if (this.compositeEmSetupImpl == null && this.staticWeaveInfo == null) {
JPAClassLoaderHolder privateClassLoaderHolder = session.getServerPlatform().getNewTempClassLoader(persistenceUnitInfo);
classLoaderToUse = privateClassLoaderHolder.getClassLoader();
} else {
classLoaderToUse = persistenceUnitInfo.getNewTempClassLoader();
}
// Loading session from sessions-xml.
.
.
// Do not register the session with the SessionManager at this point, create temporary session using a local SessionManager and private class loader.
// This allows for the project to be accessed without loading any of the classes to allow weaving.
// Note that this method assigns sessionName to session.
Session tempSession = new SessionManager().getSession(xmlLoader, tempSessionName, classLoaderToUse, false, false);
// Load path of sessions-xml resource before throwing error so user knows which sessions-xml file was found (may be multiple).
session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "sessions_xml_path_where_session_load_from", xmlLoader.getSessionName(), xmlLoader.getResourcePath());
if (tempSession == null) {
throw ValidationException.noSessionFound(sessionName, sessionsXMLStr);
}
// Currently the session must be either a ServerSession or a SessionBroker, cannot be just a DatabaseSessionImpl.
if (tempSession.isServerSession() || tempSession.isSessionBroker()) {
session = (DatabaseSessionImpl) tempSession;
if (tempSessionName != sessionName) {
// set back the original session name
session.setName(sessionName);
}
} else {
throw EntityManagerSetupException.sessionLoadedFromSessionsXMLMustBeServerSession(persistenceUnitInfo.getPersistenceUnitName(), (String)predeployProperties.get(PersistenceUnitProperties.SESSIONS_XML), tempSession);
}
.
.
}

Although, moving eclipselink.jar to websphere lib (adding it to the server classpath) resolved this specific error, I started getting ClassCastException further down when using listeners.
So I tried subclassing the WebSphere_7_Platform and overriding the getNewTempClassLoader method as follows:

@Override
public JPAClassLoaderHolder getNewTempClassLoader(PersistenceUnitInfo puInfo) {
// Return the main classloader and not the temporary one.
return new JPAClassLoaderHolder(puInfo.getClassLoader(), false);
}

But this also means that the temporary session and weaving process is using the main class loader. And I am not sure if it can cause some problems. I haven't seen any so far.]]>Kishore Kirdat2013-06-17T05:42:24-00:00