diff --git a/.mvn/settings.xml b/.mvn/settings.xml index f1e43075..bcf61232 100644 --- a/.mvn/settings.xml +++ b/.mvn/settings.xml @@ -50,9 +50,29 @@ + + staged-releases + + false + + + + sonatype-nexus-staging + Nexus Release Repository + https://oss.sonatype.org/content/groups/staging/ + + true + + + false + + + + central-https snapshots + staged-releases diff --git a/Makefile b/Makefile index 03a903d8..c36752ef 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,23 @@ +EXTRA_CLASSPATH := $(CLASSPATH) +EXTRA_IMPORTS := $(IMPORTS) +EXTRA_STATIC_IMPORTS := $(STATIC_IMPORTS) + include make/enable-java-shell.mk +CLASSPATH := $(CLASSPATH) $(EXTRA_CLASSPATH) +IMPORTS := $(IMPORTS) $(EXTRA_IMPORTS) +STATIC_IMPORTS := $(STATIC_IMPORTS) $(EXTRA_STATIC_IMPORTS) + +export CLASSPATH IMPORTS STATIC_IMPORTS + ifeq ($(OS), WINDOWS) -MVN ?= mvn.cmd +MVN ?= try { \ + System.setProperty("jdk.lang.Process.allowAmbiguousCommands", "true"); \ + exec(cons("mvn.cmd", commandLineArgs)); } \ + finally { \ + System.setProperty("jdk.lang.Process.allowAmbiguousCommands", "false"); } else -MVN ?= mvn +MVN ?= exec(cons("mvn", commandLineArgs)); endif DOCKER := docker @@ -30,9 +44,7 @@ help : "make zip-win:" + "\n" + \ " Builds a ZIP for Windows" + "\n" + \ "make dir-word-addin:" + "\n" + \ - " Builds a directory to be included in SaveAsDAISY" + "\n" + \ - "make zip-minimal:" + "\n" + \ - " Builds a minimal ZIP that will complete itself upon first update"); \ + " Builds a directory to be included in SaveAsDAISY"); \ if (getOS() != OS.WINDOWS) \ err.println( \ "make docker:" + "\n" + \ @@ -50,14 +62,13 @@ INSTALL_DIR := $(MVN_LOCAL_REPOSITORY)/org/daisy/pipeline/assem include deps.mk -.PHONY : deb rpm zip-linux zip-mac zip-win zip-minimal deb-cli rpm-cli +.PHONY : deb rpm zip-linux zip-mac zip-win deb-cli rpm-cli deb : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER).deb rpm : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER).rpm zip-linux : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-linux.zip zip-mac : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-mac.zip zip-win : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-win.zip -zip-minimal : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-minimal.zip deb-cli : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-cli.deb rpm-cli : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-cli.rpm @@ -68,30 +79,27 @@ target/release-descriptor/releaseDescriptor.xml : mvn -Pgenerate-release-descrip # some artifacts are installed through command line $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-linux.zip \ $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-mac.zip \ -$(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-win.zip \ -$(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-minimal.zip : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)% : target/assembly-$(assembly/VERSION)% +$(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-win.zip : $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)% : target/assembly-$(assembly/VERSION)% ifndef DUMP_PROFILES - exec("$(MVN)", "install:install-file", \ - "-Dfile=$<", \ - "-DpomFile=pom.xml", \ - "-Dclassifier=$(patsubst -%,%,$(patsubst assembly-$(assembly/VERSION)%,%,$(basename $(notdir $@))))", \ - "-Dpackaging=$(patsubst .%,%,$(suffix $@))"); + exec("$(SHELL)", $(call quote-for-java,$(MVN)), "--", \ + "install:install-file", \ + "-Dfile=$<", \ + "-DpomFile=pom.xml", \ + "-Dclassifier=$(patsubst -%,%,$(patsubst assembly-$(assembly/VERSION)%,%,$(basename $(notdir $@))))", \ + "-Dpackaging=$(patsubst .%,%,$(suffix $@))"); exit(new File("$@").exists()); endif $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER).deb : mvn -Pcopy-artifacts \ -Pgenerate-release-descriptor \ - -Punpack-updater-linux \ -Ppackage-deb target/assembly-$(assembly/VERSION)-linux.zip : mvn -Pcopy-artifacts \ -Pgenerate-release-descriptor \ -Punpack-cli-linux \ - -Punpack-updater-linux \ -Passemble-linux-zip target/assembly-$(assembly/VERSION)-mac.zip : mvn -Pcopy-artifacts \ -Pgenerate-release-descriptor \ - -Punpack-cli-mac \ - -Punpack-updater-mac + -Punpack-cli-mac ifneq (--without-jre,$(filter --without-jre --with-jre,$(MAKECMDGOALS))) target/assembly-$(assembly/VERSION)-mac.zip : mvn -Pbuild-jre-mac endif @@ -172,13 +180,12 @@ ifeq ($(OS), MACOSX) } \ } endif - exec("$(MVN)", "assembly:single", "-Passemble-mac-zip"); + exec("$(SHELL)", $(call quote-for-java,$(MVN)), "--", "assembly:single", "-Passemble-mac-zip"); exit(new File("$@").exists()); endif target/assembly-$(assembly/VERSION)-win.zip : mvn -Pcopy-artifacts \ -Pgenerate-release-descriptor \ - -Punpack-cli-win \ - -Punpack-updater-win + -Punpack-cli-win ifeq (--without-jre,$(filter --without-jre --with-jre,$(MAKECMDGOALS))) target/assembly-$(assembly/VERSION)-win.zip : mvn -Passemble-win-zip ifndef DUMP_PROFILES @@ -191,16 +198,10 @@ target/assembly-$(assembly/VERSION)-win.zip : endif # --with-jre32 # -Passemble-win-zip run separately because -Pbuild-jre-win64 also run separately ifndef DUMP_PROFILES - exec("$(MVN)", "assembly:single", "-Passemble-win-zip"); + exec("$(SHELL)", $(call quote-for-java,$(MVN)), "--", "assembly:single", "-Passemble-win-zip"); exit(new File("$@").exists()); endif endif # --without-jre -target/assembly-$(assembly/VERSION)-minimal.zip : mvn -Pcopy-artifacts \ - -Pgenerate-release-descriptor \ - -Punpack-updater-mac \ - -Punpack-updater-linux \ - -Punpack-updater-win \ - -Passemble-minimal-zip $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-cli.deb : mvn -Pcopy-artifacts \ -Pgenerate-release-descriptor \ -Punpack-cli-linux \ @@ -228,27 +229,24 @@ $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-cli.rpm : endif # eq ($(OS), REDHAT) .PHONY : dir-word-addin -# Note that when `dir-word-addin' is enabled together with other targets, it is as if --without-osgi, --without-persistence, -# --without-webservice, --without-cli, --without-updater and --with-simple-api were also specified. +# Note that when `dir-word-addin' is enabled together with other targets, it is as if --without-persistence, +# --without-webservice, --without-cli and --with-simple-api were also specified. dir-word-addin : assembly/SOURCES -dir-word-addin : mvn -Pwithout-osgi \ - -Pwithout-persistence \ +dir-word-addin : mvn -Pwithout-persistence \ -Pwithout-webservice \ -Pwithout-cli \ - -Pwithout-updater \ -Pwith-simple-api \ -Pcopy-artifacts \ -Pbuild-jre-win32 \ -Pbuild-jre-win64 ifndef DUMP_PROFILES - exec("$(MVN)", "assembly:single", "-Passemble-win-dir"); + exec("$(SHELL)", $(call quote-for-java,$(MVN)), "--", "assembly:single", "-Passemble-win-dir"); endif ifneq ($(OS), WINDOWS) .PHONY : docker -# Note that when `docker' is enabled together with other targets, it is as if --without-osgi was also specified. -docker : mvn -Pwithout-osgi \ +docker : mvn \ jre/target/maven-jlink/classifiers/linux \ jre/target/maven-jlink/classifiers/linux-arm64 \ target/assembly-$(assembly/VERSION)-linux/daisy-pipeline/bin/pipeline2 @@ -317,20 +315,17 @@ jre/target/maven-jlink/classifiers/linux-arm64 : mvn -Pb target/assembly-$(assembly/VERSION)-mac/daisy-pipeline/bin/pipeline2 : mvn -Pcopy-artifacts \ -Pgenerate-release-descriptor \ -Punpack-cli-mac \ - -Punpack-updater-mac \ -Passemble-mac-dir target/assembly-$(assembly/VERSION)-linux/daisy-pipeline/bin/pipeline2 : mvn -Pcopy-artifacts \ -Pgenerate-release-descriptor \ -Punpack-cli-linux \ - -Punpack-updater-linux \ -Passemble-linux-dir endif # neq ($(OS), WINDOWS) $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER).deb \ $(INSTALL_DIR)/assembly-$(assembly/VERSION)$(CLASSIFIER)-cli.deb \ -target/assembly-$(assembly/VERSION)-linux.zip \ -target/assembly-$(assembly/VERSION)-minimal.zip \ +target/assembly-$(assembly/VERSION)-linux.zip \ target/assembly-$(assembly/VERSION)-mac/daisy-pipeline/bin/pipeline2 \ target/assembly-$(assembly/VERSION)-linux/daisy-pipeline/bin/pipeline2 : ifndef DUMP_PROFILES @@ -348,7 +343,7 @@ endif # neq ($(OS), WINDOWS) .PHONY : clean clean : - exec("$(MVN)", "clean"); + exec("$(SHELL)", $(call quote-for-java,$(MVN)), "--", "clean"); rm("make/recipes"); # process-sources generate-resources process-resources prepare-package package @@ -378,16 +373,12 @@ clean : # unpack-cli-mac unpack-cli-mac # unpack-cli-linux unpack-cli-linux # unpack-cli-win unpack-cli-win -# unpack-updater-mac unpack-updater-mac -# unpack-updater-linux unpack-updater-linux -# unpack-updater-win unpack-updater-win # assemble-mac-dir assemble-mac-dir # assemble-linux-dir assemble-linux-dir # assemble-win-dir assemble-win-dir # assemble-mac-zip assemble-mac-zip # assemble-linux-zip assemble-linux-zip # assemble-win-zip assemble-win-zip -# assemble-minimal-zip assemble-minimal-zip # package-deb filter-deb-resources package-deb # package-deb-cli package-deb-cli # package-rpm package-rpm @@ -402,17 +393,13 @@ PROFILES := \ assemble-mac-zip \ assemble-win-dir \ assemble-win-zip \ - assemble-minimal-zip \ package-deb \ package-deb-cli \ package-rpm \ package-rpm-cli \ unpack-cli-linux \ unpack-cli-mac \ - unpack-cli-win \ - unpack-updater-linux \ - unpack-updater-mac \ - unpack-updater-win + unpack-cli-win .PHONY : --with-persistence --without-persistence --without-persistence : -Pwithout-persistence @@ -423,11 +410,11 @@ else endif .PHONY : --with-osgi --without-osgi ---without-osgi : -Pwithout-osgi -ifneq (--with-osgi,$(filter --with-osgi,$(MAKECMDGOALS))) -PROFILES += without-osgi +--with-osgi : -Pwith-osgi +ifneq (--without-osgi,$(filter --without-osgi,$(MAKECMDGOALS))) +PROFILES += with-osgi else -.PHONY : -Pwithout-osgi +.PHONY : -Pwith-osgi endif .PHONY : --with-webservice --without-webservice @@ -446,14 +433,6 @@ else .PHONY : -Pwithout-cli endif -.PHONY : --with-updater --without-updater ---without-updater : -Pwithout-updater -ifneq (--with-updater,$(filter --with-updater,$(MAKECMDGOALS))) -PROFILES += without-updater -else -.PHONY : -Pwithout-updater -endif - .PHONY : --with-simple-api --without-simple-api --with-simple-api : -Pwith-simple-api ifneq (--without-simple-api,$(filter --without-simple-api,$(MAKECMDGOALS))) @@ -472,7 +451,9 @@ endif mvn : ifndef DUMP_PROFILES @List cmd = new ArrayList<>(); \ - cmd.add("$(MVN)"); \ + cmd.add("$(SHELL)"); \ + cmd.add($(call quote-for-java,$(MVN))); \ + cmd.add("--"); \ cmd.add("clean"); \ cmd.add("install"); \ cmd.add("-Dclassifier=$(--classifier)"); \ @@ -482,7 +463,7 @@ ifndef DUMP_PROFILES line -> { if (line.startsWith("-P")) cmd.add(line); }, \ Arrays.asList("$(MAKE) -s --no-print-directory ECHO=true DUMP_PROFILES=true -- $(MAKECMDGOALS)".split("\\s")))); \ println(String.join(" ", cmd)); \ - exec(runInShell(cmd)); + exec(cmd); endif .PHONY : $(addprefix -P,$(PROFILES)) @@ -513,19 +494,19 @@ ifeq ($(OS), MACOSX) -Pbuild-jre-linux -Pbuild-jre-linux-arm64 -Pbuild-jre-win32 -Pbuild-jre-win64 -Pbuild-jre-mac : src/main/jre/OpenJDK17U-jdk_x64_mac_hotspot_17.0.7_7/jdk-17.0.7+7 ifndef DUMP_PROFILES exec(env("JAVA_HOME", "$(CURDIR)/$ println(f.toString().replace(" ", "\\ ")));) -else -assembly/SOURCES := $(assembly/BASEDIR)/pom.xml \ - $(shell [ -d $(assembly/BASEDIR)/src/main/ ] && \ - find $(assembly/BASEDIR)/src/main/ -type f | sed 's/ /\\ /g') -endif + $(shell Files.walk(Paths.get("$(assembly/BASEDIR)/src")).filter(Files::isRegularFile).forEach(f -> println(f.toString().replace(" ", "\\ ")));) .SECONDARY : assembly/SOURCES assembly/SOURCES : $(assembly/SOURCES) diff --git a/make/bin/darwin_amd64/eval-java b/make/bin/darwin_amd64/eval-java index ba6f2446..5679aa03 100755 Binary files a/make/bin/darwin_amd64/eval-java and b/make/bin/darwin_amd64/eval-java differ diff --git a/make/bin/darwin_arm64/eval-java b/make/bin/darwin_arm64/eval-java index 1c85ed04..434197f5 100755 Binary files a/make/bin/darwin_arm64/eval-java and b/make/bin/darwin_arm64/eval-java differ diff --git a/make/bin/linux_amd64/eval-java b/make/bin/linux_amd64/eval-java index 7dcb27f3..22788047 100755 Binary files a/make/bin/linux_amd64/eval-java and b/make/bin/linux_amd64/eval-java differ diff --git a/make/bin/linux_arm64/eval-java b/make/bin/linux_arm64/eval-java index 6945ce0e..81842559 100755 Binary files a/make/bin/linux_arm64/eval-java and b/make/bin/linux_arm64/eval-java differ diff --git a/make/bin/windows_amd64/eval-java.exe b/make/bin/windows_amd64/eval-java.exe index cce8d6b4..4f48a471 100755 Binary files a/make/bin/windows_amd64/eval-java.exe and b/make/bin/windows_amd64/eval-java.exe differ diff --git a/make/enable-java-shell.mk b/make/enable-java-shell.mk index 80b7674e..76fbc7b8 100644 --- a/make/enable-java-shell.mk +++ b/make/enable-java-shell.mk @@ -2,38 +2,77 @@ ifneq ($(firstword $(sort $(MAKE_VERSION) 3.82)), 3.82) $(error "GNU Make 3.82 is required to run this script") endif -ifeq ($(OS),Windows_NT) -SHELL := $(dir $(lastword $(MAKEFILE_LIST)))bin/windows_amd64/eval-java.exe +ifneq (,$(findstring Windows,$(OS))$(findstring WINDOWS,$(OS))) +EVAL_JAVA := $(dir $(lastword $(MAKEFILE_LIST)))bin/windows_amd64/eval-java.exe +SHELL := $(EVAL_JAVA) else +ifneq ($(patsubst %.exe,%,$(notdir $(SHELL))),eval-java) UNAME_S := $(shell uname -s) -UNAME_P := $(shell uname -p) +UNAME_P := $(shell uname -m) ifeq ($(UNAME_S),Darwin) ifneq ($(filter arm%,$(UNAME_P))$(filter aarch%,$(UNAME_P)),) -SHELL := $(dir $(lastword $(MAKEFILE_LIST)))bin/darwin_arm64/eval-java +EVAL_JAVA := $(dir $(lastword $(MAKEFILE_LIST)))bin/darwin_arm64/eval-java else -SHELL := $(dir $(lastword $(MAKEFILE_LIST)))bin/darwin_amd64/eval-java +EVAL_JAVA := $(dir $(lastword $(MAKEFILE_LIST)))bin/darwin_amd64/eval-java endif else -ifeq ($(UNAME_S),Linux) ifneq ($(filter arm%,$(UNAME_P))$(filter aarch%,$(UNAME_P)),) -SHELL := $(dir $(lastword $(MAKEFILE_LIST)))bin/linux_arm64/eval-java +EVAL_JAVA := $(dir $(lastword $(MAKEFILE_LIST)))bin/linux_arm64/eval-java else -SHELL := $(dir $(lastword $(MAKEFILE_LIST)))bin/linux_amd64/eval-java +EVAL_JAVA := $(dir $(lastword $(MAKEFILE_LIST)))bin/linux_amd64/eval-java endif +endif +ifneq ($(shell \ + if ! $(EVAL_JAVA) --verify 2>/dev/null; then \ + echo "$(EVAL_JAVA) can not be executed on this platform. Compiling it from source" >&2; \ + echo "cc $(dir $(lastword $(MAKEFILE_LIST)))eval-java.c -o $(EVAL_JAVA)" >&2; \ + cc $(dir $(lastword $(MAKEFILE_LIST)))eval-java.c -o $(EVAL_JAVA); \ + fi; \ + echo $$? ),0) +$(error Failed to compile eval-java.c) else -SHELL := $(dir $(lastword $(MAKEFILE_LIST)))bin/windows_amd64/eval-java.exe +SHELL := $(EVAL_JAVA) endif endif endif + .SHELLFLAGS := +# Reset environment variables to avoid pass-through, when one Makefile +# invokes make in another directory. +CLASSPATH := +IMPORTS := +STATIC_IMPORTS := +JAVA_REPL_PORT := +unexport CLASSPATH IMPORTS STATIC_IMPORTS JAVA_REPL_PORT + JAVA_VERSION := $(shell println(getJavaVersion());) ifeq ($(JAVA_VERSION),) # probably because java not found or exited with a UnsupportedClassVersionError -$(error "Java 8 is required to run this script") +$(error Java 8 is required to run this script) else ifeq ($(shell println($(JAVA_VERSION) >= 8);), false) -$(error "Java 8 is required to run this script") +$(error Java 8 is required to run this script) endif OS := $(shell println(getOS());) + +ifneq ($(OS), WINDOWS) +export JAVA_REPL_KILL_AFTER_IDLE := 10 +# The following is not enabled by default, because starting the server +# now means that any changes to environment variables after the +# include of enable-java-shell.mk will not be noticed by +# java-eval. This includes the environment variables JAVA_HOME, IMPORTS +# and STATIC_IMPORTS, and any other environment variables used by a +# recipe. Users may optionally include this line in their Makefile, at +# a position of their liking. +#export JAVA_REPL_PORT := $(shell --spawn-repl-server) +endif + +# utility function for helping with the migration from bash to java shell +define \n + + +endef +quote-for-java = "$(subst ${\n},\n,$(subst ",\",$(subst \,\\,$(1))))" +bash = exec("bash", "-c", $(call quote-for-java,$1)); diff --git a/make/eval-java.c b/make/eval-java.c new file mode 100644 index 00000000..abd3c661 --- /dev/null +++ b/make/eval-java.c @@ -0,0 +1,281 @@ +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#else +#include +#include +#include +#include +#include +#endif + +char *quote(char *string) { + int len = strlen(string); + int new_len = len + 2; + for (int i = 0; i < len; i++) { + int k = 0; + while (i + k < len && string[i + k] == '\\') + k++; + if (string[i + k] == '"') + new_len++; + } + char *quoted = malloc(new_len + 1); + int j = 0; + quoted[j++] = '"'; + for (int i = 0; i < len; i++) { + int k = 0; + while (i + k < len && string[i + k] == '\\') + k++; + if (string[i + k] == '"') + quoted[j++] = '\\'; + quoted[j++] = string[i]; + } + quoted[j++] = '"'; + quoted[j++] = '\0'; + return quoted; +} + +#ifdef _WIN32 +#define PATH_SEPARATOR ';' +#else +#define PATH_SEPARATOR ':' +#endif + +void exec_java(char *this_executable, char *java_executable, char *java_code, int argc, char **argv) { + char *classpath = malloc(strlen(this_executable) + strlen("/../../..") + 1); + *classpath = '\0'; + strcat(classpath, this_executable); + strcat(classpath, "/../../.."); +#ifdef _WIN32 + char **java_argv = malloc((8 + argc) * sizeof (char *)); +#else + char **java_argv = malloc((7 + argc) * sizeof (char *)); +#endif + int i = 0; + java_argv[i++] = java_executable; + java_argv[i++] = "-classpath"; + java_argv[i++] = classpath; +#ifdef _WIN32 + // to work around a bug in ProcessBuilder + java_argv[i++] = "-Djdk.lang.Process.allowAmbiguousCommands=false"; +#endif + java_argv[i++] = "eval_java"; + java_argv[i++] = this_executable; + java_argv[i++] = java_code; + for (int j = 0; j < argc; j++) + java_argv[i++] = argv[j]; + java_argv[i] = NULL; +#ifdef _WIN32 + // because of how spawnvp works we need to quote the arguments + // (see https://docs.microsoft.com/en-us/cpp/c-runtime-library/spawn-wspawn-functions) + for (i = 0; java_argv[i]; i++) + java_argv[i] = quote(java_argv[i]); + int child_status = spawnvp(P_WAIT, java_executable, java_argv); + if (child_status == -1) { + fprintf(stderr, "%s: error running command `%s' (%s)\n", this_executable, java_executable, strerror(errno)); + exit(EXIT_FAILURE); + } + exit(child_status); +#else + pid_t child_pid; + pid_t w; + int child_status; + child_pid = fork(); + if (child_pid == -1) { + perror("fork"); + exit(EXIT_FAILURE); + } else if (child_pid == 0) { + execvp(java_executable, java_argv); + // command above only returns if error occurs + fprintf(stderr, "%s: error running command `%s' (%s)\n", this_executable, java_executable, strerror(errno)); + exit(EXIT_FAILURE); + } else { + do { + w = waitpid(child_pid, &child_status, 0); + if (w == -1) { + perror("waitpid"); + exit(EXIT_FAILURE); + } + if (WIFEXITED(child_status)) + // Note that trying to run this class with Java < 8 will result in: + // + // Exception in thread "main" java.lang.UnsupportedClassVersionError: eval_java : + // Unsupported major.minor version 52.0 + // + // This error can not be caught in Java and because the exit code is 1 it can not be + // caught in C either. + exit(WEXITSTATUS(child_status)); + else { + fprintf(stderr, "%s: command `%s' did not exit normally\n", this_executable, java_executable); + exit(EXIT_FAILURE); + } + } while (!WIFEXITED(child_status)); + } + exit(EXIT_SUCCESS); +#endif +} + +#ifndef _WIN32 +void exec_java_repl_client(char *this_executable, char *java_code, int port) { + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) + // Failed to create socket. This should not happen, but fall back to evaluating Java + // directly. + return; + struct sockaddr_in servaddr; + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + servaddr.sin_port = htons(port); + if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0) + // Failed to connect to REPL on address 127.0.0.1 and specified port. Perhaps the server was + // started but was stopped in the meantime. Fall back to evaluating Java directly. + return; + write(sockfd, java_code, strlen(java_code)); + static char NEWLINE = '\n'; + write(sockfd, &NEWLINE, 1); + FILE *in_stream= fdopen(sockfd, "r"); + unsigned int buflen = 1000; + char buf[buflen]; + int new_line = 1; + FILE *out_stream = stdout; + int exit_value = 0; + int done = 0; + for (;;) { + bzero(buf, buflen); + if (fgets(buf, buflen, in_stream) == NULL) + break; + if (done) + goto unexpected; + if (new_line) { + switch (buf[0]) { + case '1': + out_stream = stdout; + break; + case '2': + out_stream = stderr; + break; + case 'x': + if (buf[1] != ':') + goto unexpected; + intmax_t v = strtoimax(&buf[2], NULL, 10); + if (errno) { + fprintf(stderr, "%s: could not parse exit value: %s\n", this_executable, &buf[2]); + fflush(stdout); + fflush(stderr); + exit(EXIT_FAILURE); + } + exit_value = v; + done = 1; + continue; + default: + goto unexpected; + } + if (buf[1] != ':') + goto unexpected; + fprintf(out_stream, "%s", &buf[2]); + } else + fprintf(out_stream, "%s", buf); + new_line = (buf[strlen(buf) - 1] == '\n'); + } + if (!done) { + fprintf(stderr, "%s: server hung up without providing exit value. System.exit() might have been called.\n", this_executable); + exit_value = 1; + } + cleanup: + fclose(in_stream); + close(sockfd); + fflush(stdout); + fflush(stderr); + exit(exit_value); + unexpected: + fprintf(stderr, "%s: received unexpected message from server: %s\n", this_executable, buf); + exit_value = 1; + goto cleanup; +} +#endif + +int main(int argc, char **argv) { + char *this_executable_path = argv[0]; + if (argc < 2) { + fprintf(stderr, "%s: expected at least one argument\n", argv[0]); + exit(EXIT_FAILURE); + } + if (argc == 2 && strcmp(argv[1], "--verify") == 0) + // just checking that the binary can be executed on the current platform + exit(EXIT_SUCCESS); + char *java_code = argv[1]; + int extra_argc = 0; + char **extra_argv = NULL; + if (argc > 2) { + if (strcmp(argv[2], "--") != 0) { + fprintf(stderr, "%s: unexpected argument: %s\n", argv[0], argv[2]); + exit(EXIT_FAILURE); + } + extra_argc = argc - 3; + extra_argv = &argv[3]; + } +#ifndef _WIN32 + if (extra_argc == 0) { + char *JAVA_REPL_PORT = getenv("JAVA_REPL_PORT"); + if (JAVA_REPL_PORT && *JAVA_REPL_PORT) { + // try to connect with REPL + intmax_t port = strtoimax(JAVA_REPL_PORT, NULL, 10); + if (errno) { + fprintf(stderr, "%s: could not parse JAVA_REPL_PORT: %s\n", this_executable_path, JAVA_REPL_PORT); + exit(EXIT_FAILURE); + } + if (port < 0 || port > 65535) { + fprintf(stderr, "%s: not a valid port number: %jd\n", this_executable_path, port); + exit(EXIT_FAILURE); + } + exec_java_repl_client(this_executable_path, java_code, port); + } + } +#endif + char *JAVA_HOME = getenv("JAVA_HOME"); + if (JAVA_HOME) { + char *java = malloc(strlen(JAVA_HOME) + 14); + strcpy(java, JAVA_HOME); +#ifdef _WIN32 + strcat(java, "\\bin\\java.exe"); +#else + strcat(java, "/bin/java"); +#endif + FILE *f; + if ((f = fopen(java, "r"))) { + fclose(f); + exec_java(this_executable_path, java, java_code, extra_argc, extra_argv); + } + free(java); + } + char *PATH = strdup(getenv("PATH")); + char *dir = PATH; + char *sep = NULL; + do { + sep = strchr(dir, PATH_SEPARATOR); + if (sep != NULL) + sep[0] = '\0'; + char *java = malloc(strlen(dir) + 10); + strcpy(java, dir); +#ifdef _WIN32 + strcat(java, "\\java.exe"); +#else + strcat(java, "/java"); +#endif + FILE *f; + if ((f = fopen(java, "r"))) { + fclose(f); + exec_java(this_executable_path, java, java_code, extra_argc, extra_argv); + } + free(java); + dir = sep ? sep + 1 : NULL; + } while (dir != NULL); + free(PATH); + fprintf(stderr, "%s: Java is required to run this script (but not found in JAVA_HOME or on PATH)\n", this_executable_path); + exit(EXIT_FAILURE); +} diff --git a/make/eval_java$MultiplexedOutputStream.class b/make/eval_java$MultiplexedOutputStream.class new file mode 100644 index 00000000..cf7a7e5d Binary files /dev/null and b/make/eval_java$MultiplexedOutputStream.class differ diff --git a/make/eval_java.class b/make/eval_java.class index e2f3b6a1..f58226f9 100644 Binary files a/make/eval_java.class and b/make/eval_java.class differ diff --git a/make/lib/lib/util$1.class b/make/lib/lib/util$1.class index 85680586..1de1addf 100644 Binary files a/make/lib/lib/util$1.class and b/make/lib/lib/util$1.class differ diff --git a/make/lib/lib/util$OS.class b/make/lib/lib/util$OS.class index ef005dc0..909f317b 100644 Binary files a/make/lib/lib/util$OS.class and b/make/lib/lib/util$OS.class differ diff --git a/make/lib/lib/util$SystemExit.class b/make/lib/lib/util$SystemExit.class new file mode 100644 index 00000000..33350b1e Binary files /dev/null and b/make/lib/lib/util$SystemExit.class differ diff --git a/make/lib/lib/util.class b/make/lib/lib/util.class index b3b7bca3..f62e0bc0 100644 Binary files a/make/lib/lib/util.class and b/make/lib/lib/util.class differ diff --git a/pom.xml b/pom.xml index 48ddbd47..3b4cb904 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ org.daisy.pipeline assembly - 1.15.1-SNAPSHOT + 1.15.2-SNAPSHOT jar DAISY Pipeline 2 :: Assembly Builds the main distribution of the DAISY Pipeline 2. @@ -20,7 +20,7 @@ HEAD - 2.2.1 + 2.3.0 @@ -596,6 +591,16 @@ + + org.daisy.pipeline.modules + dtbook-to-ebraille + + + * + * + + + org.daisy.pipeline.modules dtbook-to-epub3 @@ -1738,101 +1743,6 @@ maven-dependency-plugin - - copy-felix-launcher - process-sources - - copy - - - ${project.build.directory}/jars/osgi/bootstrap - - - org.apache.felix - org.apache.felix.main - felix.jar - - - - - - copy-felix-bundles - process-sources - - copy - - - ${project.build.directory}/jars/osgi/bundles - - - org.apache.felix - org.apache.felix.configadmin - 1.6.0 - - - org.apache.felix - org.apache.felix.dependencymanager - 3.1.0 - - - org.apache.felix - org.apache.felix.eventadmin - 1.3.2 - - - org.apache.felix - org.apache.felix.fileinstall - 3.2.6 - - - org.apache.felix - org.apache.felix.log - 1.0.1 - - - org.apache.felix - org.apache.felix.metatype - 1.0.6 - - - org.apache.felix - org.apache.felix.scr - 2.0.14 - - - org.osgi - org.osgi.enterprise - - - - - - copy-felix-gogo - process-sources - - copy - - - ${project.build.directory}/jars/osgi/gogo - - - org.apache.felix - org.apache.felix.gogo.command - 0.14.0 - - - org.apache.felix - org.apache.felix.gogo.runtime - 0.12.1 - - - org.apache.felix - org.apache.felix.gogo.shell - 0.10.0 - - - - copy-framework process-sources @@ -1954,26 +1864,6 @@ - - copy-framework-osgi - process-sources - - copy - - - ${project.build.directory}/jars/osgi/bundles - - - org.daisy.pipeline - woodstox-osgi-adapter - - - org.daisy.libs - logback-osgi-adapter - - - - copy-framework-no-osgi process-sources @@ -2095,22 +1985,6 @@ - - copy-persistence-osgi - process-sources - - copy - - - ${project.build.directory}/jars/osgi/persistence - - - org.eclipse.gemini - org.apache.derby - - - - copy-persistence-no-osgi process-sources @@ -2257,6 +2131,10 @@ org.daisy.pipeline.modules dtbook-break-detection + + org.daisy.pipeline.modules + dtbook-to-ebraille + org.daisy.pipeline.modules dtbook-to-epub3 @@ -2649,45 +2527,6 @@ - - copy-modules-osgi - process-sources - - copy - - - ${project.build.directory}/jars/osgi/bundles - - - - org.daisy.libs - jing - 20120724.0.0 - - - - org.codehaus.jackson - jackson-core-asl - - - org.codehaus.jackson - jackson-mapper-asl - - - - org.daisy.libs - jnaerator - - - - copy-modules-linux process-sources @@ -2768,6 +2607,7 @@ + generate-release-descriptor @@ -2971,96 +2811,6 @@ - - unpack-updater-mac - - - - maven-dependency-plugin - - - unpack-updater-mac - generate-resources - - unpack - - - - - org.daisy.pipeline - updater - zip - darwin_amd64 - ${project.build.directory}/updater/mac32 - - - - - - - - - - - unpack-updater-linux - - - - maven-dependency-plugin - - - unpack-updater-linux - generate-resources - - unpack - - - - - org.daisy.pipeline - updater - zip - linux_386 - ${project.build.directory}/updater/linux32 - - - - - - - - - - - unpack-updater-win - - - - maven-dependency-plugin - - - unpack-updater-win - generate-resources - - unpack - - - - - org.daisy.pipeline - updater - zip - windows_386 - ${project.build.directory}/updater/win32 - - - - - - - - - assemble-mac-dir @@ -3262,39 +3012,6 @@ - - assemble-minimal-zip - - - - maven-assembly-plugin - - - assemble-minimal-zip - package - - single - - - false - - zip - - - src/main/assembly/dist-minimal.xml - - - src/main/assembly/dist.properties - src/main/assembly/dist-linux.properties - - true - - - - - - - package-exe @@ -3848,7 +3565,7 @@ - without-osgi + with-osgi @@ -3856,27 +3573,173 @@ copy-felix-launcher - none + process-sources + + copy + + + ${project.build.directory}/jars/osgi/bootstrap + + + org.apache.felix + org.apache.felix.main + felix.jar + + + copy-felix-bundles - none + process-sources + + copy + + + ${project.build.directory}/jars/osgi/bundles + + + org.apache.felix + org.apache.felix.configadmin + 1.6.0 + + + org.apache.felix + org.apache.felix.dependencymanager + 3.1.0 + + + org.apache.felix + org.apache.felix.eventadmin + 1.3.2 + + + org.apache.felix + org.apache.felix.fileinstall + 3.2.6 + + + org.apache.felix + org.apache.felix.log + 1.0.1 + + + org.apache.felix + org.apache.felix.metatype + 1.0.6 + + + org.apache.felix + org.apache.felix.scr + 2.0.14 + + + org.osgi + org.osgi.enterprise + + + copy-felix-gogo - none + process-sources + + copy + + + ${project.build.directory}/jars/osgi/gogo + + + org.apache.felix + org.apache.felix.gogo.command + 0.14.0 + + + org.apache.felix + org.apache.felix.gogo.runtime + 0.12.1 + + + org.apache.felix + org.apache.felix.gogo.shell + 0.10.0 + + + copy-framework-osgi - none + process-sources + + copy + + + ${project.build.directory}/jars/osgi/bundles + + + org.daisy.pipeline + woodstox-osgi-adapter + + + org.daisy.libs + logback-osgi-adapter + + + copy-modules-osgi - none + process-sources + + copy + + + ${project.build.directory}/jars/osgi/bundles + + + + org.daisy.libs + jing + 20120724.0.0 + + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-mapper-asl + + + + org.daisy.libs + jnaerator + + + copy-persistence-osgi - none + process-sources + + copy + + + ${project.build.directory}/jars/osgi/persistence + + + org.eclipse.gemini + org.apache.derby + + + @@ -3923,30 +3786,6 @@ - - without-updater - - - - maven-dependency-plugin - - - unpack-updater-mac - none - - - unpack-updater-linux - none - - - unpack-updater-win - none - - - - - - test-batch @@ -4023,17 +3862,5 @@ false - - - com.springsource.repository.bundles.external - SpringSource Enterprise Bundle Repository - External Bundle Releases - https://repository.springsource.com/maven/bundles/external - - true - - - false - - diff --git a/src/main/assembly/components/updater-all.xml b/src/main/assembly/components/updater-all.xml deleted file mode 100644 index 86da2fba..00000000 --- a/src/main/assembly/components/updater-all.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - target/updater/linux32 - updater/linux - - pipeline-updater* - - 0755 - - - target/updater/mac32 - updater/mac - - pipeline-updater* - - 0755 - - - - - target/updater/win32/pipeline-updater.exe - updater/windows - pipeline-updater.exe - 0755 - - - diff --git a/src/main/assembly/components/updater-linux.xml b/src/main/assembly/components/updater-linux.xml deleted file mode 100644 index 9897be05..00000000 --- a/src/main/assembly/components/updater-linux.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - target/updater/linux32 - updater - - pipeline-updater* - - 0755 - - - diff --git a/src/main/assembly/components/updater-mac.xml b/src/main/assembly/components/updater-mac.xml deleted file mode 100644 index a02fdfe1..00000000 --- a/src/main/assembly/components/updater-mac.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - target/updater/mac32 - updater - - pipeline-updater* - - 0755 - - - diff --git a/src/main/assembly/components/updater-win.xml b/src/main/assembly/components/updater-win.xml deleted file mode 100644 index f13af1c2..00000000 --- a/src/main/assembly/components/updater-win.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - target/updater/win32 - updater - - pipeline-updater.exe - - 0755 - - - diff --git a/src/main/assembly/dist-linux.xml b/src/main/assembly/dist-linux.xml index cbdaf6c0..13ea4db3 100644 --- a/src/main/assembly/dist-linux.xml +++ b/src/main/assembly/dist-linux.xml @@ -12,7 +12,6 @@ src/main/assembly/components/jars.xml src/main/assembly/components/jars-linux.xml src/main/assembly/components/cli-linux.xml - src/main/assembly/components/updater-linux.xml src/main/assembly/components/simple-api.xml diff --git a/src/main/assembly/dist-mac.xml b/src/main/assembly/dist-mac.xml index 5cb61040..cf303cd5 100644 --- a/src/main/assembly/dist-mac.xml +++ b/src/main/assembly/dist-mac.xml @@ -12,7 +12,6 @@ src/main/assembly/components/jars.xml src/main/assembly/components/jars-mac.xml src/main/assembly/components/cli-mac.xml - src/main/assembly/components/updater-mac.xml src/main/assembly/components/simple-api.xml src/main/assembly/components/jre-mac.xml diff --git a/src/main/assembly/dist-minimal.xml b/src/main/assembly/dist-minimal.xml deleted file mode 100644 index 2eb61d0b..00000000 --- a/src/main/assembly/dist-minimal.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - minimal - - zip - dir - - daisy-pipeline - - src/main/assembly/components/base.xml - src/main/assembly/components/bin-linux.xml - src/main/assembly/components/bin-win.xml - src/main/assembly/components/updater-all.xml - - diff --git a/src/main/assembly/dist-win.xml b/src/main/assembly/dist-win.xml index 6dbd73c9..43340fdd 100644 --- a/src/main/assembly/dist-win.xml +++ b/src/main/assembly/dist-win.xml @@ -12,7 +12,6 @@ src/main/assembly/components/jars.xml src/main/assembly/components/jars-win.xml src/main/assembly/components/cli-win.xml - src/main/assembly/components/updater-win.xml src/main/assembly/components/simple-api.xml src/main/assembly/components/jre-win.xml diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile index e4a21303..aac96370 100644 --- a/src/main/docker/Dockerfile +++ b/src/main/docker/Dockerfile @@ -1,5 +1,6 @@ FROM debian:bookworm LABEL maintainer="DAISY Consortium (http://www.daisy.org/)" +RUN apt-get update && apt-get install -y espeak ADD daisy-pipeline /opt/daisy-pipeline2 ADD logback.xml /opt/daisy-pipeline2/etc/logback.xml ARG TARGETARCH diff --git a/src/main/resources/cli/config.yml b/src/main/resources/cli/config.yml index 4feab9dd..d9dc1c69 100644 --- a/src/main/resources/cli/config.yml +++ b/src/main/resources/cli/config.yml @@ -1,17 +1,29 @@ -#WS CONFIGURATION +# Host part of webservice address +# Leave empty if you wish to use the app_path setting host: http://localhost + +# Port part of webservice address +# Leave empty if you wish to use the app_path setting port: 8181 + +# Path part of webservice address, as in HOST:PORT/PATH (e.g. http://localhost:8181/ws) +# Leave empty if you wish to use the app_path setting ws_path: ws -ws_timeup: 25 -#DP2 launch config + +# Timeout for requests to the webservice in seconds +timeout: 10 + +# Path to webservice launch script exec_line: ${pipeline.cli.exec_line} -local: true -# ROBOT CONF -client_key: ${pipeline.cli.clientkey} -client_secret: ${pipeline.cli.clientsecret} -#connection settings -timeout: 60 -#debug + +# Client key for authenticated requests +#client_key: ${pipeline.cli.clientkey} + +# Client secrect for authenticated requests +#client_secret: ${pipeline.cli.clientsecret} + +# Print debug messages debug: false -starting: ${pipeline.cli.starting} +# Start the DAISY Pipeline app if it is not running +starting: ${pipeline.cli.starting}