Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 323148

Summary: JSF 1.2/2.0 managed-bean: Entities not weaved may cause NPE when EJB module containing @PersistenceContext entityManager injection is not first in application.xml module order
Product: z_Archived Reporter: Michael OBrien <michael.f.obrien>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: RESOLVED WONTFIX QA Contact:
Severity: major    
Priority: P2 CC: eclipselink.orm-inbox, michael.f.obrien
Version: unspecifiedFlags: michael.f.obrien: documentation+
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
URL: http://wiki.eclipse.org/EclipseLink/Examples/JPA/WebLogic_Web_Tutorial#Application.xml_WAR_EJB.jar_Module_order_can_cause_ClassLoader_issues_-_EJB_module_with_.40PersistenceContext_Injection_should_be_first
Whiteboard:
Bug Depends on: 293193, 323403    
Bug Blocks: 324357, 297756    
Attachments:
Description Flags
EAR (with JSF managed-bean element) that reproduces NPE exception when application.xml module order is war first
none
EAR (works fine application.xml module order is war first or ejb first) - no JSF = no JPA issues
none
JSF EAR Eclipse projects - broken deploy reproduction
none
Servlet EAR Eclipse projects - work fine as reference
none
New DescriptorException specifically for "_persistence_*_vh" weaved methods that would have thrown a secondary NPE none

Description Michael OBrien CLA 2010-08-19 10:29:07 EDT
>In some application scenarios we may get the following NPE exception when weaved "_" VH methods are not found on an Entity that should have been weaved/instrumented.

>This bug only depends on comment #7 of bug # 293193

>Reproduction 1: Works fine with either order
See the full source at
http://wiki.eclipse.org/EclipseLink/Examples/JPA/WebLogic_Web_Tutorial
http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/examples/org.eclipse.persistence.example.jpa.server.weblogic.enterpriseEAR/
http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/examples/org.eclipse.persistence.example.jpa.server.weblogic.enterpriseEJB/
http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/examples/org.eclipse.persistence.example.jpa.server.weblogic.enterpriseWeb/

@PersistenceContext injection of a Stateless Session Bean in the ejb.jar
The persistence unit is container managed JTA derby based with weaving and DDL-generation on - running on WebLogic (A glassfish repro is pending)
@EJB injection of the SSB above containing the persistence unit on a plain servlet
The application.xml module order is either war/ejb or ejb/war

>results OK
I see weaving fields added to the Cell.class
this    Cell  (id=13447)   
    _persistence_fetchGroup    null   
    _persistence_left_vh    ValueHolder  (id=13451)   
        isCoordinatedWithProperty    false   
        isNewlyWeavedValueHolder    true   
        value    null   
    _persistence_listener    null   
    _persistence_primaryKey    null   
    _persistence_right_vh    ValueHolder  (id=13452)   
        isCoordinatedWithProperty    false   
        isNewlyWeavedValueHolder    true   
        value    null   
    _persistence_session    null   
    _persistence_shouldRefreshFetchGroup    false   
    id    null   
    left    null   
    peers    HashSet<E>  (id=13453)   
    references    HashSet<E>  (id=13454)   
    right    null    

>Reproduction 2: NPE on un-weaved entity


>Results : NPE
java.lang.NullPointerException
	at org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getMethodReturnType(PrivilegedAccessHelper.java:326)
	at org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor.getGetMethodReturnType(MethodAttributeAccessor.java:112)
	at org.eclipse.persistence.mappings.ForeignReferenceMapping.validateBeforeInitialization(ForeignReferenceMapping.java:1708)
	at org.eclipse.persistence.descriptors.ClassDescriptor.validateBeforeInitialization(ClassDescriptor.java:5282)
	at org.eclipse.persistence.descriptors.ClassDescriptor.preInitialize(ClassDescriptor.java:3346)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:430)
Comment 1 Michael OBrien CLA 2010-08-19 10:30:21 EDT
>Fix for Repro 2: switch the application.xml ordering to ejb/war

<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" id="Application_ID" version="5">
  <display-name> 
org.eclipse.persistence.example.jpa.server.weblogic.enterpriseEAR</display-name>
  <module>
    <ejb>org.eclipse.persistence.example.jpa.server.weblogic.enterpriseEJB.jar</ejb>
  </module>
  <module>
    <web>
      <web-uri>org.eclipse.persistence.example.jpa.server.weblogic.enterpriseWeb.war</web-uri>
      <context-root>enterprise</context-root>
    </web>
  </module>
</application>
Comment 2 Michael OBrien CLA 2010-08-19 10:34:46 EDT
>There is a secondary issue here - when weaving is on and we do not find weaved methods
- we will want to warn and mention this classLoader order issue (EJB jar containing persistence unit must preceed any WAR injecting a bean containing the persistence unit) instead of throwing a NullPointerException because we expect the [value holder] method lookup to pass
Comment 3 Michael OBrien CLA 2010-08-20 10:27:33 EDT
>This bug is for community reference on the workaround for cases where a secondary NPE occurs because of application.xml ejb/war ordering
>The bug was reopened because we have the goahead to enter a Warning to the user on the primary cause of the secondary NullPointerException
- that occurs when an Entity is not weaved because the injected session bean containing the injected persistence context is processed after a war that uses the persistence unit via injection of the session bean in the ejb.jar.
- the NPE cause is because the weaved "_*_vh" method was not found on the entity class

>Warning addition:
- add a warning to initializeDescriptors() that fails with a weaving method check - that we expected the current class to be woven/instrumented.

>Bug is assigned only until I attach 2 nearly identical reproduction EAR files (one that fails and the other that does not)
Comment 4 Michael OBrien CLA 2010-08-20 12:23:29 EDT
>Narrowed the issue down to the way JSF managed beans are deployed.
As soon as we reference any POJO class as a managed-bean (where it contains an @EJB injection of a SSB that itself has an @PersistenceContext injection) - we fail with a secondary NPE when weaved methods are not found on the "should have been weaved" entity class

>If you remove the managed-bean element or the faces-config-xml file itself - you deploy fine with any application.xml module order


<managed-bean>
	<managed-bean-name>cell</managed-bean-name>
	<managed-bean-class>org.eclipse.persistence.example.jpa.server.weblogic.enterprise.presentation.CellBean</managed-bean-class>
	<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

>where the annotated class is on the WAR
public class CellBean {

    @EJB
    private ApplicationServiceLocal applicationService;
    private Cell cell;
}

>and the SSB is on the ejb.jar
@Local
public interface ApplicationServiceLocal {...}
@Stateless
public class ApplicationService implements ApplicationServiceLocal, ApplicationServiceRemote {
	@PersistenceContext(unitName="example", type=PersistenceContextType.TRANSACTION)	
	private EntityManager entityManager;    
...}

>Note: it is not the @EJB injection itself that causes the issue - because a servlet works fine this way - it is the JSF use of classLoaders

>I am attaching two reproduction EAR's and their Eclipse 3.5 OEPE project sets
http://127.0.0.1:7001/enterprise_jsf/FrontController?action=demo
WebLogicJTAbasedJSFSSB_EAR - fails on deploy (after a predeploy success)
WebLogicJTAbasedServletSSB_EAR - works fine

>Note: if you don't want to launch the URL above - you can do a deploy as part of the predeploy
- using the following property in your persistence.xml

<!-- 323148: force an early em.deploy() as part of the emf.predeploy() - normally done on first entityManager login -->
<property name="eclipselink.validation-only" value="True"/>
Comment 5 Michael OBrien CLA 2010-08-20 12:25:31 EDT
>exception is
Caused by: java.lang.NullPointerException
	at org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor.getAttributeValueFromObject(MethodAttributeAccessor.java:74)
	... 70 more

Exception [EclipseLink-70] (Eclipse Persistence Services - 2.2.0.qualifier): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: A NullPointerException was thrown while extracting a value through the method [_persistence_get_right_vh] in the object [org.eclipse.persistence.example.jpa.server.business.Cell].
Internal Exception: java.lang.NullPointerException
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[right]
Descriptor: RelationalDescriptor(org.eclipse.persistence.example.jpa.server.business.Cell --> [DatabaseTable(EL_CELL)])
	at org.eclipse.persistence.exceptions.DescriptorException.nullPointerWhileGettingValueThruMethodAccessor(DescriptorException.java:1256)
	at org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor.getAttributeValueFromObject(MethodAttributeAccessor.java:84)
	at org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor.getAttributeValueFromObject(MethodAttributeAccessor.java:53)
	at org.eclipse.persistence.mappings.DatabaseMapping.getAttributeValueFromObject(DatabaseMapping.java:497)
	at org.eclipse.persistence.mappings.ForeignReferenceMapping.getAttributeValueFromObject(ForeignReferenceMapping.java:792)
	at org.eclipse.persistence.mappings.ForeignReferenceMapping.buildClone(ForeignReferenceMapping.java:180)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.populateAttributesForClone(ObjectBuilder.java:3146)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.populateAndRegisterObject(UnitOfWorkImpl.java:3690)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:1005)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneNormally(ObjectBuilder.java:618)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:555)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:495)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:454)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:721)
	at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:726)
	at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:423)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1074)
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:764)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1034)
	at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:383)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1112)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2910)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1301)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1283)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1257)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:479)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:714)
	at org.eclipse.persistence.example.jpa.server.business.ApplicationService.query(ApplicationService.java:183)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
	at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
	at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at com.bea.core.repackaged.springframework.jee.spi.MethodInvocationVisitorImpl.visit(MethodInvocationVisitorImpl.java:37)
	at weblogic.ejb.container.injection.EnvironmentInterceptorCallbackImpl.callback(EnvironmentInterceptorCallbackImpl.java:54)
	at com.bea.core.repackaged.springframework.jee.spi.EnvironmentInterceptor.invoke(EnvironmentInterceptor.java:50)
	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at com.bea.core.repackaged.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
	at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
	at $Proxy142.query(Unknown Source)
	at org.eclipse.persistence.example.jpa.server.business.ApplicationService_5ptwty_ApplicationServiceLocalImpl.query(ApplicationService_5ptwty_ApplicationServiceLocalImpl.java:181)
Comment 6 Michael OBrien CLA 2010-08-20 12:27:06 EDT
Created attachment 177110 [details]
EAR (with JSF managed-bean element) that reproduces NPE exception when application.xml module order is war first
Comment 7 Michael OBrien CLA 2010-08-20 12:28:06 EDT
Created attachment 177111 [details]
EAR (works fine application.xml module order is war first or ejb first) - no JSF = no JPA issues
Comment 8 Michael OBrien CLA 2010-08-20 12:29:22 EDT
>Major P2 because em deploy will not work without the module order workaround until JSF is fixed
Comment 9 Michael OBrien CLA 2010-08-20 12:30:38 EDT
Created attachment 177112 [details]
JSF EAR Eclipse projects - broken deploy reproduction
Comment 10 Michael OBrien CLA 2010-08-20 12:31:15 EDT
Created attachment 177113 [details]
Servlet EAR Eclipse projects - work fine as reference
Comment 11 Michael OBrien CLA 2010-08-20 12:34:57 EDT
>Note: it is only the deployment of the managed-bean that causes the issue
- as the no-weaving issue occurs even without any functional JSF pages or navigation rules
- a minimal faces-config.xml descriptor is all that is needed to break the persistenceContext
- for even when the same injected persistence unit is used via @EJB injection on a separate non-JSF servlet the first-time deploy of the entityManager causes the NPE exception.

>Here is the minimal faces-config.xml that will cause early loading of the Entity that disallows weaving later in em processing

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
	<application>
		<message-bundle>resources.application</message-bundle>
		<locale-config>
			<default-locale>en</default-locale>
		</locale-config>
	</application>
	<managed-bean>
		<managed-bean-name>cell</managed-bean-name>
		<managed-bean-class>org.eclipse.persistence.example.jpa.server.weblogic.enterprise.presentation.CellBean</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>
</faces-config>
Comment 12 Michael OBrien CLA 2010-08-20 12:36:21 EDT
>The fix for the real issue is in JSF
>marking bug unassigned for the secondary fix of adding a proper EclipseLink warning
- when the class that should have been weaved - was not.
Comment 13 Michael OBrien CLA 2010-08-20 12:46:46 EDT
>Glassfish JSF 1.2:  Of note is the fact that the JSF implementation used comes from Glassfish
C:\wse\wls10330\.metadata\.plugins\oracle.eclipse.tools.weblogic\libraries\jsf_1.2_1.2.9.0\1\WEB-INF\lib\glassfish.jsf_1.2.9.0.jar
C:\wse\wls10330\.metadata\.plugins\oracle.eclipse.tools.weblogic\libraries\jsf_1.2_1.2.9.0\1\WEB-INF\lib\javax.jsf_1.0.0.0_1-2.jar
C:\wse\wls10330\.metadata\.plugins\oracle.eclipse.tools.weblogic\libraries\jsf_1.2_1.2.9.0\1\WEB-INF\lib\wls.jsf.di.jar
Comment 14 Michael OBrien CLA 2010-08-23 15:05:33 EDT
Created attachment 177254 [details]
New DescriptorException specifically for "_persistence_*_vh" weaved methods that would have thrown a secondary NPE

>New DescriptorException specifically for "_persistence_*_vh" weaved methods that would have thrown a secondary NPE
Exception [EclipseLink-218] (Eclipse Persistence Services - 2.2.0.qualifier):
org.eclipse.persistence.exceptions.DescriptorException
Exception Description: A NullPointerException would have occurred accessing a
non-existent weaved method [_persistence_get_right_vh] for the mapping
[org.eclipse.persistence.mappings.OneToOneMapping[right]].  The class was not
weaved properly - check the module order in the application.xml deployment
descriptor and verify that the module containing the persistence unit is ahead
of any module that uses it.
    at
org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:471)
Comment 15 Michael OBrien CLA 2010-08-24 09:29:45 EDT
>Change to throw descriptive DescriptorException only for missing weaving "_persistence_*_vh" functions
is in bug # 323403
>This bug representing the base issue with either the dependency injection
wls.js.di.jar or the 
glassfish.jsf_1.2.9.0.jar is for tracking only and will be set to NOFIX
Comment 16 Eclipse Webmaster CLA 2022-06-09 10:20:07 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink