2017-01-27 3 views
1

J'ai un projet, disons projectA qui avait un composant HTTP qui exposait sa logique aux clients.Le pilote Mongodb avec la bibliothèque mongodb bson provoque l'exécution de completableFuture lorsqu'il est utilisé dans des projets distincts

Dans ce projet, il y a un code comme tel:

void syncMethod() { 
    CompletableFuture<Void> f = new CompletableFuture<>(); 
    someAsyncOperationThatReceivesACallback((Void x, Exception ex) -> { 
    if(ex != null) f.completeExceptionally(ex); 
    else f.complete(null); // An example of a result. 
    }); 
    f.get(); // Wait unconditionally 
} 

Ce code fonctionne, comme il attend la fin de l'opération et l'avenir est complétée par le résultat de l'opération async.

Le besoin se faisait sentir de partager la logique entre 2 webapps et donc je me suis séparé projectA dans 2 projets, disons projectA-LOGIC et projectA-HTTPprojectA-HTTP.dependsOn(projectA-LOGIC)

Avoir le point d'entrée dans projectA-HTTP et le code ci-dessus dans le JAR emballé de projectA-LOGIC le code ci-dessus a cessé de se terminer, ce qui signifie que le futur n'est jamais terminé et l'application se trouve juste là.

Si toutefois je crée un point d'entrée dans projectA-LOGIC et exécutez le code ci-dessus tout fonctionne.

Je ne comprends pas la magie qui se passe ici. Actuellement en utilisant jdk8_111. L'opération asynchrone décrite ci-dessus provient du mongodb async driver et est listCollectionNames. Toutes les opérations asynchrones (via callback) que j'essaye de faire synchroniser en utilisant des futurs subissent le même comportement quand j'ai 2 projets.

EDIT:

décharge du fil:

vidage filet plein

"[email protected]" prio=5 tid=0x1 nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at sun.misc.Unsafe.park(Unsafe.java:-1) 
     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
     at java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1693) 
     at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323) 
     at java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1729) 
     at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) 

"cluster-ClusterId{value='588bc56a32de912224244114', description='null'}-127.0.0.1:[email protected]" daemon prio=5 tid=0xf nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at sun.misc.Unsafe.park(Unsafe.java:-1) 
     at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) 
     at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.waitForSignalOrTimeout(DefaultServerMonitor.java:238) 
     at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.waitForNext(DefaultServerMonitor.java:219) 
     at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:168) 
     - locked <0x10fe> (a com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x15 nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at sun.misc.Unsafe.park(Unsafe.java:-1) 
     at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1037) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1328) 
     at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:277) 
     at com.mongodb.connection.BaseCluster$WaitQueueHandler.run(BaseCluster.java:464) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x14 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x13 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x12 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x11 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x10 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=8 tid=0x3 nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at java.lang.Object.wait(Object.java:-1) 
     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) 
     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) 
     at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) 

"Reference [email protected]" daemon prio=10 tid=0x2 nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at java.lang.Object.wait(Object.java:-1) 
     at java.lang.Object.wait(Object.java:502) 
     at java.lang.ref.Reference.tryHandlePending(Reference.java:191) 
     at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) 

"Attach [email protected]" daemon prio=5 tid=0x5 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 

"Signal [email protected]" daemon prio=9 tid=0x4 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 

Ce que je ne comprends pas comment cela peut-il arriver juste en spliting le code dans des projets distincts. Pensez que je manque un détail subtil sur CompletableFutures ...

+0

Je ne peux pas vraiment dire ce que cela pourrait être, mais je chercherais une impasse. Vérifiez également si rien d'autre n'utilise les threads du pool de threads commun. IIRC CompletableFuture utilise des threads du pool commun - peut-être essayer d'utiliser un pool séparé. – john16384

+0

Voilà ce que je pense à, Ajout de vidage de thread. Mais j'aimerais comprendre ce qui se passe. – pedromss

+0

Si c'est le vidage de thread, alors je ne pense pas que votre code soit en cours d'exécution, ce sont deux threads JVM uniquement. – john16384

Répondre

0

Le problème s'est avéré être beaucoup plus simple et (plus bête) que tout ce à quoi je m'attendais. J'ai utilisé le pilote asynchrone mongodb v3.2.1 et en utilisant la bibliothèque mongodb bson v3.4.1. Il s'avère que lorsque j'ai changé la version de la bibliothèque bson en v3.2.1 tout a bien fonctionné.