From cb8f1239ada266693a3dbd54c5d70d59ac79e6ef Mon Sep 17 00:00:00 2001 From: Christopher Schnick Date: Mon, 31 Jan 2022 12:13:27 +0100 Subject: [PATCH] Fix various issues for the native distributions --- .../java/io/xpipe/api/XPipeApiConnector.java | 2 +- .../io/xpipe/api/impl/DataSourceImpl.java | 6 +- .../java/io/xpipe/api/impl/DataTableImpl.java | 26 ++++---- beacon/build.gradle | 1 - .../java/io/xpipe/beacon/BeaconClient.java | 4 +- .../java/io/xpipe/beacon/BeaconServer.java | 63 +++++++++++++++++++ .../java/io/xpipe/beacon/ClientException.java | 15 +++++ .../java/io/xpipe/beacon/ServerException.java | 15 +++++ .../exchange/ListCollectionsExchange.java | 8 +-- .../beacon/exchange/ListEntriesExchange.java | 8 +-- .../xpipe/beacon/exchange/ModeExchange.java | 2 + .../beacon/exchange/ReadInfoExchange.java | 58 ----------------- .../exchange/ReadStructureExchange.java | 31 --------- .../exchange/ReadTableDataExchange.java | 41 ------------ .../beacon/exchange/StoreStreamExchange.java | 4 -- .../exchange/data/ClientErrorMessage.java | 20 ++++++ .../exchange/data/CollectionListEntry.java | 17 +++++ .../beacon/exchange/data/EntryListEntry.java | 17 +++++ .../exchange/data/ServerErrorMessage.java | 23 +++++++ .../beacon/message/ClientErrorMessage.java | 10 --- .../beacon/message/ServerErrorMessage.java | 12 ---- beacon/src/main/java/module-info.java | 6 +- .../io/xpipe/core/util/CoreJacksonModule.java | 6 +- .../io/xpipe/core/util/JacksonHelper.java | 9 ++- core/src/main/java/module-info.java | 2 +- .../com.fasterxml.jackson.databind.Module | 1 + 26 files changed, 208 insertions(+), 199 deletions(-) delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/ReadInfoExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/ReadStructureExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/ReadTableDataExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/ClientErrorMessage.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/CollectionListEntry.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/EntryListEntry.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/ServerErrorMessage.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/message/ClientErrorMessage.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/message/ServerErrorMessage.java create mode 100644 core/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module diff --git a/api/src/main/java/io/xpipe/api/XPipeApiConnector.java b/api/src/main/java/io/xpipe/api/XPipeApiConnector.java index c9c8c456a..1bca846a6 100644 --- a/api/src/main/java/io/xpipe/api/XPipeApiConnector.java +++ b/api/src/main/java/io/xpipe/api/XPipeApiConnector.java @@ -21,7 +21,7 @@ public abstract class XPipeApiConnector extends BeaconConnector { @Override protected BeaconClient constructSocket() throws ConnectorException { if (!JacksonHelper.isInit()) { - JacksonHelper.init(ModuleLayer.boot()); + JacksonHelper.initModularized(ModuleLayer.boot()); } if (!BeaconServer.isRunning()) { diff --git a/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java b/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java index dfa82a3f9..8b965eb8d 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java @@ -6,7 +6,7 @@ import io.xpipe.beacon.BeaconClient; import io.xpipe.beacon.ClientException; import io.xpipe.beacon.ConnectorException; import io.xpipe.beacon.ServerException; -import io.xpipe.beacon.exchange.ReadInfoExchange; +import io.xpipe.beacon.exchange.InfoExchange; import io.xpipe.beacon.exchange.StoreResourceExchange; import io.xpipe.beacon.exchange.StoreStreamExchange; import io.xpipe.core.source.DataSourceConfig; @@ -23,8 +23,8 @@ public abstract class DataSourceImpl implements DataSource { new XPipeApiConnector() { @Override protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException { - var req = ReadInfoExchange.Request.builder().sourceId(ds).build(); - ReadInfoExchange.Response res = performSimpleExchange(sc, req); + var req = InfoExchange.Request.builder().id(ds).build(); + InfoExchange.Response res = performSimpleExchange(sc, req); } }.execute(); diff --git a/api/src/main/java/io/xpipe/api/impl/DataTableImpl.java b/api/src/main/java/io/xpipe/api/impl/DataTableImpl.java index af8cad390..36ab9ef58 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataTableImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataTableImpl.java @@ -6,14 +6,12 @@ import io.xpipe.beacon.BeaconClient; import io.xpipe.beacon.ClientException; import io.xpipe.beacon.ConnectorException; import io.xpipe.beacon.ServerException; -import io.xpipe.beacon.exchange.ReadTableDataExchange; import io.xpipe.core.data.node.ArrayNode; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.node.TupleNode; import io.xpipe.core.data.type.TupleType; import io.xpipe.core.data.typed.TypedAbstractReader; import io.xpipe.core.data.typed.TypedDataStreamParser; -import io.xpipe.core.data.typed.TypedDataStructureNodeReader; import io.xpipe.core.data.typed.TypedReusableDataStructureNodeReader; import io.xpipe.core.source.DataSourceConfig; import io.xpipe.core.source.DataSourceId; @@ -90,12 +88,12 @@ public class DataTableImpl extends DataSourceImpl implements DataTable { new XPipeApiConnector() { @Override protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException { - var req = ReadTableDataExchange.Request.builder() - .sourceId(id).maxRows(maxToRead).build(); - performInputExchange(sc, req, (ReadTableDataExchange.Response res, InputStream in) -> { - var r = new TypedDataStreamParser(info.getDataType()); - r.parseStructures(in, TypedDataStructureNodeReader.immutable(info.getDataType()), nodes::add); - }); +// var req = ReadTableDataExchange.Request.builder() +// .sourceId(id).maxRows(maxToRead).build(); +// performInputExchange(sc, req, (ReadTableDataExchange.Response res, InputStream in) -> { +// var r = new TypedDataStreamParser(info.getDataType()); +// r.parseStructures(in, TypedDataStructureNodeReader.immutable(info.getDataType()), nodes::add); +// }); } }.execute(); return ArrayNode.of(nodes); @@ -115,12 +113,12 @@ public class DataTableImpl extends DataSourceImpl implements DataTable { new XPipeApiConnector() { @Override protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException { - var req = ReadTableDataExchange.Request.builder() - .sourceId(id).maxRows(Integer.MAX_VALUE).build(); - performInputExchange(sc, req, - (ReadTableDataExchange.Response res, InputStream in) -> { - input = in; - }); +// var req = ReadTableDataExchange.Request.builder() +// .sourceId(id).maxRows(Integer.MAX_VALUE).build(); +// performInputExchange(sc, req, +// (ReadTableDataExchange.Response res, InputStream in) -> { +// input = in; +// }); } }.execute(); diff --git a/beacon/build.gradle b/beacon/build.gradle index 697d60313..064021d0b 100644 --- a/beacon/build.gradle +++ b/beacon/build.gradle @@ -21,5 +21,4 @@ repositories { dependencies { implementation project(':core') - implementation project(':extension') } diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconClient.java b/beacon/src/main/java/io/xpipe/beacon/BeaconClient.java index a12f8f21d..f29eef39c 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconClient.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconClient.java @@ -7,10 +7,10 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import io.xpipe.beacon.exchange.MessageExchanges; -import io.xpipe.beacon.message.ClientErrorMessage; +import io.xpipe.beacon.exchange.data.ClientErrorMessage; import io.xpipe.beacon.message.RequestMessage; import io.xpipe.beacon.message.ResponseMessage; -import io.xpipe.beacon.message.ServerErrorMessage; +import io.xpipe.beacon.exchange.data.ServerErrorMessage; import io.xpipe.core.util.JacksonHelper; import java.io.IOException; diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java b/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java index 6db7d930c..3b1674503 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java @@ -3,6 +3,9 @@ package io.xpipe.beacon; import java.io.IOException; import java.net.DatagramSocket; import java.net.ServerSocket; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; public class BeaconServer { @@ -26,6 +29,66 @@ public class BeaconServer { return true; } + var launcher = getLauncherExecutable(); + if (launcher.isPresent()) { + // Tell launcher that we launched from an external tool + new ProcessBuilder(launcher.get().toString(), "--external") + .redirectErrorStream(true) + .redirectOutput(ProcessBuilder.Redirect.DISCARD) + .start(); + return true; + } + return false; } + + private static Optional getPortableExecutable() { + var env = System.getenv("XPIPE_HOME"); + Path file = null; + + // Prepare for invalid XPIPE_HOME path value + try { + if (System.getProperty("os.name").startsWith("Windows")) { + file = Path.of(env, "xpipe.exe"); + } else { + file = Path.of(env, "xpipe"); + } + return Files.exists(file) ? Optional.of(file) : Optional.empty(); + } catch (Exception ex) { + return Optional.empty(); + } + } + + public static Optional getLauncherExecutable() { + var portable = getPortableExecutable(); + if (portable.isPresent()) { + return portable; + } + + try { + Path file = null; + if (System.getProperty("os.name").startsWith("Windows")) { + file = Path.of(System.getenv("LOCALAPPDATA"), "X-Pipe", "xpipe.exe"); + } else { + file = Path.of("/opt/xpipe/xpipe"); + } + return Files.exists(file) ? Optional.of(file) : Optional.empty(); + } catch (Exception ex) { + return Optional.empty(); + } + } + + public static Optional getDaemonExecutable() { + try { + Path file = null; + if (System.getProperty("os.name").startsWith("Windows")) { + file = Path.of(System.getenv("LOCALAPPDATA"), "X-Pipe", "app", "xpipe.exe"); + } else { + file = Path.of("/opt/xpipe/app/bin/xpipe"); + } + return Files.exists(file) ? Optional.of(file) : Optional.empty(); + } catch (Exception ex) { + return Optional.empty(); + } + } } diff --git a/beacon/src/main/java/io/xpipe/beacon/ClientException.java b/beacon/src/main/java/io/xpipe/beacon/ClientException.java index fd36dd466..c3dc2eb60 100644 --- a/beacon/src/main/java/io/xpipe/beacon/ClientException.java +++ b/beacon/src/main/java/io/xpipe/beacon/ClientException.java @@ -2,7 +2,22 @@ package io.xpipe.beacon; public class ClientException extends Exception { + public ClientException() { + } + public ClientException(String message) { super(message); } + + public ClientException(String message, Throwable cause) { + super(message, cause); + } + + public ClientException(Throwable cause) { + super(cause); + } + + public ClientException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } } diff --git a/beacon/src/main/java/io/xpipe/beacon/ServerException.java b/beacon/src/main/java/io/xpipe/beacon/ServerException.java index 6ebd9fdc8..3478e2abe 100644 --- a/beacon/src/main/java/io/xpipe/beacon/ServerException.java +++ b/beacon/src/main/java/io/xpipe/beacon/ServerException.java @@ -2,7 +2,22 @@ package io.xpipe.beacon; public class ServerException extends Exception { + public ServerException() { + } + + public ServerException(String message) { + super(message); + } + public ServerException(String message, Throwable cause) { super(message, cause); } + + public ServerException(Throwable cause) { + super(cause); + } + + public ServerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } } diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/ListCollectionsExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/ListCollectionsExchange.java index 7a8070e85..d7532d536 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/ListCollectionsExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/ListCollectionsExchange.java @@ -1,12 +1,12 @@ package io.xpipe.beacon.exchange; +import io.xpipe.beacon.exchange.data.CollectionListEntry; import io.xpipe.beacon.message.RequestMessage; import io.xpipe.beacon.message.ResponseMessage; import lombok.Builder; import lombok.Value; import lombok.extern.jackson.Jacksonized; -import java.time.Instant; import java.util.List; public class ListCollectionsExchange implements MessageExchange { @@ -33,14 +33,10 @@ public class ListCollectionsExchange implements MessageExchange entries; + List entries; } } diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/ListEntriesExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/ListEntriesExchange.java index cd102e46b..a750ea7c5 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/ListEntriesExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/ListEntriesExchange.java @@ -1,12 +1,12 @@ package io.xpipe.beacon.exchange; +import io.xpipe.beacon.exchange.data.EntryListEntry; import io.xpipe.beacon.message.RequestMessage; import io.xpipe.beacon.message.ResponseMessage; import lombok.Builder; import lombok.Value; import lombok.extern.jackson.Jacksonized; -import java.time.Instant; import java.util.List; public class ListEntriesExchange implements MessageExchange { @@ -33,14 +33,10 @@ public class ListEntriesExchange implements MessageExchange entries; + List entries; } } diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/ModeExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/ModeExchange.java index 4803c5c5f..b38d88e02 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/ModeExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/ModeExchange.java @@ -3,6 +3,7 @@ package io.xpipe.beacon.exchange; import io.xpipe.beacon.message.RequestMessage; import io.xpipe.beacon.message.ResponseMessage; import lombok.Builder; +import lombok.NonNull; import lombok.Value; import lombok.extern.jackson.Jacksonized; @@ -27,6 +28,7 @@ public class ModeExchange implements MessageExchange { - - @Override - public String getId() { - return "readTableInfo"; - } - - @Override - public Class getRequestClass() { - return ReadInfoExchange.Request.class; - } - - @Override - public Class getResponseClass() { - return ReadInfoExchange.Response.class; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - DataSourceId sourceId; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - DataSourceId sourceId; - DataSourceType type; - DataSourceConfig config; - Object data; - - public TableData getTableData() { - return (TableData) data; - } - } - - @Jacksonized - @Builder - @Value - public static class TableData { - DataType dataType; - int rowCount; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/ReadStructureExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/ReadStructureExchange.java deleted file mode 100644 index fad9e29c2..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/ReadStructureExchange.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.message.RequestMessage; -import io.xpipe.beacon.message.ResponseMessage; -import io.xpipe.core.source.DataSourceId; - -public class ReadStructureExchange implements MessageExchange { - - @Override - public String getId() { - return "readStructure"; - } - - @Override - public Class getRequestClass() { - return Request.class; - } - - @Override - public Class getResponseClass() { - return Response.class; - } - - public static record Request(DataSourceId id) implements RequestMessage { - - } - - public static record Response() implements ResponseMessage { - - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/ReadTableDataExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/ReadTableDataExchange.java deleted file mode 100644 index e6cd747e7..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/ReadTableDataExchange.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.message.RequestMessage; -import io.xpipe.beacon.message.ResponseMessage; -import io.xpipe.core.source.DataSourceId; -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class ReadTableDataExchange implements MessageExchange { - - @Override - public String getId() { - return "readTableData"; - } - - @Override - public Class getRequestClass() { - return ReadTableDataExchange.Request.class; - } - - @Override - public Class getResponseClass() { - return ReadTableDataExchange.Response.class; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - DataSourceId sourceId; - int maxRows; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/StoreStreamExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/StoreStreamExchange.java index 82d15cc60..ad656f485 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/StoreStreamExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/StoreStreamExchange.java @@ -41,9 +41,5 @@ public class StoreStreamExchange implements MessageExchange { @@ -75,8 +75,6 @@ public class CoreJacksonModule extends SimpleModule { } @JsonSerialize(as = Throwable.class) - public abstract static class ExceptionTypeMixIn { - - + public abstract static class ThrowableTypeMixIn { } } diff --git a/core/src/main/java/io/xpipe/core/util/JacksonHelper.java b/core/src/main/java/io/xpipe/core/util/JacksonHelper.java index dca63ed19..4be999199 100644 --- a/core/src/main/java/io/xpipe/core/util/JacksonHelper.java +++ b/core/src/main/java/io/xpipe/core/util/JacksonHelper.java @@ -14,7 +14,11 @@ public class JacksonHelper { private static final ObjectMapper INSTANCE = new ObjectMapper(); private static boolean init = false; - public static synchronized void init(ModuleLayer layer) { + public static synchronized void initClassBased() { + initModularized(null); + } + + public static synchronized void initModularized(ModuleLayer layer) { ObjectMapper objectMapper = INSTANCE; objectMapper.enable(SerializationFeature.INDENT_OUTPUT); @@ -30,7 +34,8 @@ public class JacksonHelper { private static List findModules(ModuleLayer layer) { ArrayList modules = new ArrayList(); - ServiceLoader loader = ServiceLoader.load(layer, Module.class); + ServiceLoader loader = layer != null ? + ServiceLoader.load(layer, Module.class) : ServiceLoader.load(Module.class); for (Module module : loader) { modules.add(module); } diff --git a/core/src/main/java/module-info.java b/core/src/main/java/module-info.java index d429ea04f..96f16e57c 100644 --- a/core/src/main/java/module-info.java +++ b/core/src/main/java/module-info.java @@ -3,7 +3,6 @@ import io.xpipe.core.util.CoreJacksonModule; module io.xpipe.core { requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.databind; - requires com.fasterxml.jackson.module.paramnames; requires static lombok; @@ -17,6 +16,7 @@ module io.xpipe.core { opens io.xpipe.core.data.type; opens io.xpipe.core.data.generic; exports io.xpipe.core.util; + opens io.xpipe.core.util; exports io.xpipe.core.data.node; opens io.xpipe.core.data.node; exports io.xpipe.core.data.typed; diff --git a/core/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module b/core/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module new file mode 100644 index 000000000..a3c185b3e --- /dev/null +++ b/core/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module @@ -0,0 +1 @@ +io.xpipe.core.util.CoreJacksonModule \ No newline at end of file