Dukascopy Support Board
http://www.dukascopy.com/swiss/english/forex/jforex/forum/

Two Live Logins with Standalone API ConcurrentModificationException
http://www.dukascopy.com/swiss/english/forex/jforex/forum/viewtopic.php?f=88&t=50433
Page 1 of 1

Author:  hyperscalper [ Thu 28 Nov, 2013, 18:19 ]
Post subject:  Two Live Logins with Standalone API ConcurrentModificationException

Standalone API client on LINUX running Oracle/Sun Java Server VM JDK 7 update 45
on an Amazon Linux EC2 AMI . JForex API 2.8.0
One client already running 8 strategies.
During startup of second client process, same Live account login, different process,
I see this exception while the second client is attempting to start
its strategies, which is an identical set of strategies as the first
client process is already running.

May be simply a synchronization issue of delivering Ticks to a strategy simultaneous with an internal
Strategy list being modified, since it is intermittent?? So the additional process stuff may be a
"red herring"........

Is there some synchronization issue you can recognize, since I don't think it's a problem
on my end... ? Since these are separate processes, I don't think there is
anything I can do in my code, so could be an issue in Dukascopy API and/or
server side coding. Would appreciate if you could look into it.

HyperScalper

after call startStrategy HyperBOT_EURJPY
Waiting for Strategy HyperBOT_EURJPY
2013-11-28 16:59:25.959 ERROR LiveCurrencyMarketProcessingThread - java.util.ConcurrentModificationException
java.util.concurrent.ExecutionException: java.util.ConcurrentModificationException
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
        at com.dukascopy.dds2.greed.market.LiveCurrencyMarketProcessingThread.run(LiveCurrencyMarketProcessingThread.java:84)
Caused by: java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:926)
        at java.util.HashMap$ValueIterator.next(HashMap.java:954)
        at com.dukascopy.api.impl.connect.DCClientImpl$7.tickReceived(DCClientImpl.java:821)
        at com.dukascopy.dds2.greed.market.LiveCurrencyMarketProcessingThread$1.run(LiveCurrencyMarketProcessingThread.java:138)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)


Here is the code section where the error occurs, as a list
of Strategy instances is started. Very reliable with a single
process but, as I say, when a second process instance is started
this code throws the ConcurrentModificationException.

   final void startStrategies() {
      int numStrategies = instrumentNamesList.size();
      log("StartStrategies running "+instrumentNamesList.size()+" instances.");
      IHyperBotStrategy strategy = null;
      String instrumentName = null;
      String currency1 = null;
      String currency2 = null;
      String slashName = null;
      long id = 0;
      try {
         log("Run RemoteServerTickTimestamps");
         RemoteServerTickTimestamps remoteServerTickTimestamps = new RemoteServerTickTimestamps(); // use defaults
         id = getIClient().startStrategy(remoteServerTickTimestamps, myStrategyExceptionHandler);
         synchronized(strategiesMapMutex) {
            strategiesMap.put(new Long(id), remoteServerTickTimestamps);
         }
         log("after RemoteServerTickTimestamps");
      }
      catch(Exception e) {
         e.printStackTrace();
      }
      pause(10000);
      for (int i=0; i<numStrategies; i++) {
         Instrument instrument = null;
         instrumentName = instrumentNamesList.get(i);
         if (instrumentName.length()!=6) continue;
         boolean error = false;
         try {
            // create an Instrument
            currency1 = instrumentName.substring(0,3);
            currency2 = instrumentName.substring(3,6);
            slashName = currency1+"/"+currency2;
            log("Slashed name: "+slashName);
            instrument = Instrument.fromString(slashName);
         }
         catch(Exception e) {
            log("Error creating instrument "+instrumentName);
            error=true;
         }
         if (instrument==null || error) {
            log("ERROR INSTRUMENT "+instrumentName+" does not exist.");
            continue; // skip it
         }
         if ( !availableInstruments.contains(instrument)) {
            log("ERROR INSTRUMENT "+instrumentName+" is NOT AVAILABLE to your account.");
            continue; // skip it
         }
         masterStrategy = new HyperBot(); //RemoteServerTickTimestamps();
         masterStrategy.selectedInstrument = instrument;
         boolean validStrategy = validStrategy(masterStrategy);
         if ( !validStrategy) {
            log("Invalid HyperBot strategy failed.");
            systemExit(1);
         }
         // cast is guaranteed by validStrategy check
         strategy = (IHyperBotStrategy)masterStrategy;
         strategy.setHyperBotHost(this); // this is the host
         
         String strategyName = "HyperBOT"+"_"+instrumentName;
         strategy.setName(strategyName);
         try {
            log("call startStrategy "+strategyName);
            id = getIClient().startStrategy(masterStrategy, myStrategyExceptionHandler);
            synchronized(strategiesMapMutex) {
               strategiesMap.put(new Long(id), masterStrategy);
            }
            log("after call startStrategy "+strategyName);
         }
         catch(Exception e) {
            e.printStackTrace();
         }
         if (id==0) {
            log("Start strategy failed.");
            systemExit(1);
         }
         log("Waiting for Strategy "+strategyName);
         if (i<numStrategies) {
            pause(5000);
         }
      }
   }
   

Author:  hyperscalper [ Fri 29 Nov, 2013, 06:33 ]
Post subject:  Re: Two Live Logins with Standalone API ConcurrentModificationException

Hi, the previous post was using a 32-bit Linux JDK version, and
I recently upgraded to a 64-bit Amazon Linux EC2 AMI, having
installed version of Oracle/Sun JDK 7 Update 45 for x64
and saw this exception on startup.

In this case, there was just this single process starting up,
so no additional processes to worry about.

Again, JForex API 2.8.0

HyperScalper

after call startStrategy HyperBOT_GBPUSD
Waiting for Strategy HyperBOT_GBPUSD
2013-11-29 05:06:15.619 ERROR LiveCurrencyMarketProcessingThread - java.util.ConcurrentModificationException
java.util.concurrent.ExecutionException: java.util.ConcurrentModificationException
   at java.util.concurrent.FutureTask.report(FutureTask.java:122)
   at java.util.concurrent.FutureTask.get(FutureTask.java:188)
   at com.dukascopy.dds2.greed.market.LiveCurrencyMarketProcessingThread.run(LiveCurrencyMarketProcessingThread.java:84)
Caused by: java.util.ConcurrentModificationException
   at java.util.HashMap$HashIterator.nextEntry(HashMap.java:926)
   at java.util.HashMap$ValueIterator.next(HashMap.java:954)
   at com.dukascopy.api.impl.connect.DCClientImpl$7.tickReceived(DCClientImpl.java:821)
   at com.dukascopy.dds2.greed.market.LiveCurrencyMarketProcessingThread$1.run(LiveCurrencyMarketProcessingThread.java:138)
   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
   at java.util.concurrent.FutureTask.run(FutureTask.java:262)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
   at java.lang.Thread.run(Thread.java:744)

Author:  API Support [ Mon 09 Dec, 2013, 17:14 ]
Post subject:  Re: Two Live Logins with Standalone API ConcurrentModificationException

This is going to get fixed with JForex-API 2.9.6.

  Page 1 of 1