Example usage for com.google.common.util.concurrent ListeningExecutorService submit

List of usage examples for com.google.common.util.concurrent ListeningExecutorService submit

Introduction

In this page you can find the example usage for com.google.common.util.concurrent ListeningExecutorService submit.

Prototype

@Override
ListenableFuture<?> submit(Runnable task);

Source Link

Usage

From source file:com.google.caliper.runner.ExperimentingCaliperRun.java

/**
 * Schedule all the trials.//from  www.  j  a va2s.com
 *
 * <p>This method arranges all the {@link ScheduledTrial trials} to run according to their
 * scheduling criteria.  The executor instance is responsible for enforcing max parallelism.
 */
private List<ListenableFuture<TrialResult>> scheduleTrials(List<ScheduledTrial> trials,
        final ListeningExecutorService executor) {
    List<ListenableFuture<TrialResult>> pendingTrials = Lists.newArrayList();
    List<ScheduledTrial> serialTrials = Lists.newArrayList();
    for (final ScheduledTrial scheduledTrial : trials) {
        if (scheduledTrial.policy() == TrialSchedulingPolicy.PARALLEL) {
            pendingTrials.add(executor.submit(scheduledTrial.trialTask()));
        } else {
            serialTrials.add(scheduledTrial);
        }
    }
    // A future representing the completion of all prior tasks. Futures.successfulAsList allows us
    // to ignore failure.
    ListenableFuture<?> previous = Futures.successfulAsList(pendingTrials);
    for (final ScheduledTrial scheduledTrial : serialTrials) {
        // each of these trials can only start after all prior trials have finished, so we use
        // Futures.transform to force the sequencing.
        ListenableFuture<TrialResult> current = Futures.transform(previous,
                new AsyncFunction<Object, TrialResult>() {
                    @Override
                    public ListenableFuture<TrialResult> apply(Object ignored) {
                        return executor.submit(scheduledTrial.trialTask());
                    }
                });
        pendingTrials.add(current);
        // ignore failure of the prior task.
        previous = Futures.withFallback(current, FALLBACK_TO_NULL);
    }
    return pendingTrials;
}

From source file:com.facebook.buck.distributed.build_client.PostBuildPhase.java

@VisibleForTesting
ListenableFuture<BuildSlaveStats> publishBuildSlaveFinishedStatsEvent(BuildJob job,
        ListeningExecutorService executor, ConsoleEventsDispatcher consoleEventsDispatcher) {
    if (!job.isSetBuildSlaves()) {
        return Futures.immediateFuture(null);
    }//w w w. java 2  s  .  c o m

    List<ListenableFuture<Pair<BuildSlaveRunId, Optional<BuildSlaveFinishedStats>>>> slaveFinishedStatsFutures = new ArrayList<>(
            job.getBuildSlavesSize());
    for (BuildSlaveInfo info : job.getBuildSlaves()) {
        BuildSlaveRunId runId = info.getBuildSlaveRunId();
        slaveFinishedStatsFutures.add(executor.submit(() -> {
            Optional<BuildSlaveFinishedStats> stats = fetchStatsForIndividualSlave(job, runId);
            return new Pair<BuildSlaveRunId, Optional<BuildSlaveFinishedStats>>(runId, stats);
        }));
    }

    Builder builder = BuildSlaveStats.builder().setStampedeId(job.getStampedeId());
    return Futures.transform(Futures.allAsList(slaveFinishedStatsFutures),
            statsList -> createAndPublishBuildSlaveStats(builder, statsList, consoleEventsDispatcher),
            MoreExecutors.directExecutor());
}

From source file:org.jclouds.examples.rackspace.cloudfiles.UploadDirectoryToCDN.java

/**
 * Upload the files in parallel.//from  w ww  . j  a v a  2 s.c o  m
 */
private void uploadFiles(String container, List<BlobDetail> blobDetails)
        throws InterruptedException, ExecutionException {
    ListeningExecutorService executor = MoreExecutors.listeningDecorator(newFixedThreadPool(THREADS));
    List<ListenableFuture<BlobDetail>> blobUploaderFutures = Lists.newArrayList();
    BlobUploaderCallback blobUploaderCallback = new BlobUploaderCallback();

    try {

        for (BlobDetail blobDetail : blobDetails) {
            BlobUploader blobUploader = new BlobUploader(container, blobDetail);
            ListenableFuture<BlobDetail> blobDetailFuture = executor.submit(blobUploader);
            blobUploaderFutures.add(blobDetailFuture);

            Futures.addCallback(blobDetailFuture, blobUploaderCallback);
        }

        ListenableFuture<List<BlobDetail>> future = Futures.successfulAsList(blobUploaderFutures);
        List<BlobDetail> uploadedBlobDetails = future.get(); // begin the upload

        System.out.format("%n");

        for (int i = 0; i < uploadedBlobDetails.size(); i++) {
            if (uploadedBlobDetails.get(i) != null) {
                BlobDetail blobDetail = uploadedBlobDetails.get(i);
                System.out.format("  %s (eTag: %s)%n", blobDetail.getRemoteBlobName(), blobDetail.getETag());
            } else {
                System.out.format(" %s (ERROR)%n", blobDetails.get(i).getLocalFile().getAbsolutePath());
            }
        }
    } finally {
        executor.shutdown();
    }
}

From source file:com.cloudera.oryx.kmeans.computation.local.WeightedPointsByFold.java

@Override
public List<List<WeightedRealVector>> call() throws InterruptedException, ExecutionException {
    Config config = ConfigUtils.getDefaultConfig();
    ClusterSettings cluster = ClusterSettings.create(config);
    KSketchIndex index = buildIndex(foldVecs, cluster);
    int pointsPerIteration = cluster.getSketchPoints();
    RandomGenerator random = RandomManager.getRandom();

    ListeningExecutorService exec = MoreExecutors
            .listeningDecorator(Executors.newFixedThreadPool(config.getInt("model.parallelism"),
                    new ThreadFactoryBuilder().setNameFormat("KSKETCH-%d").setDaemon(true).build()));
    for (int iter = 0; iter < cluster.getSketchIterations(); iter++) {
        log.info("Starting sketch iteration {}", iter + 1);
        List<ListenableFuture<Collection<RealVector>>> futures = Lists.newArrayList();
        for (int foldId = 0; foldId < foldVecs.size(); foldId++) {
            futures.add(exec
                    .submit(new SamplingRun(index, random, foldId, foldVecs.get(foldId), pointsPerIteration)));
        }/*w  w  w .  j  a v  a 2  s.c o  m*/
        // At the end of each iteration, gather up the sampled points to add to the index
        Future<List<Collection<RealVector>>> all = Futures.allAsList(futures);
        try {
            List<Collection<RealVector>> newSamples = all.get();
            for (int foldId = 0; foldId < foldVecs.size(); foldId++) {
                for (RealVector v : newSamples.get(foldId)) {
                    index.add(v, foldId);
                }
            }
        } catch (ExecutionException e) {
            ExecutorUtils.shutdownNowAndAwait(exec);
            all.cancel(true);
            throw e;
        }
        index.rebuildIndices();
    }

    List<ListenableFuture<List<WeightedRealVector>>> ret = Lists.newArrayList();
    for (int foldId = 0; foldId < foldVecs.size(); foldId++) {
        ret.add(exec.submit(new AssignmentRun(index, foldId, foldVecs.get(foldId))));
    }
    try {
        return Futures.allAsList(ret).get();
    } finally {
        ExecutorUtils.shutdownNowAndAwait(exec);
    }
}

From source file:org.glowroot.central.RollupService.java

private List<Future<?>> rollupAggregates(AgentRollup agentRollup, ListeningExecutorService workerExecutor) {
    List<Future<?>> futures = new ArrayList<>();
    // randomize order so that multiple central collector nodes will be less likely to perform
    // duplicative work
    for (AgentRollup childAgentRollup : shuffle(agentRollup.children())) {
        futures.addAll(rollupAggregates(childAgentRollup, workerExecutor));
    }/* w  ww  .  j a v a 2 s.  co m*/
    futures.add(workerExecutor.submit(new Runnable() {
        @Override
        public void run() {
            try {
                aggregateDao.rollup(agentRollup.id());
            } catch (InterruptedException e) {
                // probably shutdown requested (see close method above)
            } catch (Throwable t) {
                logger.error("{} - {}", agentRollup.id(), t.getMessage(), t);
            }
        }
    }));
    return futures;
}

From source file:com.microsoft.azuretools.azureexplorer.forms.createrediscache.CreateRedisCacheForm.java

@Override
protected void okPressed() {
    try {// w ww  . ja  v  a 2 s  . c  om
        if (!RedisCacheUtil.doValidate(azureManager, currentSub, dnsNameValue, selectedLocationValue,
                selectedResGrpValue, selectedPriceTierValue)) {
            return;
        }
        Azure azure = azureManager.getAzure(currentSub.getSubscriptionId());
        ProcessingStrategy processor = RedisCacheUtil.doGetProcessor(azure, skus, dnsNameValue,
                selectedLocationValue, selectedResGrpValue, selectedPriceTierValue, noSSLPort, newResGrp);
        ExecutorService executor = Executors.newSingleThreadExecutor();
        ListeningExecutorService executorService = MoreExecutors.listeningDecorator(executor);
        ListenableFuture<Void> futureTask = executorService.submit(new CreateRedisCacheCallable(processor));
        final ProcessingStrategy processorInner = processor;
        Futures.addCallback(futureTask, new FutureCallback<Void>() {
            @Override
            public void onSuccess(Void arg0) {
                if (onCreate != null) {
                    onCreate.run();
                }
            }

            @Override
            public void onFailure(Throwable throwable) {
                JOptionPane.showMessageDialog(null, throwable.getMessage(),
                        String.format(MessageHandler.getResourceString(resourceBundle,
                                CREATING_ERROR_INDICATOR_FORMAT), dnsNameValue),
                        JOptionPane.ERROR_MESSAGE, null);
                try {
                    processorInner.notifyCompletion();
                } catch (InterruptedException ex) {
                    LOG.log("Error occurred while notifyCompletion in RedisCache.", ex);
                }
            }
        });
    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null, ex.getMessage(),
                String.format(MessageHandler.getResourceString(resourceBundle, CREATING_ERROR_INDICATOR_FORMAT),
                        dnsNameValue),
                JOptionPane.ERROR_MESSAGE, null);
        LOG.log(String.format(MessageHandler.getResourceString(resourceBundle, CREATING_ERROR_INDICATOR_FORMAT),
                dnsNameValue), ex);
    }
    super.okPressed();
}

From source file:org.apache.brooklyn.core.entity.Entities.java

/**
 * Stops, destroys, and unmanages all apps in the given context, and then terminates the management context.
 * // www  . j a  v  a 2s.c  om
 * Apps will be stopped+destroyed+unmanaged concurrently, waiting for all to complete.
 */
public static void destroyAll(final ManagementContext mgmt) {
    if (mgmt instanceof NonDeploymentManagementContext) {
        // log here because it is easy for tests to destroyAll(app.getMgmtContext())
        // which will *not* destroy the mgmt context if the app has been stopped!
        log.warn("Entities.destroyAll invoked on non-deployment " + mgmt + " - not likely to have much effect! "
                + "(This usually means the mgmt context has been taken from an entity that has been destroyed. "
                + "To destroy other things on the management context ensure you keep a handle to the context "
                + "before the entity is destroyed, such as by creating the management context first.)");
    }
    if (!mgmt.isRunning())
        return;

    ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
    List<ListenableFuture<?>> futures = Lists.newArrayList();
    final AtomicReference<Exception> error = Atomics.newReference();
    try {
        log.debug("destroying all apps in " + mgmt + ": " + mgmt.getApplications());
        for (final Application app : mgmt.getApplications()) {
            futures.add(executor.submit(new Runnable() {
                public void run() {
                    log.debug("destroying app " + app + " (managed? " + isManaged(app) + "; mgmt is " + mgmt
                            + ")");
                    try {
                        destroy(app);
                        log.debug("destroyed app " + app + "; mgmt now " + mgmt);
                    } catch (Exception e) {
                        log.warn("problems destroying app " + app + " (mgmt now " + mgmt
                                + ", will rethrow at least one exception): " + e);
                        error.compareAndSet(null, e);
                    }
                }
            }));
        }
        Futures.allAsList(futures).get();

        for (Location loc : mgmt.getLocationManager().getLocations()) {
            destroyCatching(loc);
        }
        if (mgmt instanceof ManagementContextInternal) {
            ((ManagementContextInternal) mgmt).terminate();
        }
        if (error.get() != null)
            throw Exceptions.propagate(error.get());
    } catch (Exception e) {
        if (!mgmt.isRunning()) {
            // we've checked this above so it would only happen if a different thread stopped it;
            // this does happen sometimes e.g. in CliTest where the server shutdown occurs concurrently
            log.debug(
                    "Destroying apps gave an error, but mgmt context was concurrently stopped so not really a problem; swallowing (unless fatal): "
                            + e);
            Exceptions.propagateIfFatal(e);
        } else {
            throw Exceptions.propagate(e);
        }
    } finally {
        executor.shutdownNow();
    }
}

From source file:org.apache.abdera2.common.protocol.Session.java

/**
 * Processes requests asynchronously.. will return a Future
 * whose value will be set once the call completes
 *//*from  ww  w .j a v a2  s  .  co  m*/
public <X extends ClientResponse> Future<X> process(ExecutorService executor, Callable<X> resp) {
    ListeningExecutorService exec = MoreExecutors.listeningDecorator(executor);
    return exec.submit(resp);
}

From source file:com.google.idea.blaze.java.libraries.JarCache.java

private void refresh(@Nullable BlazeContext context, boolean removeMissingFiles) {
    if (!enabled || sourceFileToCacheKey == null) {
        return;//w  w w  .  j ava  2s .c o m
    }

    // Ensure the cache dir exists
    if (!cacheDir.exists()) {
        if (!cacheDir.mkdirs()) {
            LOG.error("Could not create jar cache directory");
            return;
        }
    }

    // Discover state of source jars
    ImmutableMap<File, Long> sourceFileTimestamps = FileDiffer.readFileState(sourceFileToCacheKey.keySet());
    if (sourceFileTimestamps == null) {
        return;
    }
    ImmutableMap.Builder<String, Long> sourceFileCacheKeyToTimestamp = ImmutableMap.builder();
    for (Map.Entry<File, Long> entry : sourceFileTimestamps.entrySet()) {
        String cacheKey = sourceFileToCacheKey.get(entry.getKey());
        sourceFileCacheKeyToTimestamp.put(cacheKey, entry.getValue());
    }

    // Discover current on-disk cache state
    File[] cacheFiles = cacheDir.listFiles();
    assert cacheFiles != null;
    ImmutableMap<File, Long> cacheFileTimestamps = FileDiffer.readFileState(Lists.newArrayList(cacheFiles));
    if (cacheFileTimestamps == null) {
        return;
    }
    ImmutableMap.Builder<String, Long> cachedFileCacheKeyToTimestamp = ImmutableMap.builder();
    for (Map.Entry<File, Long> entry : cacheFileTimestamps.entrySet()) {
        String cacheKey = entry.getKey().getName(); // Cache key == file name
        cachedFileCacheKeyToTimestamp.put(cacheKey, entry.getValue());
    }

    List<String> updatedFiles = Lists.newArrayList();
    List<String> removedFiles = Lists.newArrayList();
    FileDiffer.diffState(cachedFileCacheKeyToTimestamp.build(), sourceFileCacheKeyToTimestamp.build(),
            updatedFiles, removedFiles);

    ListeningExecutorService executor = FetchExecutor.EXECUTOR;
    List<ListenableFuture<?>> futures = Lists.newArrayList();
    Map<String, File> cacheKeyToSourceFile = sourceFileToCacheKey.inverse();
    for (String cacheKey : updatedFiles) {
        File sourceFile = cacheKeyToSourceFile.get(cacheKey);
        File cacheFile = cacheFileForKey(cacheKey);
        futures.add(executor.submit(() -> {
            try {
                Files.copy(Paths.get(sourceFile.getPath()), Paths.get(cacheFile.getPath()),
                        StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
            } catch (IOException e) {
                LOG.warn(e);
            }
        }));
    }

    if (removeMissingFiles) {
        for (String cacheKey : removedFiles) {
            File cacheFile = cacheFileForKey(cacheKey);
            futures.add(executor.submit(() -> {
                try {
                    Files.deleteIfExists(Paths.get(cacheFile.getPath()));
                } catch (IOException e) {
                    LOG.warn(e);
                }
            }));
        }
    }

    try {
        Futures.allAsList(futures).get();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        LOG.warn(e);
    } catch (ExecutionException e) {
        LOG.error(e);
    }
    if (context != null && updatedFiles.size() > 0) {
        context.output(PrintOutput.log(String.format("Copied %d jars", updatedFiles.size())));
    }
    if (context != null && removedFiles.size() > 0 && removeMissingFiles) {
        context.output(PrintOutput.log(String.format("Removed %d jars", removedFiles.size())));
    }
    if (context != null) {
        try {
            File[] finalCacheFiles = cacheDir.listFiles();
            assert finalCacheFiles != null;
            ImmutableMap<File, Long> cacheFileSizes = FileSizeScanner
                    .readFilesizes(Lists.newArrayList(finalCacheFiles));
            Long total = cacheFileSizes.values().stream().reduce((size1, size2) -> size1 + size2).orElse(0L);
            context.output(PrintOutput.log(String.format("Total Jar Cache size: %d kB (%d files)", total / 1024,
                    finalCacheFiles.length)));
        } catch (Exception e) {
            LOG.warn("Could not determine cache size", e);
        }
    }
}

From source file:org.multibit.viewsystem.swing.action.SendBitcoinConfirmAction.java

/**
 * Complete the transaction to work out the fee) and then show the send bitcoin confirm dialog.
 *///from w ww.j  ava2  s.c o  m
@Override
public void actionPerformed(ActionEvent e) {
    if (abort()) {
        return;
    }

    //        SendBitcoinConfirmDialog sendBitcoinConfirmDialog = null;
    ValidationErrorDialog validationErrorDialog = null;

    try {
        String sendAddress = dataProvider.getAddress();
        String sendAmount = dataProvider.getAmount();
        String sendMessage = null;
        boolean canSendMessage = false;

        /*CoinSpark START */
        CoinSparkPaymentRef paymentRef = null;

        /*
         If the address is a coinspark address, retrieve the bitcoin address and let the validator check it.
         The SendRequest object will use the bitcoin address, while the confirmation dialog will use
         whatever is displayed in the address text field i.e. coinspark address, if there is one.
         For reference, you can see what is in the textfield, which has been saved in prefs:
         String address = this.bitcoinController.getModel().getActiveWalletPreference(BitcoinModel.SEND_ADDRESS
         */
        if (sendAddress.startsWith("s")) {
            CoinSparkAddress csa = CSMiscUtils.decodeCoinSparkAddress(sendAddress);
            String btcAddress = CSMiscUtils.getBitcoinAddressStringFromCoinSparkAddress(csa);
            if (btcAddress != null) {
                sendAddress = btcAddress; // the validator will check the btcAddress like normal.
            }

            // Does a payment ref exist?
            int flags = csa.getAddressFlags();
            if ((flags & CoinSparkAddress.COINSPARK_ADDRESS_FLAG_PAYMENT_REFS) > 0) {
                paymentRef = csa.getPaymentRef();
            }

            // Messages - can send message and BTC to CoinSpark address, without any assets.
            sendMessage = ((AssetFormDataProvider) dataProvider).getMessage();
            canSendMessage = (flags & CoinSparkAddress.COINSPARK_ADDRESS_FLAG_TEXT_MESSAGES) > 0;
        }
        /*CoinSpark END */

        Validator validator = new Validator(super.bitcoinController);
        if (validator.validate(sendAddress, sendAmount)) {
            // The address and amount are valid.

            // Create a SendRequest.
            Address sendAddressObject;

            sendAddressObject = new Address(bitcoinController.getModel().getNetworkParameters(), sendAddress);
            final SendRequest sendRequest = SendRequest.to(sendAddressObject, Utils.toNanoCoins(sendAmount));
            //                SendRequest sendRequest = SendRequest.to(sendAddressObject, Utils.toNanoCoins(sendAmount), 6, new BigInteger("10000"),1);
            sendRequest.ensureMinRequiredFee = true;
            sendRequest.fee = BigInteger.ZERO;
            sendRequest.feePerKb = BitcoinModel.SEND_FEE_PER_KB_DEFAULT;

            // Note - Request is populated with the AES key in the SendBitcoinNowAction after the user has entered it on the SendBitcoinConfirm form.

            // Send with payment ref - if it exists and is not 0 which SparkBit treats semantically as null
            if (paymentRef != null && paymentRef.getRef() != 0) {
                sendRequest.setPaymentRef(paymentRef);
            }

            // Send a message if the address will take it and message is not empty
            boolean willSendMessage = false;
            if (canSendMessage) {
                boolean isEmptyMessage = false;
                if (sendMessage == null || sendMessage.isEmpty() || sendMessage.trim().length() == 0) {
                    isEmptyMessage = true;
                }
                if (!isEmptyMessage) {
                    willSendMessage = true;
                    CoinSparkMessagePart[] parts = {
                            CSMiscUtils.createPlainTextCoinSparkMessagePart(sendMessage) };
                    String[] serverURLs = CSMiscUtils.getMessageDeliveryServersArray(bitcoinController);
                    sendRequest.setMessage(parts, serverURLs);

                    log.debug(">>>> Messaging servers = " + ArrayUtils.toString(serverURLs));
                    log.debug(">>>> parts[0] = " + parts[0]);
                    log.debug(">>>> parts[0].fileName = " + parts[0].fileName);
                    log.debug(">>>> parts[0].mimeType = " + parts[0].mimeType);
                    log.debug(">>>> parts[0].content = " + new String(parts[0].content, "UTF-8"));
                    //String message = "Hello, the time is now..." + DateTime.now().toString();
                    //      parts[2].fileName = imagePath;
                    //      parts[2].mimeType = "image/png";
                    //      byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath));
                    //      parts[2].content = imageBytes;

                }
            }

            //
            // When sending a message, show a modal dialog.
            // CompleteTX now occurs in background thread so UI does not block
            // when "Send" is clicked with widget updates frozen.
            //

            // Show dialog with indeterminate progress bar
            final JDialog dialog = CSMiscUtils.createModalMessageDialogWithIndeterminateProgress(mainFrame,
                    "SparkBit", "Contacting message delivery servers...");
            // Dialog is made visible after futures have been set up

            ListeningExecutorService service = MoreExecutors
                    .listeningDecorator(Executors.newSingleThreadExecutor()); //newFixedThreadPool(10));
            ListenableFuture<Boolean> future = service.submit(new Callable<Boolean>() {
                public Boolean call() throws Exception {
                    try {
                        // Complete it (which works out the fee) but do not sign it yet.
                        log.debug("Just about to complete the tx (and calculate the fee)...");
                        bitcoinController.getModel().getActiveWallet().completeTx(sendRequest, false);
                        log.debug("The fee after completing the transaction was " + sendRequest.fee);

                    } catch (Exception e) {
                        throw e;
                    }
                    return true;
                }
            });

            Futures.addCallback(future, new FutureCallback<Boolean>() {
                public void onSuccess(Boolean b) {

                    // There is enough money.
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            dialog.dispose();

                            SendBitcoinConfirmDialog mySendBitcoinConfirmDialog = new SendBitcoinConfirmDialog(
                                    bitcoinController, mainFrame, sendRequest);
                            mySendBitcoinConfirmDialog.setVisible(true);
                        }
                    });

                }

                public void onFailure(Throwable thrown) {
                    final String failureReason = thrown.getMessage();
                    final boolean isCSException = thrown instanceof org.coinspark.core.CSExceptions.CannotEncode;
                    final boolean isInsufficientMoney = thrown instanceof com.google.bitcoin.core.InsufficientMoneyException;
                    // There is not enough money.
                    // TODO setup validation parameters accordingly so that it displays ok.
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            dialog.dispose();

                            if (isCSException) {
                                JOptionPane
                                        .showMessageDialog(mainFrame,
                                                "SparkBit is unable to proceed with this transaction:\n\n"
                                                        + failureReason,
                                                "SparkBit Error", JOptionPane.ERROR_MESSAGE);
                            } else if (isInsufficientMoney) {
                                // Try to show a human friendly message, need to pass the missing satoshis from failure reason.
                                try {
                                    String numberOnly = failureReason.replaceAll("[^0-9]", "");
                                    BigInteger needed = new BigInteger(numberOnly);
                                    JOptionPane.showMessageDialog(mainFrame,
                                            "SparkBit is unable to proceed with this transaction.\n\nInsufficient money in wallet, require "
                                                    + Utils.bitcoinValueToFriendlyString(needed) + " BTC more.",
                                            "SparkBit Error", JOptionPane.ERROR_MESSAGE);
                                } catch (NumberFormatException e) {
                                    ValidationErrorDialog myValidationErrorDialog = new ValidationErrorDialog(
                                            bitcoinController, mainFrame, sendRequest, true);
                                    myValidationErrorDialog.setVisible(true);
                                }
                            } else {
                                ValidationErrorDialog myValidationErrorDialog = new ValidationErrorDialog(
                                        bitcoinController, mainFrame, sendRequest, true);
                                myValidationErrorDialog.setVisible(true);
                            }
                        }
                    });
                }
            });

            // Show message server dialog only if we are going to send
            if (willSendMessage) {
                dialog.setVisible(true);
            }

            /*      
                            // Complete it (which works out the fee) but do not sign it yet.
                            log.debug("Just about to complete the tx (and calculate the fee)...");
                            boolean completedOk;
                            try {
            bitcoinController.getModel().getActiveWallet().completeTx(sendRequest, false);
                              completedOk = true;
                              log.debug("The fee after completing the transaction was " + sendRequest.fee);
                            } catch (InsufficientMoneyException ime) {
                              completedOk = false;
                            }
                            if (completedOk) {
            // There is enough money.
                    
            sendBitcoinConfirmDialog = new SendBitcoinConfirmDialog(super.bitcoinController, mainFrame, sendRequest);
            sendBitcoinConfirmDialog.setVisible(true);
                            } else {
            // There is not enough money.
            // TODO setup validation parameters accordingly so that it displays ok.
            validationErrorDialog = new ValidationErrorDialog(super.bitcoinController, mainFrame, sendRequest, true);
            validationErrorDialog.setVisible(true);
                            }
               */

        } else {
            validationErrorDialog = new ValidationErrorDialog(super.bitcoinController, mainFrame, null, false);
            validationErrorDialog.setVisible(true);
        }
    } catch (WrongNetworkException e1) {
        logMessage(e1);
    } catch (AddressFormatException e1) {
        logMessage(e1);
    } catch (KeyCrypterException e1) {
        logMessage(e1);
    } catch (Exception e1) {
        logMessage(e1);
    }
}