[ 
https://issues.apache.org/jira/browse/ISIS-1502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dan Haywood updated ISIS-1502:
------------------------------
    Description: 
The situation being an error in toString() throwing an 
InvocationTargetException, as part of the processing of ChangedObjectsService 
in the preCommit().

Although this preCommit() code catches RuntimeExceptions, the 
InvocationTargetException thrown is actually an Exception (even though not in 
any throws clause).

What therefore happened was that the catch block in endTransaction did not 
fire, and was then caught a layer further out (in WebRequestCycleForIsis), 
which incorrectly created a new transaction but with the current transaction's 
state / transaction manager's transactionLevel in invalid states.

The net effect was a transaction with the current transaction still in 
progress, but with transactionLevel = 0.  A subsequent endTransaction took the 
transactionLevel to -1, then resulting in the infinite loop.

Fixes are:
1. catch Exception rather than just RuntimeException in endTransaction
2. also change the order in which transactionLevel is decremented, so that it 
is only done after the preCommit stuff has completed ok
3. in the place where we throw an exception if transactionLevel is found to be 
-1, then also ensure that the state of the current transaction is set 
appropriately.

All of these have been implemented (and any is sufficient to prevent the 
infinite loop).

In addition, further logging to detect when there is an invalid end state of 
transactionLevel and transaction state has been added.




Original root cause that was not caught in endTransaction :

{code}
Caused by:
java.lang.reflect.InvocationTargetException
sun.reflect.GeneratedMethodAccessor367#invoke(null:-1)
sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method#invoke(Method.java:498)
org.apache.isis.core.runtime.services.ServiceInstantiator$2#invoke(ServiceInstantiator.java:219)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal_$$_jvst301_6#getChangedObjectProperties(ChangedObjectsServiceInternal_$$_jvst301_6.java:-1)
org.apache.isis.core.runtime.services.auditing.AuditingServiceInternal#audit(AuditingServiceInternal.java:79)
org.apache.isis.core.runtime.system.transaction.IsisTransaction#preCommit(IsisTransaction.java:424)
org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#endTransaction(IsisTransactionManager.java:363)
org.apache.isis.viewer.wicket.viewer.integration.wicket.WebRequestCycleForIsis#onRequestHandlerExecuted(WebRequestCycleForIsis.java:129)

Caused by:
java.lang.IllegalArgumentException
No such method ' getSent' or 'isSent'
org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:372)
org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
org.apache.isis.core.runtime.services.changes.PreAndPostValues#setPost(PreAndPostValues.java:90)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#capturePostValuesAndDrain(ChangedObjectsServiceInternal.java:241)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#getChangedObjectProperties(ChangedObjectsServiceInternal.java:222)

Caused by:
java.lang.NoSuchMethodException
org.incode.module.communications.dom.impl.comms.Communication.getSent()
java.lang.Class#getMethod(Class.java:1786)
org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:364)
org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
{code}

  was:
The situation being an error in toString() throwing an 
InvocationTargetException, as part of the processing of ChangedObjectsService 
in the preCommit().

Although this preCommit() code catches RuntimeExceptions, the 
InvocationTargetException thrown is actually an Exception (even though not in 
any throws clause).

What therefore happened was that the catch block in endTransaction did not 
fire, and was then caught a layer further out (in WebRequestCycleForIsis), 
which incorrectly created a new transaction but with the current transaction's 
state / transaction manager's transactionLevel in invalid states.

The net effect was a transaction with the current transaction still in 
progress, but with transactionLevel = 0.  A subsequent endTransaction took the 
transactionLevel to -1, then resulting in the infinite loop.

Fixes are:
1. catch Exception rather than just RuntimeException in endTransaction
2. also change the order in which transactionLevel is decremented, so that it 
is only done after the preCommit stuff has completed ok

Both of these have been implemented (and either one is sufficient to prevent 
the error).

In addition, further logging to detect when there is an invalid end state of 
transactionLevel and transaction state has been added.




Original root cause that was not caught in endTransaction :

{code}
Caused by:
java.lang.reflect.InvocationTargetException
sun.reflect.GeneratedMethodAccessor367#invoke(null:-1)
sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method#invoke(Method.java:498)
org.apache.isis.core.runtime.services.ServiceInstantiator$2#invoke(ServiceInstantiator.java:219)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal_$$_jvst301_6#getChangedObjectProperties(ChangedObjectsServiceInternal_$$_jvst301_6.java:-1)
org.apache.isis.core.runtime.services.auditing.AuditingServiceInternal#audit(AuditingServiceInternal.java:79)
org.apache.isis.core.runtime.system.transaction.IsisTransaction#preCommit(IsisTransaction.java:424)
org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#endTransaction(IsisTransactionManager.java:363)
org.apache.isis.viewer.wicket.viewer.integration.wicket.WebRequestCycleForIsis#onRequestHandlerExecuted(WebRequestCycleForIsis.java:129)

Caused by:
java.lang.IllegalArgumentException
No such method ' getSent' or 'isSent'
org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:372)
org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
org.apache.isis.core.runtime.services.changes.PreAndPostValues#setPost(PreAndPostValues.java:90)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#capturePostValuesAndDrain(ChangedObjectsServiceInternal.java:241)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#getChangedObjectProperties(ChangedObjectsServiceInternal.java:222)

Caused by:
java.lang.NoSuchMethodException
org.incode.module.communications.dom.impl.comms.Communication.getSent()
java.lang.Class#getMethod(Class.java:1786)
org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:364)
org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
{code}


> Error handling of invalid domain object not strong enough, causing infinite 
> loop in endTransaction.
> ---------------------------------------------------------------------------------------------------
>
>                 Key: ISIS-1502
>                 URL: https://issues.apache.org/jira/browse/ISIS-1502
>             Project: Isis
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 1.13.0
>            Reporter: Dan Haywood
>            Assignee: Dan Haywood
>             Fix For: 1.13.1
>
>
> The situation being an error in toString() throwing an 
> InvocationTargetException, as part of the processing of ChangedObjectsService 
> in the preCommit().
> Although this preCommit() code catches RuntimeExceptions, the 
> InvocationTargetException thrown is actually an Exception (even though not in 
> any throws clause).
> What therefore happened was that the catch block in endTransaction did not 
> fire, and was then caught a layer further out (in WebRequestCycleForIsis), 
> which incorrectly created a new transaction but with the current 
> transaction's state / transaction manager's transactionLevel in invalid 
> states.
> The net effect was a transaction with the current transaction still in 
> progress, but with transactionLevel = 0.  A subsequent endTransaction took 
> the transactionLevel to -1, then resulting in the infinite loop.
> Fixes are:
> 1. catch Exception rather than just RuntimeException in endTransaction
> 2. also change the order in which transactionLevel is decremented, so that it 
> is only done after the preCommit stuff has completed ok
> 3. in the place where we throw an exception if transactionLevel is found to 
> be -1, then also ensure that the state of the current transaction is set 
> appropriately.
> All of these have been implemented (and any is sufficient to prevent the 
> infinite loop).
> In addition, further logging to detect when there is an invalid end state of 
> transactionLevel and transaction state has been added.
> Original root cause that was not caught in endTransaction :
> {code}
> Caused by:
> java.lang.reflect.InvocationTargetException
> sun.reflect.GeneratedMethodAccessor367#invoke(null:-1)
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
> java.lang.reflect.Method#invoke(Method.java:498)
> org.apache.isis.core.runtime.services.ServiceInstantiator$2#invoke(ServiceInstantiator.java:219)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal_$$_jvst301_6#getChangedObjectProperties(ChangedObjectsServiceInternal_$$_jvst301_6.java:-1)
> org.apache.isis.core.runtime.services.auditing.AuditingServiceInternal#audit(AuditingServiceInternal.java:79)
> org.apache.isis.core.runtime.system.transaction.IsisTransaction#preCommit(IsisTransaction.java:424)
> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#endTransaction(IsisTransactionManager.java:363)
> org.apache.isis.viewer.wicket.viewer.integration.wicket.WebRequestCycleForIsis#onRequestHandlerExecuted(WebRequestCycleForIsis.java:129)
> Caused by:
> java.lang.IllegalArgumentException
> No such method ' getSent' or 'isSent'
> org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:372)
> org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
> org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
> org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
> org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
> org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
> org.apache.isis.core.runtime.services.changes.PreAndPostValues#setPost(PreAndPostValues.java:90)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#capturePostValuesAndDrain(ChangedObjectsServiceInternal.java:241)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#getChangedObjectProperties(ChangedObjectsServiceInternal.java:222)
> Caused by:
> java.lang.NoSuchMethodException
> org.incode.module.communications.dom.impl.comms.Communication.getSent()
> java.lang.Class#getMethod(Class.java:1786)
> org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:364)
> org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
> org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
> org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
> org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
> org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to