Details

    • Type: Task Task
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: None
    • Fix Version/s: 2.4
    • Security Level: Public (Public: Anyone can view)
    • Labels:
      None
    • Similar issues:
      KULRICE-4763Code a proof of concept reflecting Savoir versioning recommendations
      KULRICE-14143POC: REST-ful API to KIM Groups
      KULRICE-1298Rename the NamedTestClassRunner to reflect functionality
      KULRICE-4201Create a POC using JAXB
      KULRICE-13147Inefficiencies in view lifecycle and rendering
      KULRICE-14066Modify KSB_Bus_Security.xml and Subversion wiki page to reflect Git change
      KULRICE-11044KRAD PoC - Problems with refreshId when used in a lightbox.
      KULRICE-10438Analysis for delaying lifecycle row details component before it is needed
      KULRICE-5029Update 1.1 Jira versions to 2.0 to reflect ARC changes
      KULRICE-10538retrieveViaAjax delay lifecycle analysis
    • Epic Link:
    • Rice Module:
      KRAD
    • Sprint:
      2.4.0-m3 KRAD UXI Sprint 2, 2.4.0-m3 KRAD UXI Sprint 3
    • KAI Review Status:
      Not Required
    • KTI Review Status:
      Not Required
    • Code Review Status:
      Not Required
    • Include in Release Notes?:
      Yes

      Description

      In order to facilitate running a branch of the view tree during component refresh, try changing the lifecycle to use reflection for finding child components.

      Currently after the lifecycle phase is processed for a component, a call is made to getComponentsForLifecycle. The phase is then executed on each returned component, and so on. Instead of calling this method, inspect the properties for component types, and then invoke the phase on each found component property. This will allow us to build up a property path from the view to a particular component, and on the refresh we can recreate the parents for the refresh component and execute a refresh method on each to set the necessary state on the refreshed component.

      Couple things to keep in mind. We will probably need a NoLifecycle annotation (or something similar) that can be added to a property. Also, there will be no control over the order child components are processed. Not sure if that will be an issue or not.

      At least in one place I know about, there is logic in the getComponentsForLifecycle method. This is in the view component. Take a look through current implementation of getComponentsForLifecycle to see if there is anything else that might cause problems.

        Activity

        Hide
        Mark Fyffe (Inactive) added a comment -

        Committed initial POC and unit test for determining View sublifecycle components using reflection.

        In this update are updates to ObjectPropertyUtils:

        • Converted property descriptor cache to metadata cache
        • Added cached read and write methods to metadata to improve property lookup performance
        • Added cached lists of property names by type, annotation, and collection type, including support for generic collections and maps.

        The unit test, repeated below proves that all lifecycle components returned via getComponentsForLifecycle are found using a new method in ComponentUtils, which returns lifecycle components in a map using the property path for the component relative to the parent node as keys.

            @Test
            public void testComponentsForLifecycle() throws Throwable {
                ViewService viewService = KRADServiceLocatorWeb.getViewService();
                View view = viewService.getViewById("TransactionView");
                
                List<Component> l1 = view.getComponentsForLifecycle();
                Map<String, Component> m2 = ComponentUtils.getComponentsForLifecycle(view, false);
                LOG.debug(l1.toString());
                LOG.debug(m2.toString());
                assertTrue(l1.size() >= m2.size());
        
                Iterator<Entry<String, Component>> i2 = m2.entrySet().iterator();
                while (i2.hasNext()) {
                    Entry<String, Component> e2 = i2.next();
                    assertTrue(e2.getKey(), l1.contains(e2.getValue()));
                    l1.remove(e2.getValue());
                }
                for (int i=0;i<l1.size();i++) {
                    assertNull(l1.get(i) == null ? null : l1.get(i).toString(), l1.get(i));
                }
            }
        

        For reference, the mapping noted in this test is printed in debug logs below:

        2013-11-05 05:40:03,923 [main] u:/d: DEBUG org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTest - {applicationFooter=org.kuali.ri
        ce.krad.uif.container.Group@d430c4f, applicationHeader=org.kuali.rice.krad.uif.element.Header@5751190a, breadcrumbItem=org.kuali
        .rice.krad.uif.util.BreadcrumbItem@8087e56, breadcrumbs=org.kuali.rice.krad.uif.widget.Breadcrumbs@2cdd1d56, currentPage=org.kua
        li.rice.krad.uif.container.PageGroup@61fe38f3, footer=org.kuali.rice.krad.uif.container.Group@9cdf821, growls=org.kuali.rice.kra
        d.uif.widget.Growls@68b1101c, header=org.kuali.rice.krad.uif.element.ViewHeader@19a0c4a4, help=org.kuali.rice.krad.uif.widget.He
        lp@315d438e, navigationBlockUI=org.kuali.rice.krad.uif.widget.BlockUI@4098d3f6, refreshBlockUI=org.kuali.rice.krad.uif.widget.Bl
        ockUI@7183dc9b, breadcrumbItems[0]=org.kuali.rice.krad.uif.util.BreadcrumbItem@659e4438, breadcrumbItems[1]=org.kuali.rice.krad.
        uif.util.BreadcrumbItem@7990eca6}
        

        The next step is to assemble a POC for executing the full lifecycle using this new mechanism instead of the manual getComponentsForLifecycle() implementations.

        Show
        Mark Fyffe (Inactive) added a comment - Committed initial POC and unit test for determining View sublifecycle components using reflection. In this update are updates to ObjectPropertyUtils: Converted property descriptor cache to metadata cache Added cached read and write methods to metadata to improve property lookup performance Added cached lists of property names by type, annotation, and collection type, including support for generic collections and maps. The unit test, repeated below proves that all lifecycle components returned via getComponentsForLifecycle are found using a new method in ComponentUtils, which returns lifecycle components in a map using the property path for the component relative to the parent node as keys. @Test public void testComponentsForLifecycle() throws Throwable { ViewService viewService = KRADServiceLocatorWeb.getViewService(); View view = viewService.getViewById( "TransactionView" ); List<Component> l1 = view.getComponentsForLifecycle(); Map< String , Component> m2 = ComponentUtils.getComponentsForLifecycle(view, false ); LOG.debug(l1.toString()); LOG.debug(m2.toString()); assertTrue(l1.size() >= m2.size()); Iterator<Entry< String , Component>> i2 = m2.entrySet().iterator(); while (i2.hasNext()) { Entry< String , Component> e2 = i2.next(); assertTrue(e2.getKey(), l1.contains(e2.getValue())); l1.remove(e2.getValue()); } for ( int i=0;i<l1.size();i++) { assertNull(l1.get(i) == null ? null : l1.get(i).toString(), l1.get(i)); } } For reference, the mapping noted in this test is printed in debug logs below: 2013-11-05 05:40:03,923 [main] u:/d: DEBUG org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTest - {applicationFooter=org.kuali.ri ce.krad.uif.container.Group@d430c4f, applicationHeader=org.kuali.rice.krad.uif.element.Header@5751190a, breadcrumbItem=org.kuali .rice.krad.uif.util.BreadcrumbItem@8087e56, breadcrumbs=org.kuali.rice.krad.uif.widget.Breadcrumbs@2cdd1d56, currentPage=org.kua li.rice.krad.uif.container.PageGroup@61fe38f3, footer=org.kuali.rice.krad.uif.container.Group@9cdf821, growls=org.kuali.rice.kra d.uif.widget.Growls@68b1101c, header=org.kuali.rice.krad.uif.element.ViewHeader@19a0c4a4, help=org.kuali.rice.krad.uif.widget.He lp@315d438e, navigationBlockUI=org.kuali.rice.krad.uif.widget.BlockUI@4098d3f6, refreshBlockUI=org.kuali.rice.krad.uif.widget.Bl ockUI@7183dc9b, breadcrumbItems[0]=org.kuali.rice.krad.uif.util.BreadcrumbItem@659e4438, breadcrumbItems[1]=org.kuali.rice.krad. uif.util.BreadcrumbItem@7990eca6} The next step is to assemble a POC for executing the full lifecycle using this new mechanism instead of the manual getComponentsForLifecycle() implementations.
        Hide
        Mark Fyffe (Inactive) added a comment -

        Completed reflection-based lifecycle work with passing unit tests, and have committed to performance branch along with a merge of recent work from trunk merge.

        Added getPath() to LifecyclePhase. When reflection-based lifecycle is enabled, this property returns the property path relative to the view of the component the phase is related to.

        This evening and tomorrow, I'll work into regression testing on krad-sampleapp and rice-sampleapp then commit final cleanup work to performance branch.

        Show
        Mark Fyffe (Inactive) added a comment - Completed reflection-based lifecycle work with passing unit tests, and have committed to performance branch along with a merge of recent work from trunk merge. Added getPath() to LifecyclePhase. When reflection-based lifecycle is enabled, this property returns the property path relative to the view of the component the phase is related to. This evening and tomorrow, I'll work into regression testing on krad-sampleapp and rice-sampleapp then commit final cleanup work to performance branch.
        Hide
        Mark Fyffe (Inactive) added a comment -

        KRAD sampleapp regression testing has been completed. Added annotations to LookupView and component library classes to resolve errors.

        So far, reflection-based traversal appears to be functionally equivalent and performance is on part with manually implemented getComponentsForLifecycle() methods.

        Show
        Mark Fyffe (Inactive) added a comment - KRAD sampleapp regression testing has been completed. Added annotations to LookupView and component library classes to resolve errors. So far, reflection-based traversal appears to be functionally equivalent and performance is on part with manually implemented getComponentsForLifecycle() methods.
        Hide
        Mark Fyffe (Inactive) added a comment -

        Implementation summary and to-do items for completing this request, from a recent email to Jerry:

        The current algorithm I’m working with aims to be similar to the manual getComponentsForLifecycle() and getComponentPrototypes() implementations:

        1. Scan for all bean properties with a read method with a return type extending LifecycleElement.
        2. Skip the property if @NoLifecycle is found, or if @LifecyclePrototype is found and includePrototypes = false
        3. Call the read method on the property:
          • Add the property path and component to the map if the property value is a subclass of Component.
          • Nest into the non-component lifecycle element if not a component (layout manager)
        4. Scan for all bean properties with a read method with a return type of Array, List, or Map where the component type extends Collection. Generic type parameters, including wildcard types, are supported.
        5. Repeat steps 2 and 3 for each element in the array, list, or map.

        By default, any component located as a bean property will be included - @NoLifecycle or @LifecyclePrototype is needed to exclude the component from the list. Following a blacklist approach should make it easier to write components, since exclusion is not a common case. If you’d like to review the details, the algorithm for generating lifecycle component maps is in ComponentUtils. This algorithm relies on bean property scanning functionality added to ObjectPropertyUtils.

        In my testing so far, the reflection overhead is negligible, but I’m still working through a few odd cases where components either end up out of phase or attempt to process twice. Correct placement of @NoLifecycle and @LifecyclePrototype are sufficient to correct the cases I’ve fixed so far.

        The two annotations I created so far were simpler to write, but once I have regression testing working, I’d like to remove them and replace with a single annotation @LifecycleRestriction. The value list on this annotation will indicate which phases the component applies to – for example:

        1. @NoLifecycle becomes @LifecycleRestriction
        2. @LifecyclePrototype becomes @LifecycleRestriction(UifConstants.ViewPhases.INITIALIZE)
        3. Theoritcally, @LifecycleRestriction({UifConstances.ViewPhases.APPLY_MODEL, UifConstances.ViewPhases.FINALIZE}) would include a component only in the indicated phases.

        After converting the annotation, I’ll change ComponentUtils.getComponentsForLifecycle() to take a lifecycle phase instead of the “includePrototypes” flag.

        Show
        Mark Fyffe (Inactive) added a comment - Implementation summary and to-do items for completing this request, from a recent email to Jerry: The current algorithm I’m working with aims to be similar to the manual getComponentsForLifecycle() and getComponentPrototypes() implementations: Scan for all bean properties with a read method with a return type extending LifecycleElement. Skip the property if @NoLifecycle is found, or if @LifecyclePrototype is found and includePrototypes = false Call the read method on the property: Add the property path and component to the map if the property value is a subclass of Component. Nest into the non-component lifecycle element if not a component (layout manager) Scan for all bean properties with a read method with a return type of Array, List, or Map where the component type extends Collection. Generic type parameters, including wildcard types, are supported. Repeat steps 2 and 3 for each element in the array, list, or map. By default, any component located as a bean property will be included - @NoLifecycle or @LifecyclePrototype is needed to exclude the component from the list. Following a blacklist approach should make it easier to write components, since exclusion is not a common case. If you’d like to review the details, the algorithm for generating lifecycle component maps is in ComponentUtils. This algorithm relies on bean property scanning functionality added to ObjectPropertyUtils. In my testing so far, the reflection overhead is negligible, but I’m still working through a few odd cases where components either end up out of phase or attempt to process twice. Correct placement of @NoLifecycle and @LifecyclePrototype are sufficient to correct the cases I’ve fixed so far. The two annotations I created so far were simpler to write, but once I have regression testing working, I’d like to remove them and replace with a single annotation @LifecycleRestriction. The value list on this annotation will indicate which phases the component applies to – for example: @NoLifecycle becomes @LifecycleRestriction @LifecyclePrototype becomes @LifecycleRestriction(UifConstants.ViewPhases.INITIALIZE) Theoritcally, @LifecycleRestriction({UifConstances.ViewPhases.APPLY_MODEL, UifConstances.ViewPhases.FINALIZE}) would include a component only in the indicated phases. After converting the annotation, I’ll change ComponentUtils.getComponentsForLifecycle() to take a lifecycle phase instead of the “includePrototypes” flag.
        Hide
        Mark Fyffe (Inactive) added a comment -

        Created @ViewLifecycleRestriction to replace @NoLifecycle and @LifeCyclePrototype, and converted as described in previous comment.

        Unit tests are passing, and KSA works well in my local environment with this configuration. The bulk of the effort for this POC has been completed. However, I am seeing errors that appear to be related to JPA rather than UIF in sampleapp when running against the performance branch - will need to track down the cause of these errors and complete KRAD sampleapp and Rice sampleapp regression testing before resolving this issue.

        For reference, the JPA error is below - I am seeing this on both Library and Demo views:

        org.kuali.rice.core.api.exception.RiceRuntimeException: The workflow document is null.  This indicates that the DocumentHeader has not been initialized properly.  This can be caused by not retrieving a document using the DocumentService.
        at org.kuali.rice.krad.bo.DocumentHeader.getWorkflowDocument(DocumentHeader.java:75)
        at org.kuali.rice.krad.service.impl.DocumentHeaderServiceImpl.saveDocumentHeader(DocumentHeaderServiceImpl.java:46)
        at org.kuali.rice.krad.document.DocumentBase.prePersist(DocumentBase.java:667)
        at sun.reflect.GeneratedMethodAccessor2302.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.eclipse.persistence.internal.security.PrivilegedAccessHelper.invokeMethod(PrivilegedAccessHelper.java:409)
        at org.eclipse.persistence.internal.jpa.metadata.listeners.EntityListener.invokeMethod(EntityListener.java:326)
        at org.eclipse.persistence.internal.jpa.metadata.listeners.EntityClassListener.invokeMethod(EntityClassListener.java:75)
        at org.eclipse.persistence.internal.jpa.metadata.listeners.EntityListener.prePersist(EntityListener.java:449)
        at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:748)
        at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:684)
        at org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:229)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectClone(UnitOfWorkImpl.java:4316)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.cloneAndRegisterNewObject(RepeatableWriteUnitOfWork.java:608)
        at org.eclipse.persistence.internal.sessions.MergeManager.registerObjectForMergeCloneIntoWorkingCopy(MergeManager.java:1097)
        at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:557)
        at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:313)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3521)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.mergeCloneWithReferences(RepeatableWriteUnitOfWork.java:384)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3481)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.mergeInternal(EntityManagerImpl.java:542)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.merge(EntityManagerImpl.java:519)
        at sun.reflect.GeneratedMethodAccessor2251.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)
        at com.sun.proxy.$Proxy75.merge(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor2251.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
        at com.sun.proxy.$Proxy75.merge(Unknown Source)
        at org.kuali.rice.krad.data.jpa.JpaPersistenceProvider.save(JpaPersistenceProvider.java:80)
        at sun.reflect.GeneratedMethodAccessor2250.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at com.sun.proxy.$Proxy77.save(Unknown Source)
        at org.kuali.rice.krad.data.provider.impl.ProviderBasedDataObjectService.save(ProviderBasedDataObjectService.java:89)
        at org.kuali.rice.krad.service.impl.KRADLegacyDataAdapterImpl.saveDocument(KRADLegacyDataAdapterImpl.java:117)
        at org.kuali.rice.krad.service.impl.LegacyDataAdapterImpl.saveDocument(LegacyDataAdapterImpl.java:56)
        at org.kuali.rice.krad.service.impl.DocumentServiceImpl.validateAndPersistDocument(DocumentServiceImpl.java:851)
        at org.kuali.rice.krad.service.impl.DocumentServiceImpl.validateAndPersistDocumentAndSaveAdHocRoutingRecipients(DocumentServiceImpl.java:468)
        at org.kuali.rice.krad.service.impl.DocumentServiceImpl.saveDocument(DocumentServiceImpl.java:126)
        at org.kuali.rice.krad.service.impl.DocumentServiceImpl.saveDocument(DocumentServiceImpl.java:107)
        at org.kuali.rice.krad.demo.uif.form.KradSampleAppForm.&lt;init&gt;(KradSampleAppForm.java:410)
        at org.kuali.rice.krad.demo.uif.controller.KradSampleAppController.createInitialForm(KradSampleAppController.java:45)
        at org.kuali.rice.krad.demo.uif.controller.KradSampleAppController.createInitialForm(KradSampleAppController.java:39)
        at org.kuali.rice.krad.web.controller.UifControllerBase.initForm(UifControllerBase.java:112)
        at org.kuali.rice.krad.web.controller.UifControllerBase$$FastClassByCGLIB$$7929303a.invoke(&lt;generated&gt;)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
        at org.kuali.rice.krad.demo.uif.controller.KradSampleAppController$$EnhancerByCGLIB$$1f82f45c.initForm(&lt;generated&gt;)
        at sun.reflect.GeneratedMethodAccessor1526.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
        at org.springframework.web.method.annotation.ModelFactory.invokeModelAttributeMethods(ModelFactory.java:123)
        at org.springframework.web.method.annotation.ModelFactory.initModel(ModelFactory.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:722)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.kuali.rice.krad.web.filter.CharsetFilter.doFilter(CharsetFilter.java:58)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.kuali.rice.krad.web.filter.UserLoginFilter.doFilter(UserLoginFilter.java:89)
        at org.kuali.rice.krad.web.filter.UserLoginFilter.doFilter(UserLoginFilter.java:77)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.kuali.rice.krad.web.filter.BootstrapFilterChain.doFilter(BootstrapFilter.java:327)
        at org.kuali.rice.krad.web.filter.DummyLoginFilter.doFilter(DummyLoginFilter.java:82)
        at org.kuali.rice.krad.web.filter.DummyLoginFilter.doFilter(DummyLoginFilter.java:62)
        at org.kuali.rice.krad.web.filter.BootstrapFilterChain.doFilter(BootstrapFilter.java:320)
        at org.kuali.rice.krad.web.filter.BootstrapFilter.doFilter(BootstrapFilter.java:199)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.kuali.rice.krad.web.filter.UifSessionTimeoutFilter.doFilter(UifSessionTimeoutFilter.java:128)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.kuali.rice.core.web.Log4JContextClearingFilter.doFilterInternal(Log4JContextClearingFilter.java:37)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.kuali.rice.krad.web.filter.HideWebInfFilter.doFilter(HideWebInfFilter.java:68)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:213)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:744)
        
        Show
        Mark Fyffe (Inactive) added a comment - Created @ViewLifecycleRestriction to replace @NoLifecycle and @LifeCyclePrototype, and converted as described in previous comment. Unit tests are passing, and KSA works well in my local environment with this configuration. The bulk of the effort for this POC has been completed. However, I am seeing errors that appear to be related to JPA rather than UIF in sampleapp when running against the performance branch - will need to track down the cause of these errors and complete KRAD sampleapp and Rice sampleapp regression testing before resolving this issue. For reference, the JPA error is below - I am seeing this on both Library and Demo views: org.kuali.rice.core.api.exception.RiceRuntimeException: The workflow document is null. This indicates that the DocumentHeader has not been initialized properly. This can be caused by not retrieving a document using the DocumentService. at org.kuali.rice.krad.bo.DocumentHeader.getWorkflowDocument(DocumentHeader.java:75) at org.kuali.rice.krad.service.impl.DocumentHeaderServiceImpl.saveDocumentHeader(DocumentHeaderServiceImpl.java:46) at org.kuali.rice.krad.document.DocumentBase.prePersist(DocumentBase.java:667) at sun.reflect.GeneratedMethodAccessor2302.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.eclipse.persistence.internal.security.PrivilegedAccessHelper.invokeMethod(PrivilegedAccessHelper.java:409) at org.eclipse.persistence.internal.jpa.metadata.listeners.EntityListener.invokeMethod(EntityListener.java:326) at org.eclipse.persistence.internal.jpa.metadata.listeners.EntityClassListener.invokeMethod(EntityClassListener.java:75) at org.eclipse.persistence.internal.jpa.metadata.listeners.EntityListener.prePersist(EntityListener.java:449) at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:748) at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:684) at org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:229) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectClone(UnitOfWorkImpl.java:4316) at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.cloneAndRegisterNewObject(RepeatableWriteUnitOfWork.java:608) at org.eclipse.persistence.internal.sessions.MergeManager.registerObjectForMergeCloneIntoWorkingCopy(MergeManager.java:1097) at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:557) at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:313) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3521) at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.mergeCloneWithReferences(RepeatableWriteUnitOfWork.java:384) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3481) at org.eclipse.persistence.internal.jpa.EntityManagerImpl.mergeInternal(EntityManagerImpl.java:542) at org.eclipse.persistence.internal.jpa.EntityManagerImpl.merge(EntityManagerImpl.java:519) at sun.reflect.GeneratedMethodAccessor2251.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366) at com.sun.proxy.$Proxy75.merge(Unknown Source) at sun.reflect.GeneratedMethodAccessor2251.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241) at com.sun.proxy.$Proxy75.merge(Unknown Source) at org.kuali.rice.krad.data.jpa.JpaPersistenceProvider.save(JpaPersistenceProvider.java:80) at sun.reflect.GeneratedMethodAccessor2250.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy77.save(Unknown Source) at org.kuali.rice.krad.data.provider.impl.ProviderBasedDataObjectService.save(ProviderBasedDataObjectService.java:89) at org.kuali.rice.krad.service.impl.KRADLegacyDataAdapterImpl.saveDocument(KRADLegacyDataAdapterImpl.java:117) at org.kuali.rice.krad.service.impl.LegacyDataAdapterImpl.saveDocument(LegacyDataAdapterImpl.java:56) at org.kuali.rice.krad.service.impl.DocumentServiceImpl.validateAndPersistDocument(DocumentServiceImpl.java:851) at org.kuali.rice.krad.service.impl.DocumentServiceImpl.validateAndPersistDocumentAndSaveAdHocRoutingRecipients(DocumentServiceImpl.java:468) at org.kuali.rice.krad.service.impl.DocumentServiceImpl.saveDocument(DocumentServiceImpl.java:126) at org.kuali.rice.krad.service.impl.DocumentServiceImpl.saveDocument(DocumentServiceImpl.java:107) at org.kuali.rice.krad.demo.uif.form.KradSampleAppForm.&lt;init&gt;(KradSampleAppForm.java:410) at org.kuali.rice.krad.demo.uif.controller.KradSampleAppController.createInitialForm(KradSampleAppController.java:45) at org.kuali.rice.krad.demo.uif.controller.KradSampleAppController.createInitialForm(KradSampleAppController.java:39) at org.kuali.rice.krad.web.controller.UifControllerBase.initForm(UifControllerBase.java:112) at org.kuali.rice.krad.web.controller.UifControllerBase$$FastClassByCGLIB$$7929303a.invoke(&lt;generated&gt;) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631) at org.kuali.rice.krad.demo.uif.controller.KradSampleAppController$$EnhancerByCGLIB$$1f82f45c.initForm(&lt;generated&gt;) at sun.reflect.GeneratedMethodAccessor1526.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) at org.springframework.web.method.annotation.ModelFactory.invokeModelAttributeMethods(ModelFactory.java:123) at org.springframework.web.method.annotation.ModelFactory.initModel(ModelFactory.java:97) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:722) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827) at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) at javax.servlet.http.HttpServlet.service(HttpServlet.java:723) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.kuali.rice.krad.web.filter.CharsetFilter.doFilter(CharsetFilter.java:58) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.kuali.rice.krad.web.filter.UserLoginFilter.doFilter(UserLoginFilter.java:89) at org.kuali.rice.krad.web.filter.UserLoginFilter.doFilter(UserLoginFilter.java:77) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.kuali.rice.krad.web.filter.BootstrapFilterChain.doFilter(BootstrapFilter.java:327) at org.kuali.rice.krad.web.filter.DummyLoginFilter.doFilter(DummyLoginFilter.java:82) at org.kuali.rice.krad.web.filter.DummyLoginFilter.doFilter(DummyLoginFilter.java:62) at org.kuali.rice.krad.web.filter.BootstrapFilterChain.doFilter(BootstrapFilter.java:320) at org.kuali.rice.krad.web.filter.BootstrapFilter.doFilter(BootstrapFilter.java:199) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.kuali.rice.krad.web.filter.UifSessionTimeoutFilter.doFilter(UifSessionTimeoutFilter.java:128) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.kuali.rice.core.web.Log4JContextClearingFilter.doFilterInternal(Log4JContextClearingFilter.java:37) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.kuali.rice.krad.web.filter.HideWebInfFilter.doFilter(HideWebInfFilter.java:68) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:213) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:744)
        Hide
        Mark Fyffe (Inactive) added a comment -

        Completed regression testing w/ POC enabled - KRAD sampleapp is working properly in my local environment, with equivalent or better performance.

        The JPA errors reported previously were resolved by re-enabling weaving in EclipseLink. Disabling weaving was a short-term workaround to get KSA working in Rice 2.4 for performance analysis (on KULRICE-10810).

        Show
        Mark Fyffe (Inactive) added a comment - Completed regression testing w/ POC enabled - KRAD sampleapp is working properly in my local environment, with equivalent or better performance. The JPA errors reported previously were resolved by re-enabling weaving in EclipseLink. Disabling weaving was a short-term workaround to get KSA working in Rice 2.4 for performance analysis (on KULRICE-10810 ).

          People

          • Assignee:
            Mark Fyffe (Inactive)
            Reporter:
            Jerry Neal (Inactive)
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 2 days
              2d
              Remaining:
              Remaining Estimate - 0 minutes
              0m
              Logged:
              Time Spent - 2 days
              2d

                Agile

                  Structure Helper Panel