diff --git a/build.gradle b/build.gradle index e7c027d57f..553f6be97e 100644 --- a/build.gradle +++ b/build.gradle @@ -56,7 +56,7 @@ configure(subprojects) { httpcoreVersion = '4.4.13' ioVersion = '2.6' jacksonVersion = '2.12.1' - javafxVersion = '21.0.2' + javafxVersion = '21.0.9' javaxAnnotationVersion = '1.2' jcsvVersion = '1.4.0' jetbrainsAnnotationsVersion = '13.0' @@ -84,6 +84,10 @@ configure(subprojects) { os = (osName == 'mac' && (osArch.contains('aarch64') || osArch.contains('arm'))) ? 'mac-aarch64' : osName } + configurations { + javafxVerification + } + repositories { mavenCentral() //mavenLocal() @@ -685,6 +689,32 @@ configure(project(':desktop')) { implementation "org.openjfx:javafx-swing:$javafxVersion:$os" implementation "org.openjfx:javafx-base:$javafxVersion:$os" implementation "org.openjfx:javafx-graphics:$javafxVersion:$os" + + // verification-only dependencies + javafxVerification "org.openjfx:javafx-controls:$javafxVersion:mac" + javafxVerification "org.openjfx:javafx-controls:$javafxVersion:mac-aarch64" + javafxVerification "org.openjfx:javafx-controls:$javafxVersion:win" + javafxVerification "org.openjfx:javafx-controls:$javafxVersion:linux" + + javafxVerification "org.openjfx:javafx-fxml:$javafxVersion:mac" + javafxVerification "org.openjfx:javafx-fxml:$javafxVersion:mac-aarch64" + javafxVerification "org.openjfx:javafx-fxml:$javafxVersion:win" + javafxVerification "org.openjfx:javafx-fxml:$javafxVersion:linux" + + javafxVerification "org.openjfx:javafx-swing:$javafxVersion:mac" + javafxVerification "org.openjfx:javafx-swing:$javafxVersion:mac-aarch64" + javafxVerification "org.openjfx:javafx-swing:$javafxVersion:win" + javafxVerification "org.openjfx:javafx-swing:$javafxVersion:linux" + + javafxVerification "org.openjfx:javafx-base:$javafxVersion:mac" + javafxVerification "org.openjfx:javafx-base:$javafxVersion:mac-aarch64" + javafxVerification "org.openjfx:javafx-base:$javafxVersion:win" + javafxVerification "org.openjfx:javafx-base:$javafxVersion:linux" + + javafxVerification "org.openjfx:javafx-graphics:$javafxVersion:mac" + javafxVerification "org.openjfx:javafx-graphics:$javafxVersion:mac-aarch64" + javafxVerification "org.openjfx:javafx-graphics:$javafxVersion:win" + javafxVerification "org.openjfx:javafx-graphics:$javafxVersion:linux" } test { diff --git a/core/src/main/java/haveno/core/offer/OpenOfferManager.java b/core/src/main/java/haveno/core/offer/OpenOfferManager.java index 64949a3369..7f5d729802 100644 --- a/core/src/main/java/haveno/core/offer/OpenOfferManager.java +++ b/core/src/main/java/haveno/core/offer/OpenOfferManager.java @@ -1761,7 +1761,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe request.getReserveTxKeyImages(), verifiedTx.getFee().longValueExact(), signature); // TODO (woodser): no need for signature to be part of SignedOffer? - addSignedOffer(signedOffer); + UserThread.execute(() -> addSignedOffer(signedOffer)); requestPersistence(); // send response with signature diff --git a/core/src/main/java/haveno/core/support/dispute/DisputeManager.java b/core/src/main/java/haveno/core/support/dispute/DisputeManager.java index 9dfe58d9fd..672b1d729c 100644 --- a/core/src/main/java/haveno/core/support/dispute/DisputeManager.java +++ b/core/src/main/java/haveno/core/support/dispute/DisputeManager.java @@ -420,7 +420,12 @@ public abstract class DisputeManager> extends Sup if (reOpen) { dispute = storedDisputeOptional.get(); } else { - disputeList.add(dispute); + final Dispute finalDispute = dispute; + UserThread.execute(() -> { + synchronized (disputeList.getObservableList()) { + disputeList.add(finalDispute); + } + }); } } @@ -556,15 +561,17 @@ public abstract class DisputeManager> extends Sup } public void removeDisputes(Trade trade) { - T disputeList = getDisputeList(); - synchronized (disputeList.getObservableList()) { - for (Dispute dispute : trade.getDisputes()) { - disputeList.remove(dispute); + UserThread.execute(() -> { + T disputeList = getDisputeList(); + synchronized (disputeList.getObservableList()) { + for (Dispute dispute : trade.getDisputes()) { + disputeList.remove(dispute); + } } - } - trade.setDisputeState(Trade.DisputeState.NO_DISPUTE); - clearPendingMessage(); - requestPersistence(); + trade.setDisputeState(Trade.DisputeState.NO_DISPUTE); + clearPendingMessage(); + requestPersistence(); + }); } // arbitrator receives dispute opened message from opener, opener's peer receives from arbitrator @@ -694,7 +701,11 @@ public abstract class DisputeManager> extends Sup if (reOpen) { trade.setDisputeState(Trade.DisputeState.DISPUTE_OPENED); } else { - disputeList.add(dispute); + UserThread.execute(() -> { + synchronized (disputeList) { + disputeList.add(dispute); + } + }); trade.advanceDisputeState(Trade.DisputeState.DISPUTE_OPENED); } @@ -822,9 +833,12 @@ public abstract class DisputeManager> extends Sup dispute = storedDisputeOptional.get(); dispute.reOpen(); } else { - synchronized (disputeList) { - disputeList.add(dispute); - } + final Dispute finalDispute = dispute; + UserThread.execute(() -> { + synchronized (disputeList) { + disputeList.add(finalDispute); + } + }); } // get trade diff --git a/daemon/src/main/java/haveno/daemon/grpc/GrpcDisputesService.java b/daemon/src/main/java/haveno/daemon/grpc/GrpcDisputesService.java index bc7a9a0f74..1708e8df91 100644 --- a/daemon/src/main/java/haveno/daemon/grpc/GrpcDisputesService.java +++ b/daemon/src/main/java/haveno/daemon/grpc/GrpcDisputesService.java @@ -1,6 +1,8 @@ package haveno.daemon.grpc; import com.google.inject.Inject; + +import haveno.common.UserThread; import haveno.common.config.Config; import haveno.common.proto.ProtoUtil; import haveno.core.api.CoreApi; @@ -66,64 +68,72 @@ public class GrpcDisputesService extends DisputesImplBase { @Override public void getDispute(GetDisputeRequest req, StreamObserver responseObserver) { - try { - var dispute = coreApi.getDispute(req.getTradeId()); - var reply = GetDisputeReply.newBuilder() - .setDispute(dispute.toProtoMessage()) - .build(); - responseObserver.onNext(reply); - responseObserver.onCompleted(); - } catch (Throwable cause) { - exceptionHandler.handleExceptionAsWarning(log, getClass().getName() + ".getDispute", cause, responseObserver); - } + UserThread.execute(() -> { + try { + var dispute = coreApi.getDispute(req.getTradeId()); + var reply = GetDisputeReply.newBuilder() + .setDispute(dispute.toProtoMessage()) + .build(); + responseObserver.onNext(reply); + responseObserver.onCompleted(); + } catch (Throwable cause) { + exceptionHandler.handleExceptionAsWarning(log, getClass().getName() + ".getDispute", cause, responseObserver); + } + }); } @Override public void getDisputes(GetDisputesRequest req, StreamObserver responseObserver) { - try { - var disputes = coreApi.getDisputes(); - var disputesProtobuf = disputes.stream() - .map(d -> d.toProtoMessage()) - .collect(Collectors.toList()); - var reply = GetDisputesReply.newBuilder() - .addAllDisputes(disputesProtobuf) - .build(); - responseObserver.onNext(reply); - responseObserver.onCompleted(); - } catch (Throwable cause) { - exceptionHandler.handleException(log, cause, responseObserver); - } + UserThread.execute(() -> { + try { + var disputes = coreApi.getDisputes(); + var disputesProtobuf = disputes.stream() + .map(d -> d.toProtoMessage()) + .collect(Collectors.toList()); + var reply = GetDisputesReply.newBuilder() + .addAllDisputes(disputesProtobuf) + .build(); + responseObserver.onNext(reply); + responseObserver.onCompleted(); + } catch (Throwable cause) { + exceptionHandler.handleException(log, cause, responseObserver); + } + }); } @Override public void resolveDispute(ResolveDisputeRequest req, StreamObserver responseObserver) { - try { - var winner = ProtoUtil.enumFromProto(DisputeResult.Winner.class, req.getWinner().name()); - var reason = ProtoUtil.enumFromProto(DisputeResult.Reason.class, req.getReason().name()); - coreApi.resolveDispute(req.getTradeId(), winner, reason, req.getSummaryNotes(), req.getCustomPayoutAmount()); - var reply = ResolveDisputeReply.newBuilder().build(); - responseObserver.onNext(reply); - responseObserver.onCompleted(); - } catch (Throwable cause) { - cause.printStackTrace(); - exceptionHandler.handleExceptionAsWarning(log, getClass().getName() + ".resolveDispute", cause, responseObserver); - } + UserThread.execute(() -> { + try { + var winner = ProtoUtil.enumFromProto(DisputeResult.Winner.class, req.getWinner().name()); + var reason = ProtoUtil.enumFromProto(DisputeResult.Reason.class, req.getReason().name()); + coreApi.resolveDispute(req.getTradeId(), winner, reason, req.getSummaryNotes(), req.getCustomPayoutAmount()); + var reply = ResolveDisputeReply.newBuilder().build(); + responseObserver.onNext(reply); + responseObserver.onCompleted(); + } catch (Throwable cause) { + cause.printStackTrace(); + exceptionHandler.handleExceptionAsWarning(log, getClass().getName() + ".resolveDispute", cause, responseObserver); + } + }); } @Override public void sendDisputeChatMessage(SendDisputeChatMessageRequest req, StreamObserver responseObserver) { - try { - var attachmentsProto = req.getAttachmentsList(); - var attachments = attachmentsProto.stream().map(a -> Attachment.fromProto(a)) - .collect(Collectors.toList()); - coreApi.sendDisputeChatMessage(req.getDisputeId(), req.getMessage(), new ArrayList(attachments)); - var reply = SendDisputeChatMessageReply.newBuilder().build(); - responseObserver.onNext(reply); - responseObserver.onCompleted(); - } catch (Throwable cause) { - exceptionHandler.handleException(log, cause, responseObserver); - } + UserThread.execute(() -> { + try { + var attachmentsProto = req.getAttachmentsList(); + var attachments = attachmentsProto.stream().map(a -> Attachment.fromProto(a)) + .collect(Collectors.toList()); + coreApi.sendDisputeChatMessage(req.getDisputeId(), req.getMessage(), new ArrayList(attachments)); + var reply = SendDisputeChatMessageReply.newBuilder().build(); + responseObserver.onNext(reply); + responseObserver.onCompleted(); + } catch (Throwable cause) { + exceptionHandler.handleException(log, cause, responseObserver); + } + }); } final ServerInterceptor[] interceptors() { diff --git a/desktop/package/package.gradle b/desktop/package/package.gradle index 38927a1373..58822d55d4 100644 --- a/desktop/package/package.gradle +++ b/desktop/package/package.gradle @@ -77,18 +77,18 @@ task getJavaBinariesDownloadURLs { // -- macOS ( -> use the tar.gz JDK link) // -- windows ( -> use the .zip JDK link) Map jdk21Binaries = [ - 'linux' : 'https://download.bell-sw.com/java/21.0.2+14/bellsoft-jdk21.0.2+14-linux-amd64-full.tar.gz', - 'linux-sha256' : '7eda80851fba1da023e03446c77100f19e7c770491b0d5bc9f893044e1b2b69b', - 'linux-aarch64' : 'https://download.bell-sw.com/java/21.0.2+14/bellsoft-jdk21.0.2+14-linux-aarch64-full.tar.gz', - 'linux-aarch64-sha256' : 'a477fc72085f30b03bf71fbed47923cea3b6f33b5b6a5a74718623b772a3a043', - 'mac' : 'https://download.bell-sw.com/java/21.0.2+14/bellsoft-jdk21.0.2+14-macos-amd64-full.tar.gz', - 'mac-sha256' : '42b528206595e559803b6f9f6bdbbf236ec6d10684058f46bc5261f5498d345c', - 'mac-aarch64' : 'https://download.bell-sw.com/java/21.0.2+14/bellsoft-jdk21.0.2+14-macos-aarch64-full.tar.gz', - 'mac-aarch64-sha256' : 'eba73a9bff7234220dc9a1da7f44b3d7ed2a562663eadc1c53bd74b355839a55', - 'windows' : 'https://download.bell-sw.com/java/21.0.2+14/bellsoft-jdk21.0.2+14-windows-amd64-full.zip', - 'windows-sha256' : 'f823eff0234af5bef095e53e5431191dbee8c2e42ca321eda23148a15cbf8d5b', - 'windows-aarch64' : 'https://download.bell-sw.com/java/21.0.2+14/bellsoft-jdk21.0.2+14-windows-aarch64-full.zip', - 'windows-aarch64-sha256': 'a2e9edecaf9637f83ef1cddab3a74f39ac55f8e1a479f10f3584ad939dfadd0a' + 'linux' : 'https://download.bell-sw.com/java/21.0.9+15/bellsoft-jdk21.0.9+15-linux-amd64-full.tar.gz', + 'linux-sha256' : 'cada3343156c10dab634a7caca586941665af8f58a680664846adc2a27542968', + 'linux-aarch64' : 'https://download.bell-sw.com/java/21.0.9+15/bellsoft-jdk21.0.9+15-linux-aarch64-full.tar.gz', + 'linux-aarch64-sha256' : '09081d587a59f48d2900d62f3008f5a786a27932d68d64eeb4938aa715bf1ea8', + 'mac' : 'https://download.bell-sw.com/java/21.0.9+15/bellsoft-jdk21.0.9+15-macos-amd64-full.tar.gz', + 'mac-sha256' : 'f7ceb9743fe96da0e3b07f64aa23c6f54c39d134af01ed56869db0864c0cd13d', + 'mac-aarch64' : 'https://download.bell-sw.com/java/21.0.9+15/bellsoft-jdk21.0.9+15-macos-aarch64-full.tar.gz', + 'mac-aarch64-sha256' : '6af4be6c59c2ac4e2d89ee940e26f19ec09ea86fac0405058bc3d7f1f805b78c', + 'windows' : 'https://download.bell-sw.com/java/21.0.9+15/bellsoft-jdk21.0.9+15-windows-amd64-full.zip', + 'windows-sha256' : 'ff1260f6c234799cebeb4df08b68da3fd066ad6e4209c67dd3de7bc4fb7e9a35', + 'windows-aarch64' : 'https://download.bell-sw.com/java/21.0.9+15/bellsoft-jdk21.0.9+15-windows-aarch64-full.zip', + 'windows-aarch64-sha256': '5396566e494ebca5119681cb9961f69310b5b315d24ca1b4c897b71ebfc4fbed' ] String osKey diff --git a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java index 8df9fdb33d..52698a7440 100644 --- a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java +++ b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java @@ -314,37 +314,39 @@ public class PendingTradesDataModel extends ActivatableDataModel { /////////////////////////////////////////////////////////////////////////////////////////// private void onListChanged() { - synchronized (tradeManager.getObservableList()) { + UserThread.execute(() -> { + synchronized (tradeManager.getObservableList()) { - // add or remove listener for hidden trades - for (Trade trade : tradeManager.getObservableList()) { - if (isTradeShown(trade)) { - if (hiddenTrades.contains(trade)) { - UserThread.execute(() -> trade.stateProperty().removeListener(hiddenStateChangeListener)); - hiddenTrades.remove(trade); - } - } else { - if (!hiddenTrades.contains(trade)) { - UserThread.execute(() -> trade.stateProperty().addListener(hiddenStateChangeListener)); - hiddenTrades.add(trade); + // add or remove listener for hidden trades + for (Trade trade : tradeManager.getObservableList()) { + if (isTradeShown(trade)) { + if (hiddenTrades.contains(trade)) { + UserThread.execute(() -> trade.stateProperty().removeListener(hiddenStateChangeListener)); + hiddenTrades.remove(trade); + } + } else { + if (!hiddenTrades.contains(trade)) { + UserThread.execute(() -> trade.stateProperty().addListener(hiddenStateChangeListener)); + hiddenTrades.add(trade); + } } } - } - - // add shown trades to list - synchronized (list) { - list.clear(); - list.addAll(tradeManager.getObservableList().stream() - .filter(trade -> isTradeShown(trade)) - .map(trade -> new PendingTradesListItem(trade, btcFormatter)) - .collect(Collectors.toList())); + + // add shown trades to list + synchronized (list) { + list.clear(); + list.addAll(tradeManager.getObservableList().stream() + .filter(trade -> isTradeShown(trade)) + .map(trade -> new PendingTradesListItem(trade, btcFormatter)) + .collect(Collectors.toList())); - // we sort by date, earliest first - list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate())); + // we sort by date, earliest first + list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate())); + } } - } - selectBestItem(); + selectBestItem(); + }); } private boolean isTradeShown(Trade trade) { diff --git a/docs/deployment-guide.md b/docs/deployment-guide.md index eb41f71d0c..7827676b4d 100644 --- a/docs/deployment-guide.md +++ b/docs/deployment-guide.md @@ -29,7 +29,7 @@ On Linux and macOS, install Java JDK 21: ``` curl -s "https://get.sdkman.io" | bash -sdk install java 21.0.2.fx-librca +sdk install java 21.0.9.fx-librca ``` Alternatively, on Ubuntu 22.04: @@ -47,7 +47,7 @@ On Windows, install MSYS2 and Java JDK 21: 32-bit: `pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-cmake git` 6. `curl -s "https://get.sdkman.io" | bash` -7. `sdk install java 21.0.2.fx-librca` +7. `sdk install java 21.0.9.fx-librca` ## Fork and build Haveno diff --git a/docs/installing.md b/docs/installing.md index aebf7b20c3..9717992b71 100644 --- a/docs/installing.md +++ b/docs/installing.md @@ -27,7 +27,7 @@ On all platforms, install Java JDK 21: ``` curl -s "https://get.sdkman.io" | bash -sdk install java 21.0.2.fx-librca +sdk install java 21.0.9.fx-librca ``` Restart the terminal for the changes to take effect. diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 5552314dba..f4d09532d5 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -2405,86 +2405,83 @@ - - - + + + - - + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - - - - + + diff --git a/scripts/install_java.bat b/scripts/install_java.bat index 28224d2d9c..2ba71dfeb6 100644 --- a/scripts/install_java.bat +++ b/scripts/install_java.bat @@ -25,9 +25,10 @@ cd /D "%~dp0" title Install Java -set jdk_version=21.0.2 -set jdk_filename=openjdk-%jdk_version%_windows-x64_bin -set jdk_url=https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_windows-x64_bin.zip +set jdk_version=21.0.9 +set jdk_build=10 +set jdk_filename=OpenJDK21U-jdk_x64_windows_hotspot_%jdk_version%_%jdk_build% +set jdk_url=https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9+10/OpenJDK21U-jdk_x64_windows_hotspot_21.0.9_10.zip if exist "%PROGRAMFILES%\Java\openjdk\jdk-%jdk_version%" ( echo %PROGRAMFILES%\Java\openjdk\jdk-%jdk_version% already exists, skipping install diff --git a/scripts/install_java.sh b/scripts/install_java.sh index e52fb5f918..470c0c69f5 100755 --- a/scripts/install_java.sh +++ b/scripts/install_java.sh @@ -15,9 +15,9 @@ set -e unameOut="$(uname -s)" case "${unameOut}" in Linux*) - JAVA_HOME=/usr/lib/jvm/openjdk-21.0.2 - JDK_FILENAME=openjdk-21.0.2_linux-x64_bin.tar.gz - JDK_URL=https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-x64_bin.tar.gz + JAVA_HOME=/usr/lib/jvm/openjdk-21.0.9 + JDK_FILENAME=OpenJDK21U-jdk_x64_linux_hotspot_21.0.9_10.tar.gz + JDK_URL=https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9+10/OpenJDK21U-jdk_x64_linux_hotspot_21.0.9_10.tar.gz # Determine which package manager to use depending on the distribution declare -A osInfo; @@ -52,9 +52,9 @@ case "${unameOut}" in update-alternatives --set javac $JAVA_HOME/bin/javac ;; Darwin*) - JAVA_HOME=/Library/Java/JavaVirtualMachines/openjdk-21.0.2.jdk/Contents/Home - JDK_FILENAME=openjdk-21.0.2_macos-x64_bin.tar.gz - JDK_URL=https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_macos-x64_bin.tar.gz + JAVA_HOME=/Library/Java/JavaVirtualMachines/openjdk-21.0.9.jdk/Contents/Home + JDK_FILENAME=OpenJDK21U-jdk_x64_mac_hotspot_21.0.9_10.tar.gz + JDK_URL=https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9+10/OpenJDK21U-jdk_x64_mac_hotspot_21.0.9_10.tar.gz if [ ! -d "$JAVA_HOME" ]; then if [[ $(command -v brew) == "" ]]; then echo "Installing Homebrew" @@ -66,10 +66,10 @@ case "${unameOut}" in brew install curl curl -L -O $JDK_URL - sudo mkdir /Library/Java/JavaVirtualMachines/openjdk-21.0.2.jdk | sudo bash + sudo mkdir /Library/Java/JavaVirtualMachines/openjdk-21.0.9.jdk | sudo bash gunzip -c $JDK_FILENAME | tar xopf - - sudo mv jdk-21.0.2.jdk/* /Library/Java/JavaVirtualMachines/openjdk-21.0.2.jdk - sudo rmdir jdk-21.0.2.jdk + sudo mv jdk-21.0.9+10/* /Library/Java/JavaVirtualMachines/openjdk-21.0.9.jdk + sudo rmdir jdk-21.0.9+10 rm $JDK_FILENAME fi