[résolu] ConcurrentModificationException collection list multi-thread jboss
Bonjour,
je m'arrache les cheveux depuis un petit temps avec cette erreur:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| javax.ejb.EJBException: java.util.ConcurrentModificationException
at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:77)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:190)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorv2.invoke(RoleBasedAuthorizationInterceptorv2.java:201)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:186)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:421)
at org.jboss.ejb3.session.InvokableContextClassProxyHack._dynamicInvoke(InvokableContextClassProxyHack.java:53)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:91)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:891)
at org.jboss.remoting.transport.socket.ServerThread.completeInvocation(ServerThread.java:744)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:697)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:524)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:232)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:782)
at java.util.ArrayList$Itr.next(ArrayList.java:754)
at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:577)
at dns.redundancy.uccImpl.ManagerUsersImpl.saveZoneConfiguration(ManagerUsersImpl.java:497)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:122)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111)
at org.jboss.ejb3.EJBContainerInvocationWrapper.invokeNext(EJBContainerInvocationWrapper.java:69)
at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.invoke(InterceptorSequencer.java:73)
at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.aroundInvoke(InterceptorSequencer.java:59)
at sun.reflect.GeneratedMethodAccessor274.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.jboss.aop.advice.PerJoinpointAdvice.invoke(PerJoinpointAdvice.java:174)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.fillMethod(InvocationContextInterceptor.java:72)
at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_fillMethod_23075407.invoke(InvocationContextInterceptor_z_fillMethod_23075407.java)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.setup(InvocationContextInterceptor.java:88)
at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_setup_23075407.invoke(InvocationContextInterceptor_z_setup_23075407.java)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:56)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:68)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:190)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorv2.invoke(RoleBasedAuthorizationInterceptorv2.java:201)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:186)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:421)
at org.jboss.ejb3.session.InvokableContextClassProxyHack._dynamicInvoke(InvokableContextClassProxyHack.java:53)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:91)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:891)
at org.jboss.remoting.transport.socket.ServerThread.completeInvocation(ServerThread.java:744)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:697)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:524)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:232)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:211)
at org.jboss.remoting.Client.invoke(Client.java:1724)
at org.jboss.remoting.Client.invoke(Client.java:629)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:60)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
at $Proxy6.invoke(Unknown Source)
at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207)
at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)
at $Proxy1.saveZoneConfiguration(Unknown Source)
at addData.main(addData.java:92)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:72)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
at $Proxy6.invoke(Unknown Source)
at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207)
at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)
at $Proxy1.saveZoneConfiguration(Unknown Source)
at addData.main(addData.java:92) |
Je sais qu'elle proviens du fait que la liste est traitée par plusieurs threads simultanés et que pendant que l'un deux effectue une lecture d'un élément, un autre fait une modification sur un autre élément et que cela n'est pas permis car la liste "est modifiée"...
Avez-vous une idée pour résoudre ce problème?
Si je me souviens bien, il est proscrit d'utiliser le mot clé synchronized et je ne pense pas que de passer les classes ucc de stateless en statefull permettra de répondre notament à ce problème...?
Sinon, je suis tombé là-dessus http://wiki.eclipse.org/Using_Eclips...ned_Annotation, mais sans grande conviction...
Donc, je suis ouvert à toutes suggestions...
Merci
Sans oublier le code sources concerné:
dns.redundancy.uccImpl.ManagerUsersImpl:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
//imports ...
@Stateless
public class ManagerUsersImpl implements ManagerUsers {
private static final Logger log = Logger.getLogger(ManagerUsersImpl.class.getName());
@EJB
private HostnameDao hostnameDao;
@EJB
private HostnameIPDao hostnameIpDao;
@EJB
private AddressIPDao addressIpDao;
@EJB
private ZoneDao zoneDao;
@EJB
private UsersDao usersDao;
@EJB
private ManagerSystemHostnameBackup managerSystem;
//...
@Override
public void saveZoneConfiguration(Zone zone) throws ArgumentInvalidException, UccSystemException, HostNotHaveAnAddressIPError {
CheckerArguments.checkObject(zone);
String slog = "Saving the zone's hostnames definitions of " + zone.getZoneName();
log.info(slog);
zone = this.zoneDao.reloadListHostnames(zone);
for (Hostname h : zone.getListHostnames()) {
log.debug(slog + ": election for hostname " + h.getHostname());
h = this.hostnameDao.reloadListHostnameIP(h);
this.managerSystem.electAddressIPFor(h, true);
}
// FIXME doesn't work fine
try {
this.managerSystem.checkADnsZoneFile(zone);
} catch (SerialOutOfBoundException e) {
log.warn(slog, e);
throw new UccSystemException(slog, e);
} catch (ZoneFileSystemException e) {
log.warn(slog, e);
throw new UccSystemException(slog, e);
} catch (BadAddressIPException e) {
log.warn(slog, e);
throw new UccSystemException(slog, e);
} catch (SshConnectionException e) {
log.warn(slog, e);
throw new UccSystemException(slog, e);
} catch (TooMuchSshConnectionsOpenedException e) {
log.warn(slog, e);
throw new UccSystemException(slog, e);
}
log.info(slog + ": done");
} |
dns.redundancy.uccImpl.ManagerSystemHostnameBackupImpl:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
@Stateless
public class ManagerSystemHostnameBackupImpl implements ManagerSystemHostnameBackup, EncodeTimer {
private static final Logger log = Logger.getLogger(ManagerSystemHostnameBackupImpl.class.getName());
@EJB
private HostnameIPDao hostnameIPDao;
@EJB
private HostnameDao hostnameDao;
@EJB
private AddressIPDao addressIpDao;
@EJB
private ZoneDao zoneDao;
@EJB
private UsersDao usersDao;
@EJB
private LogLatencyKADao logLatencyKADao;
@Resource
private TimerService timerService;
private static List<AddressIP> listAddressIp_inInitTime;
private static List<Zone> listZones_whoseSerialHasExceeded = new ArrayList<Zone>(3);
private static List<Zone> listZonesFailedToReload = new ArrayList<Zone>(5);
private static final String timerMsgWaitingList = "process at " + WAITING_PROCESS_HOUR + ":" + WAITING_PROCESS_MINUTES;
//...
@Override
public void electAddressIPFor(Hostname hostname, boolean writeTheFileLater) throws ArgumentInvalidException, HostNotHaveAnAddressIPError {
CheckerArguments.checkObject(hostname);
String slog = "Electing an IP for hostname " + hostname.getHostname() + "." + hostname.getZone().getZoneName() + ": ";
log.info(slog);
hostname = this.hostnameDao.find(hostname.getId());
HostnameIP hi_candidate = this.hostnameIPDao.getHostnameIP_addressIpAvailable(hostname);
HostnameIP hi_current = this.hostnameIPDao.getHostnameIP_referencedFrom(hostname);
// check if the hostname has at least an IP (current or candidate)
if (hi_current == null & hi_candidate == null) {
log.warn(slog + "this host has no IP address allocated");
throw new HostNotHaveAnAddressIPError(slog + "this host has no IP address allocated");
}
// check if there are any candidates
if (hi_candidate == null) {
log.info(slog + "nothing to do because there is no IP candidate for hostname " + hostname.getHostname());
return;
}
if (hi_current == null) {
log.debug(slog + "do a reference switching (there was no designed ip for " + hostname.getHostname() + ")");
try {
hi_candidate = this.hostnameIPDao.reload(hi_candidate);
switchHostnameIpReference(hostname, hi_candidate, hi_candidate, writeTheFileLater);
} catch (SerialOutOfBoundException e) {
// already logged
return;
}
}
// compare the priority of the current IP and the candidate
else if (hi_candidate.isMorePriorityThan(hi_current)) {
log.debug(slog + "do a reference switching between " + hi_current.getAddressIP().getAddressIPHumanFormat() + " and " + hi_candidate.getAddressIP().getAddressIPHumanFormat());
try {
hi_current = this.hostnameIPDao.reload(hi_current);
hi_candidate = this.hostnameIPDao.reload(hi_candidate);
switchHostnameIpReference(hostname, hi_current, hi_candidate, writeTheFileLater);
} catch (SerialOutOfBoundException e) {
// already logged
return;
}
}
log.info(slog + "done");
}
@Override
public void switchHostnameIpReference(Hostname hostname, HostnameIP old, HostnameIP newer, boolean writeTheFileLater) throws ArgumentInvalidException,
SerialOutOfBoundException {
CheckerArguments.checkObject(hostname);
CheckerArguments.checkObject(old);
CheckerArguments.checkObject(newer);
log.info("Switching hostname reference: " + hostname.getHostname() + " from " + old.getAddressIP().getAddressIPHumanFormat() + " to "
+ newer.getAddressIP().getAddressIPHumanFormat());
old = this.hostnameIPDao.reload(old);
newer = this.hostnameIPDao.reload(newer);
if (newer == null) {
log.debug("Switching hostname reference: the IP that will be referenced is unknown by the system");
return;
}
if (old == null) {
log.debug("Switching hostname reference: the IP that is referenced is unknown by the system");
return;
}
// switch the reference of IPs
if (!old.equals(newer)) {
old.toDereference();
old = this.hostnameIPDao.update(old);
}
newer.toReference();
newer = this.hostnameIPDao.update(newer);
if (writeTheFileLater)
return;
// updating the DNS zone file
try {
hostname = this.hostnameDao.reloadListHostnameIP(hostname);
log.debug("Switching hostname reference: updating the DNS zone file of hostname " + hostname.getHostname());
checkADnsZoneFile(this.zoneDao.getZoneOf(hostname));
log.info("Switching hostname reference: done");
} catch (ZoneFileSystemException e) {
log.error("Switching hostname reference: can not update the zone file of " + hostname.getHostname() + " : " + e.getMessage());
throw new DnsRendundancySystemRuntimeException("Can not update the zone file of " + hostname.getHostname() + " : " + e.getMessage());
} catch (BadAddressIPException e) {
log.error("Switching hostname reference: can not update the zone file of " + hostname.getHostname() + " : " + e.getMessage());
throw new DnsRendundancySystemRuntimeException("Can not update the zone file of " + hostname.getHostname() + " : " + e.getMessage());
} catch (SshConnectionException e) {
log.error("Switching hostname reference: can not update the zone file of " + hostname.getHostname() + " : " + e.getMessage());
throw new DnsRendundancySystemRuntimeException("Can not update the zone file of " + hostname.getHostname() + " : " + e.getMessage());
} catch (TooMuchSshConnectionsOpenedException e) {
log.error("Switching hostname reference: can not update the zone file of " + hostname.getHostname() + " : " + e.getMessage());
throw new DnsRendundancySystemRuntimeException("Can not update the zone file of " + hostname.getHostname() + " : " + e.getMessage());
}
} |