use of com.vaklinov.zcashui.ZCashClientCaller.WalletCallException in project zencash-swing-wallet-ui by ZencashOfficial.
the class MessagingPanel method sendMessage.
// String textToSend - if null, taken from the text area
// MessagingIdentity remoteIdentity - if null selection is taken
private void sendMessage(String textToSend, MessagingIdentity remoteIdentity) throws IOException, WalletCallException, InterruptedException {
boolean sendAnonymously = this.sendAnonymously.isSelected();
boolean sendReturnAddress = false;
boolean updateMessagingIdentityJustBeforeSend = false;
// Make sure contacts are available
if (this.contactList.getNumberOfContacts() <= 0) {
JOptionPane.showMessageDialog(this.parentFrame, "You have no messaging contacts in your contact list. To use messaging\n" + "you need to add at least one contact. You can add a contact by importing\n" + "their messaging identity using the menu item Messaging >> Import contact \n" + "identity.", "No messaging contacts available...", JOptionPane.ERROR_MESSAGE);
return;
}
if ((remoteIdentity == null) && (this.contactList.getSelectedContact() == null)) {
JOptionPane.showMessageDialog(this.parentFrame, "No messaging contact is selected in the contact list (on the right side of the UI).\n" + "In order to send an outgoing message you need to select a contact to send it to!", "No messaging contact is selected...", JOptionPane.ERROR_MESSAGE);
return;
}
// Create a copy of the identity to make sure changes made temporarily to do get reflected until
// storage s updated (such a change may be setting a Z address)
final MessagingIdentity contactIdentity = (remoteIdentity != null) ? remoteIdentity.getCloneCopy() : this.contactList.getSelectedContact().getCloneCopy();
// Make sure contact identity is full (not Unknown with no address to send to)
if (Util.stringIsEmpty(contactIdentity.getSendreceiveaddress())) {
String errroMessage = "The messaging contact selected: " + contactIdentity.getDiplayString() + "\n" + "seems to have no valid Z address for sending and receiving messages. \n";
errroMessage += contactIdentity.isAnonymous() ? ("Since the contact is anonymous this means that the contact intentionally did\n" + "not send his Z address (for replies to be psosible). Message cannot be sent!") : ("Most likely the reason is that this contact's messaging identity is not \n" + "imported yet. Message cannot be sent!");
JOptionPane.showMessageDialog(this.parentFrame, errroMessage, "Selected contact has to Z address to send message to!", JOptionPane.ERROR_MESSAGE);
return;
}
// set for the recipient. Also ask the user if he wishes to send a return address.
if (sendAnonymously) {
// If also no thread ID is set yet...
if (Util.stringIsEmpty(contactIdentity.getThreadID())) {
if (!contactIdentity.isGroup()) {
// Offer the user to send a return address
int reply = JOptionPane.showConfirmDialog(this.parentFrame, "This is the first anomymous message you are sending to contact: \n" + contactIdentity.getDiplayString() + "\n" + "Do you wish to send him your send/receive messaging Z address so\n" + "that the contact may be able to answer your anonymous messages?", "Send return address?", JOptionPane.YES_NO_OPTION);
if (reply == JOptionPane.YES_OPTION) {
sendReturnAddress = true;
}
}
String threadID = UUID.randomUUID().toString();
contactIdentity.setThreadID(threadID);
// will have a thread ID set on the first arriving message!
if (contactIdentity.isGroup() || (!Util.stringIsEmpty(contactIdentity.getSenderidaddress()))) {
updateMessagingIdentityJustBeforeSend = true;
} else {
JOptionPane.showMessageDialog(this.parentFrame, "The contact: " + contactIdentity.getDiplayString() + "\n" + "has no message identification T address. It is not possible to \n" + "send a message!", "Contact has no message identification T address", JOptionPane.ERROR_MESSAGE);
return;
}
}
} else {
// Check to make sure a normal message is not being sent to an anonymous identity
if (contactIdentity.isAnonymous()) {
int reply = JOptionPane.showConfirmDialog(this.parentFrame, "The contact: " + contactIdentity.getDiplayString() + "\n" + "is anonymous. However you are about to send a message to him\n" + "that includes your sender identification T address. Are you sure\n" + "you wish to send him the message?", "Send message releavling your sender identification T address?", JOptionPane.YES_NO_OPTION);
if (reply == JOptionPane.NO_OPTION) {
return;
}
}
}
// Get the text to send as a message
if (textToSend == null) {
textToSend = this.writeMessageTextArea.getText();
}
if (textToSend.length() <= 0) {
JOptionPane.showMessageDialog(this.parentFrame, "You have not written any text for a message to be sent. Please write some text\n" + "in the message text field...", "Message text is empty", JOptionPane.ERROR_MESSAGE);
return;
}
// Make sure there is not another send operation going on - at this time
if ((this.operationStatusTimer != null) || (!this.sendButton.isEnabled())) {
JOptionPane.showMessageDialog(this.parentFrame, "There is currently another message sending operation under way.\n" + "Please wait until the operation is completed...", "Another message sending operation is under way!", JOptionPane.ERROR_MESSAGE);
return;
}
// Disable sending controls, set status.
this.sendButton.setEnabled(false);
this.writeMessageTextArea.setEnabled(false);
// Form the JSON message to be sent
MessagingIdentity ownIdentity = this.messagingStorage.getOwnIdentity();
MessagingOptions msgOptions = this.messagingStorage.getMessagingOptions();
// Check to make sure the sending address has some funds!!!
final double minimumBalance = msgOptions.getAmountToSend() + msgOptions.getTransactionFee();
Double balance = null;
Double unconfirmedBalance = null;
Cursor oldCursor = this.parentFrame.getCursor();
try {
this.parentFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
balance = Double.valueOf(this.clientCaller.getBalanceForAddress(ownIdentity.getSendreceiveaddress()));
unconfirmedBalance = Double.valueOf(this.clientCaller.getUnconfirmedBalanceForAddress(ownIdentity.getSendreceiveaddress()));
} finally {
this.parentFrame.setCursor(oldCursor);
}
if ((balance < minimumBalance) && (unconfirmedBalance < minimumBalance)) {
Log.warning("Sending address has balance: {0} and unconfirmed balance: {1}", balance, unconfirmedBalance);
JOptionPane.showMessageDialog(this.parentFrame, "The Z address used to send/receive messages has insufficient balance: \n" + ownIdentity.getSendreceiveaddress() + "\n" + "You will be redirected to the UI tab for sending ZEN to add some balance to it. You need only\n" + "a small amount e.g. typically 0.1 ZEN is suffucient to send 500 messages. After sending some\n" + "ZEN you need to wait for the transaciton to be confirmed (typically takes 2.5 minutes). It is\n" + "recommended to send ZEN to this Z address in two or more separate transactions (though one \n" + "transaction is sufficient).", "Z address to send/receive messages has insufficient balance...", JOptionPane.ERROR_MESSAGE);
// Restore controls and move to the send cash tab etc.
this.sendButton.setEnabled(true);
this.writeMessageTextArea.setEnabled(true);
sendCashPanel.prepareForSending(ownIdentity.getSendreceiveaddress());
parentTabs.setSelectedIndex(3);
return;
}
if ((balance < minimumBalance) && (unconfirmedBalance >= minimumBalance)) {
Log.warning("Sending address has balance: {0} and unconfirmed balance: {1}", balance, unconfirmedBalance);
JOptionPane.showMessageDialog(this.parentFrame, "The Z address used to send/receive messages has insufficient confirmed balance: \n" + ownIdentity.getSendreceiveaddress() + "\n" + "This usually means that the previous mesasaging transaction is not yet confirmed. You\n" + "need to wait for the transaciton to be confirmed (typically takes 2.5 minutes). This\n" + "problem may be avoided if you send ZEN to this Z address in two or more separate \n" + "transactions (when you supply the ZEN balance to be used for messaging).", "Z address to send/receive messages has insufficient confirmed balance...", JOptionPane.ERROR_MESSAGE);
// Restore controls and move to the send cash tab etc.
this.sendButton.setEnabled(true);
this.writeMessageTextArea.setEnabled(true);
return;
}
String memoString = null;
JsonObject jsonInnerMessage = null;
if (sendAnonymously) {
// Form an anonymous message
jsonInnerMessage = new JsonObject();
jsonInnerMessage.set("ver", 1d);
jsonInnerMessage.set("message", textToSend);
jsonInnerMessage.set("threadid", contactIdentity.getThreadID());
if (sendReturnAddress) {
jsonInnerMessage.set("returnaddress", ownIdentity.getSendreceiveaddress());
}
JsonObject jsonOuterMessage = new JsonObject();
jsonOuterMessage.set("zenmsg", jsonInnerMessage);
memoString = jsonOuterMessage.toString();
} else {
// Sign a HEX encoded message ... to avoid possible UNICODE issues
String signature = this.clientCaller.signMessage(ownIdentity.getSenderidaddress(), Util.encodeHexString(textToSend).toUpperCase());
jsonInnerMessage = new JsonObject();
jsonInnerMessage.set("ver", 1d);
jsonInnerMessage.set("from", ownIdentity.getSenderidaddress());
jsonInnerMessage.set("message", textToSend);
jsonInnerMessage.set("sign", signature);
JsonObject jsonOuterMessage = new JsonObject();
jsonOuterMessage.set("zenmsg", jsonInnerMessage);
memoString = jsonOuterMessage.toString();
}
final JsonObject jsonInnerMessageForFurtherUse = jsonInnerMessage;
// Check the size of the message to be sent, error if it exceeds.
final int maxSendingLength = 512;
int overallSendingLength = memoString.getBytes("UTF-8").length;
if (overallSendingLength > maxSendingLength) {
Log.warning("Text length of exceeding message: {0}", textToSend.length());
int difference = Math.abs(maxSendingLength - overallSendingLength);
// We give exact size and advice on reduction...
JOptionPane.showMessageDialog(this.parentFrame, "The text of the message you have written is too long to be sent. When\n" + "packaged as a memo it comes up to " + overallSendingLength + " bytes (maximum is " + maxSendingLength + " bytes)\n\n" + "Advice: try to reduce the message length by " + difference + " characters. The current\n" + "version of the ZEN messaging protocol supports approximately 330\n" + "characters per message (number is not exact - depends on character\n" + "encoding specifics).", "Message size exceeds currently supported limits...", JOptionPane.ERROR_MESSAGE);
// Restore controls and exit
this.sendButton.setEnabled(true);
this.writeMessageTextArea.setEnabled(true);
return;
}
if (updateMessagingIdentityJustBeforeSend) {
if (!contactIdentity.isGroup()) {
this.messagingStorage.updateContactIdentityForSenderIDAddress(contactIdentity.getSenderidaddress(), contactIdentity);
} else {
this.messagingStorage.updateGroupContactIdentityForSendReceiveAddress(contactIdentity.getSendreceiveaddress(), contactIdentity);
}
}
// Finally send the message
String tempOperationID = null;
try {
tempOperationID = this.clientCaller.sendMessage(ownIdentity.getSendreceiveaddress(), contactIdentity.getSendreceiveaddress(), msgOptions.getAmountToSend(), msgOptions.getTransactionFee(), memoString);
} catch (WalletCallException wce) {
Log.error("Wallet call error in sending message: ", wce);
sendResultLabel.setText("<html><span style=\"font-size:0.8em;\">Send status: " + "<span style=\"color:red;font-weight:bold\">ERROR! </span></span></html>");
JOptionPane.showMessageDialog(MessagingPanel.this.getRootPane().getParent(), "An error occurred upon sending message to contact: " + contactIdentity.getDiplayString() + ". \n" + "Error message is: " + wce.getMessage() + "\n" + "If the problem persists, you may need technical support :( ...\n", "Error in sending message", JOptionPane.ERROR_MESSAGE);
sendMessageProgressBar.setValue(0);
sendButton.setEnabled(true);
writeMessageTextArea.setEnabled(true);
// Exit prematurely
return;
}
final String operationStatusID = tempOperationID;
// Start a data gathering thread specific to the operation being executed - this is done is a separate
// thread since the server responds more slowly during JoinSPlits and this blocks he GUI somewhat.
final DataGatheringThread<Boolean> opFollowingThread = new DataGatheringThread<Boolean>(new DataGatheringThread.DataGatherer<Boolean>() {
public Boolean gatherData() throws Exception {
long start = System.currentTimeMillis();
Boolean result = MessagingPanel.this.clientCaller.isSendingOperationComplete(operationStatusID);
long end = System.currentTimeMillis();
Log.info("Checking for messaging operation " + operationStatusID + " status done in " + (end - start) + "ms.");
return result;
}
}, this.errorReporter, 2000, true);
// Start a timer to update the progress of the operation
this.operationStatusTimer = new Timer(2000, new ActionListener() {
public int operationStatusCounter = 0;
@Override
public void actionPerformed(ActionEvent e) {
try {
Boolean opComplete = opFollowingThread.getLastData();
if ((opComplete != null) && opComplete.booleanValue()) {
// End the special thread used to follow the operation
opFollowingThread.setSuspended(true);
boolean sendWasSuccessful = clientCaller.isCompletedOperationSuccessful(operationStatusID);
if (sendWasSuccessful) {
sendResultLabel.setText("<html><span style=\"font-size:0.8em;\">Send status: " + "<span style=\"color:green;font-weight:bold\">SUCCESSFUL</span></span></html>");
} else {
String errorMessage = clientCaller.getOperationFinalErrorMessage(operationStatusID);
sendResultLabel.setText("<html><span style=\"font-size:0.8em;\">Send status: " + "<span style=\"color:red;font-weight:bold\">ERROR! </span></span></html>");
JOptionPane.showMessageDialog(MessagingPanel.this.getRootPane().getParent(), "An error occurred when sending message to contact: " + contactIdentity.getDiplayString() + ". \n" + "Error message is: " + errorMessage + "\n\n" + "If the problem persists, you may need technical support :( ...\n", "Error in sending message", JOptionPane.ERROR_MESSAGE);
}
// Restore controls etc. final actions - reenable
sendMessageProgressBar.setValue(0);
operationStatusTimer.stop();
operationStatusTimer = null;
sendButton.setEnabled(true);
writeMessageTextArea.setEnabled(true);
// clear message from text area
writeMessageTextArea.setText("");
if (sendWasSuccessful) {
// Save message as outgoing
Message msg = new Message(jsonInnerMessageForFurtherUse);
msg.setTime(new Date());
msg.setDirection(DIRECTION_TYPE.SENT);
// TODO: We can get the transaction ID for outgoing messages but is is probably unnecessary
msg.setTransactionID("");
messagingStorage.writeNewSentMessageForContact(contactIdentity, msg);
}
// Update conversation text pane
displayMessagesForContact(contactIdentity);
} else {
// Update the progress
sendResultLabel.setText("<html><span style=\"font-size:0.8em;\">Send status: " + "<span style=\"color:orange;font-weight:bold\">IN PROGRESS</span></span></html>");
operationStatusCounter += 2;
int progress = 0;
if (operationStatusCounter <= 100) {
progress = operationStatusCounter;
} else {
progress = 100 + (((operationStatusCounter - 100) * 6) / 10);
}
sendMessageProgressBar.setValue(progress);
}
MessagingPanel.this.repaint();
} catch (Exception ex) {
Log.error("Unexpected error in sending message: ", ex);
MessagingPanel.this.errorReporter.reportError(ex);
}
}
});
// End timer operation
operationStatusTimer.setInitialDelay(0);
operationStatusTimer.start();
}
use of com.vaklinov.zcashui.ZCashClientCaller.WalletCallException in project zencash-swing-wallet-ui by ZencashOfficial.
the class ZCashUI method main.
public static void main(String[] argv) throws IOException {
try {
OS_TYPE os = OSUtil.getOSType();
if ((os == OS_TYPE.WINDOWS) || (os == OS_TYPE.MAC_OS)) {
possiblyCreateZENConfigFile();
}
LanguageUtil langUtil = LanguageUtil.instance();
Log.info("Starting ZENCash Swing Wallet ...");
Log.info("OS: " + System.getProperty("os.name") + " = " + os);
Log.info("Current directory: " + new File(".").getCanonicalPath());
Log.info("Class path: " + System.getProperty("java.class.path"));
Log.info("Environment PATH: " + System.getenv("PATH"));
// Look and feel settings - a custom OS-look and feel is set for Windows
if (os == OS_TYPE.WINDOWS) {
// Custom Windows L&F and font settings
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
// This font looks good but on Windows 7 it misses some chars like the stars...
// FontUIResource font = new FontUIResource("Lucida Sans Unicode", Font.PLAIN, 11);
// UIManager.put("Table.font", font);
} else if (os == OS_TYPE.MAC_OS) {
// The MacOS L&F is active by default - the property sets the menu bar Mac style
System.setProperty("apple.laf.useScreenMenuBar", "true");
} else {
for (LookAndFeelInfo ui : UIManager.getInstalledLookAndFeels()) {
Log.info("Available look and feel: " + ui.getName() + " " + ui.getClassName());
if (ui.getName().equals("Nimbus")) {
Log.info("Setting look and feel: {0}", ui.getClassName());
UIManager.setLookAndFeel(ui.getClassName());
break;
}
;
}
}
// If zend is currently not running, do a startup of the daemon as a child process
// It may be started but not ready - then also show dialog
ZCashInstallationObserver initialInstallationObserver = new ZCashInstallationObserver(OSUtil.getProgramDirectory());
DaemonInfo zcashdInfo = initialInstallationObserver.getDaemonInfo();
initialInstallationObserver = null;
ZCashClientCaller initialClientCaller = new ZCashClientCaller(OSUtil.getProgramDirectory());
boolean daemonStartInProgress = false;
try {
if (zcashdInfo.status == DAEMON_STATUS.RUNNING) {
NetworkAndBlockchainInfo info = initialClientCaller.getNetworkAndBlockchainInfo();
// If more than 20 minutes behind in the blockchain - startup in progress
if ((System.currentTimeMillis() - info.lastBlockDate.getTime()) > (20 * 60 * 1000)) {
Log.info("Current blockchain synchronization date is " + new Date(info.lastBlockDate.getTime()));
daemonStartInProgress = true;
}
}
} catch (WalletCallException wce) {
if (// Started but not ready
(wce.getMessage().indexOf("{\"code\":-28") != -1) || (wce.getMessage().indexOf("error code: -28") != -1)) {
Log.info("zend is currently starting...");
daemonStartInProgress = true;
}
}
StartupProgressDialog startupBar = null;
if ((zcashdInfo.status != DAEMON_STATUS.RUNNING) || (daemonStartInProgress)) {
Log.info("zend is not runing at the moment or has not started/synchronized 100% - showing splash...");
startupBar = new StartupProgressDialog(initialClientCaller);
startupBar.setVisible(true);
startupBar.waitForStartup();
}
initialClientCaller = null;
// Main GUI is created here
ZCashUI ui = new ZCashUI(startupBar);
ui.setVisible(true);
} catch (InstallationDetectionException ide) {
Log.error("Unexpected error: ", ide);
JOptionPane.showMessageDialog(null, LanguageUtil.instance().getString("main.frame.option.pane.installation.error.text", OSUtil.getProgramDirectory(), ide.getMessage()), LanguageUtil.instance().getString("main.frame.option.pane.installation.error.title"), JOptionPane.ERROR_MESSAGE);
System.exit(1);
} catch (WalletCallException wce) {
Log.error("Unexpected error: ", wce);
if ((wce.getMessage().indexOf("{\"code\":-28,\"message\"") != -1) || (wce.getMessage().indexOf("error code: -28") != -1)) {
JOptionPane.showMessageDialog(null, LanguageUtil.instance().getString("main.frame.option.pane.wallet.communication.error.text"), LanguageUtil.instance().getString("main.frame.option.pane.wallet.communication.error.title"), JOptionPane.ERROR_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, LanguageUtil.instance().getString("main.frame.option.pane.wallet.communication.error.2.text", wce.getMessage()), LanguageUtil.instance().getString("main.frame.option.pane.wallet.communication.error.2.title"), JOptionPane.ERROR_MESSAGE);
}
System.exit(2);
} catch (Exception e) {
Log.error("Unexpected error: ", e);
JOptionPane.showMessageDialog(null, LanguageUtil.instance().getString("main.frame.option.pane.wallet.critical.error.text", e.getMessage()), LanguageUtil.instance().getString("main.frame.option.pane.wallet.critical.error.title"), JOptionPane.ERROR_MESSAGE);
System.exit(3);
} catch (Error err) {
// Last resort catch for unexpected problems - just to inform the user
err.printStackTrace();
JOptionPane.showMessageDialog(null, LanguageUtil.instance().getString("main.frame.option.pane.wallet.critical.error.2.text", err.getMessage()), LanguageUtil.instance().getString("main.frame.option.pane.wallet.critical.error.2.title"), JOptionPane.ERROR_MESSAGE);
System.exit(4);
}
}
use of com.vaklinov.zcashui.ZCashClientCaller.WalletCallException in project zencash-swing-wallet-ui by ZencashOfficial.
the class WalletOperations method backupWallet.
public void backupWallet() {
try {
this.issueBackupDirectoryWarning();
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle(langUtil.getString("wallet.operations.dialog.backup.wallet.title"));
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setCurrentDirectory(OSUtil.getUserHomeDirectory());
int result = fileChooser.showSaveDialog(this.parent);
if (result != JFileChooser.APPROVE_OPTION) {
return;
}
File f = fileChooser.getSelectedFile();
Cursor oldCursor = this.parent.getCursor();
String path = null;
try {
this.parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
path = this.clientCaller.backupWallet(f.getName());
this.backupTracker.handleBackup();
this.parent.setCursor(oldCursor);
} catch (WalletCallException wce) {
this.parent.setCursor(oldCursor);
Log.error("Unexpected error: ", wce);
JOptionPane.showMessageDialog(this.parent, langUtil.getString("wallet.operations.option.pane.backup.wallet.error.text", wce.getMessage().replace(",", ",\n")), langUtil.getString("wallet.operations.option.pane.backup.wallet.error.title"), JOptionPane.ERROR_MESSAGE);
return;
}
JOptionPane.showMessageDialog(this.parent, langUtil.getString("wallet.operations.option.pane.backup.wallet.success.text", f.getName(), path), langUtil.getString("wallet.operations.option.pane.backup.wallet.success.title"), JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
this.errorReporter.reportError(e, false);
}
}
use of com.vaklinov.zcashui.ZCashClientCaller.WalletCallException in project zencash-swing-wallet-ui by ZencashOfficial.
the class WalletOperations method exportWalletPrivateKeys.
public void exportWalletPrivateKeys() {
try {
this.issueBackupDirectoryWarning();
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle(langUtil.getString("wallet.operations.dialog.export.private.keys.title"));
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setCurrentDirectory(OSUtil.getUserHomeDirectory());
int result = fileChooser.showSaveDialog(this.parent);
if (result != JFileChooser.APPROVE_OPTION) {
return;
}
File f = fileChooser.getSelectedFile();
Cursor oldCursor = this.parent.getCursor();
String path = null;
try {
this.parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
path = this.clientCaller.exportWallet(f.getName());
this.backupTracker.handleBackup();
this.parent.setCursor(oldCursor);
} catch (WalletCallException wce) {
this.parent.setCursor(oldCursor);
Log.error("Unexpected error: ", wce);
JOptionPane.showMessageDialog(this.parent, "An unexpected error occurred while exporting wallet private keys!" + "\n" + wce.getMessage().replace(",", ",\n"), "Error in exporting wallet private keys...", JOptionPane.ERROR_MESSAGE);
return;
}
JOptionPane.showMessageDialog(this.parent, "The wallet private keys have been exported successfully to file:\n" + f.getName() + "\n" + "in the backup directory provided to zend (-exportdir=<dir>).\nFull path is: " + path + "\n" + "You need to protect this file from unauthorized access. Anyone who\n" + "has access to the private keys can spend the ZENCash balance!", "Wallet private key export...", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
this.errorReporter.reportError(e, false);
}
}
use of com.vaklinov.zcashui.ZCashClientCaller.WalletCallException in project zencash-swing-wallet-ui by ZencashOfficial.
the class StartupProgressDialog method waitForStartup.
public void waitForStartup() throws IOException, InterruptedException, WalletCallException, InvocationTargetException {
// special handling of Windows/Mac OS app launch
OS_TYPE os = OSUtil.getOSType();
if ((os == OS_TYPE.WINDOWS) || (os == OS_TYPE.MAC_OS)) {
ProvingKeyFetcher keyFetcher = new ProvingKeyFetcher();
keyFetcher.fetchIfMissing(this);
}
Log.info("Splash: checking if zend is already running...");
boolean shouldStartZCashd = false;
try {
clientCaller.getDaemonRawRuntimeInfo();
} catch (IOException e) {
// may be thrown for an unexpected reason!!! - so message is checked
if (e.getMessage() != null && e.getMessage().toLowerCase(Locale.ROOT).contains("error: couldn't connect to server")) {
shouldStartZCashd = true;
}
}
if (!shouldStartZCashd) {
Log.info("Splash: zend already running...");
// What if started by hand but taking long to initialize???
// doDispose();
// return;
} else {
Log.info("Splash: zend will be started...");
}
final Process daemonProcess = shouldStartZCashd ? clientCaller.startDaemon() : null;
// just a little extra
Thread.sleep(POLL_PERIOD);
int iteration = 0;
while (true) {
iteration++;
Thread.sleep(POLL_PERIOD);
JsonObject info = null;
try {
info = clientCaller.getDaemonRawRuntimeInfo();
} catch (IOException e) {
if (iteration > 4) {
throw e;
} else {
continue;
}
}
JsonValue code = info.get("code");
if (code == null || (code.asInt() != STARTUP_ERROR_CODE))
break;
final String message = info.getString("message", "???");
setProgressText(message);
}
if (// Shutdown only if we started it
daemonProcess != null)
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
Log.info("Stopping zend because we started it - now it is alive: " + StartupProgressDialog.this.isAlive(daemonProcess));
try {
clientCaller.stopDaemon();
long start = System.currentTimeMillis();
while (!StartupProgressDialog.this.waitFor(daemonProcess, 3000)) {
long end = System.currentTimeMillis();
Log.info("Waiting for " + ((end - start) / 1000) + " seconds for zend to exit...");
if (end - start > 15 * 1000) {
clientCaller.stopDaemon();
daemonProcess.destroy();
}
if (end - start > 1 * 60 * 1000) {
break;
}
}
if (StartupProgressDialog.this.isAlive(daemonProcess)) {
Log.info("zend is still alive although we tried to stop it. " + "Hopefully it will stop later!");
// System.out.println("zend is still alive, killing forcefully");
// daemonProcess.destroyForcibly();
} else
Log.info("zend shut down successfully");
} catch (Exception bad) {
Log.error("Couldn't stop zend!", bad);
}
}
});
}
Aggregations