You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by xu...@apache.org on 2011/05/11 16:43:01 UTC
svn commit: r1101900 - in
/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer:
EjbTimerServiceImpl.java TimerData.java TimerImpl.java
Author: xuhaihong
Date: Wed May 11 14:43:01 2011
New Revision: 1101900
URL: http://svn.apache.org/viewvc?rev=1101900&view=rev
Log:
OPENEJB-1544 Correct current timer exception logic to confirm EJB31 spec: 18.4.3 Timer Expiration and Timeout Callback Method and 18.4.4 Timer Cancellation (Patch from Shawn Jiang)
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EjbTimerServiceImpl.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerData.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerImpl.java
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EjbTimerServiceImpl.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EjbTimerServiceImpl.java?rev=1101900&r1=1101899&r2=1101900&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EjbTimerServiceImpl.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EjbTimerServiceImpl.java Wed May 11 14:43:01 2011
@@ -28,6 +28,7 @@ import javax.ejb.ScheduleExpression;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.transaction.Status;
+import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import org.apache.openejb.BeanContext;
@@ -313,8 +314,8 @@ public class EjbTimerServiceImpl impleme
if (timer == null) {
return;
}
-
for (int tries = 0; tries < (1 + retryAttempts); tries++) {
+ boolean retry = false;
// if transacted, begin the transaction
if (transacted) {
try {
@@ -324,41 +325,45 @@ public class EjbTimerServiceImpl impleme
return;
}
}
-
// call the timeout method
try {
RpcContainer container = (RpcContainer) deployment.getContainer();
Method ejbTimeout = timerData.getTimeoutMethod();
container.invoke(deployment.getDeploymentID(), InterfaceType.TIMEOUT, ejbTimeout.getDeclaringClass(), ejbTimeout, new Object[] { timer }, timerData.getPrimaryKey());
} catch (RuntimeException e) {
+ retry = true;
// exception from a timer does not necessairly mean failure
log.warning("RuntimeException from ejbTimeout on " + deployment.getDeploymentID(), e);
+ try {
+ transactionManager.setRollbackOnly();
+ } catch (SystemException e1) {
+ log.warning("Exception occured while setting RollbackOnly for container transaction", e1);
+ }
} catch (OpenEJBException e) {
+ retry = true;
log.warning("Exception from ejbTimeout on " + deployment.getDeploymentID(), e);
+ if (transacted) {
+ try {
+ transactionManager.setRollbackOnly();
+ } catch (SystemException e1) {
+ log.warning("Exception occured while setting RollbackOnly for container transaction", e1);
+ }
+ }
} finally {
try {
- if (!transacted || transactionManager.getStatus() == Status.STATUS_ACTIVE) {
- // clean up the timer store
- //TODO shall we do all this via Quartz listener ???
- if (timerData.getType() == TimerType.SingleAction) {
- timerStore.removeTimer(timerData.getId());
+ if (!transacted) {
+ if (retry) {
+ continue;
} else {
- timerStore.updateIntervalTimer(timerData);
- }
-
- // commit the tx
- if (transacted) {
- transactionManager.commit();
+ return;
}
-
- // all is cool
- //noinspection ReturnInsideFinallyBlock
+ } else if (transactionManager.getStatus() == Status.STATUS_ACTIVE) {
+ transactionManager.commit();
return;
} else {
- // tx was marked rollback, so roll it back
- if (transacted) {
- transactionManager.rollback();
- }
+ // tx was marked rollback, so roll it back and retry.
+ transactionManager.rollback();
+ continue;
}
} catch (Exception e) {
log.warning("Exception occured while completing container transaction", e);
@@ -373,9 +378,16 @@ public class EjbTimerServiceImpl impleme
log.warning("Error occured while calling ejbTimeout", e);
throw e;
} finally {
- // if this is a single action timer, mark it as cancelled
+ // clean up the timer store
+ //TODO shall we do all this via Quartz listener ???
if (timerData.getType() == TimerType.SingleAction) {
- cancelled(timerData);
+ timerStore.removeTimer(timerData.getId());
+ timerData.setExpired(true);
+ } else if (timerData.getType() == TimerType.Calendar && timerData.getNextTimeout() == null) {
+ timerStore.removeTimer(timerData.getId());
+ timerData.setExpired(true);
+ } else {
+ timerStore.updateIntervalTimer(timerData);
}
}
}
@@ -400,4 +412,4 @@ public class EjbTimerServiceImpl impleme
});
}
}*/
-}
+}
\ No newline at end of file
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerData.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerData.java?rev=1101900&r1=1101899&r2=1101900&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerData.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerData.java Wed May 11 14:43:01 2011
@@ -21,8 +21,6 @@ import java.lang.reflect.Method;
import java.util.Date;
import javax.ejb.EJBException;
-import javax.ejb.NoMoreTimeoutsException;
-import javax.ejb.NoSuchObjectLocalException;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.transaction.Status;
@@ -79,6 +77,14 @@ public abstract class TimerData {
* when we are registered to avoid multiple registrations.
*/
private boolean synchronizationRegistered = false;
+
+ /**
+ * Used to set timer to expired state after the timeout callback method has been successfully invoked.
+ * only apply to
+ * 1, Single action timer
+ * 2, Calendar timer there are no future timeout.
+ */
+ private boolean expired;
public TimerData(long id, EjbTimerServiceImpl timerService, String deploymentId, Object primaryKey, Method timeoutMethod, TimerConfig timerConfig) {
this.id = id;
@@ -227,11 +233,7 @@ public abstract class TimerData {
return trigger;
}
- public Date getNextTimeout() throws NoSuchObjectLocalException, NoMoreTimeoutsException {
- if (cancelled) {
- throw new NoSuchObjectLocalException("The timer has been cancelled");
- }
-
+ public Date getNextTimeout() {
Date nextTimeout = null;
@@ -240,19 +242,21 @@ public abstract class TimerData {
nextTimeout = getTrigger().getNextFireTime();
}
-
-
- if (nextTimeout == null) {
- throw new NoMoreTimeoutsException("The timer has no future timeouts");
- }
-
return nextTimeout;
}
- public long getTimeRemaining() throws NoSuchObjectLocalException, NoMoreTimeoutsException {
+ public long getTimeRemaining() {
Date nextTimeout = getNextTimeout();
return nextTimeout.getTime() - System.currentTimeMillis();
}
+
+ public boolean isExpired() {
+ return expired;
+ }
+
+ public void setExpired(boolean expired){
+ this.expired = expired;
+ }
public abstract TimerType getType();
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerImpl.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerImpl.java?rev=1101900&r1=1101899&r2=1101900&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerImpl.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerImpl.java Wed May 11 14:43:01 2011
@@ -21,6 +21,7 @@ import java.util.Date;
import javax.ejb.EJBContext;
import javax.ejb.EJBException;
+import javax.ejb.NoMoreTimeoutsException;
import javax.ejb.NoSuchObjectLocalException;
import javax.ejb.ScheduleExpression;
import javax.ejb.Timer;
@@ -44,13 +45,16 @@ public class TimerImpl implements Timer
public long getTimeRemaining() throws IllegalStateException, NoSuchObjectLocalException {
checkState();
- /*long now = System.currentTimeMillis();
- long then = timerData.getExpiration().getTime();*/
+ Date nextTimeout = timerData.getNextTimeout();
+ if (nextTimeout == null) throw new NoMoreTimeoutsException("The timer has no future timeouts");
return timerData.getTimeRemaining();
}
public Date getNextTimeout() throws IllegalStateException, NoSuchObjectLocalException {
checkState();
+
+ Date nextTimeout = timerData.getNextTimeout();
+ if (nextTimeout == null) throw new NoMoreTimeoutsException("The timer has no future timeouts");
return timerData.getNextTimeout();
}
@@ -61,6 +65,9 @@ public class TimerImpl implements Timer
public TimerHandle getHandle() throws IllegalStateException, NoSuchObjectLocalException {
checkState();
+ if(!timerData.isPersistent()){
+ throw new IllegalStateException("can't getHandle for a non-persistent timer");
+ }
return new TimerHandleImpl(timerData.getId(), timerData.getDeploymentId());
}
@@ -93,6 +100,10 @@ public class TimerImpl implements Timer
if (timerData.isCancelled()) {
throw new NoSuchObjectLocalException("Timer has been cancelled");
}
+
+ if (timerData.isExpired()){
+ throw new NoSuchObjectLocalException("The timer has expired");
+ }
}
}