From 1a4954a24f6be408f7fc3f2d8d0af52b86f4f40f Mon Sep 17 00:00:00 2001 From: pponec Date: Fri, 29 Sep 2023 12:22:10 +0200 Subject: [PATCH 1/3] GIT ignores --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 1624643..a69bb15 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ # BlueJ files *.ctxt +# IntelliJ IDEA +.idea + # Mobile Tools for Java (J2ME) .mtj.tmp/ From 6f606438ec00c8491118880900205afb7c75ca82 Mon Sep 17 00:00:00 2001 From: pponec Date: Fri, 29 Sep 2023 12:25:44 +0200 Subject: [PATCH 2/3] Binary building by a Marcus --- mavenForQuarkus/.dockerignore | 5 + mavenForQuarkus/.gitignore | 35 ++ .../.mvn/wrapper/maven-wrapper.properties | 18 + mavenForQuarkus/README.md | 81 ++++ mavenForQuarkus/mvnw | 316 ++++++++++++++ mavenForQuarkus/mvnw.cmd | 188 +++++++++ mavenForQuarkus/pom.xml | 113 +++++ .../src/main/docker/Dockerfile.jvm | 98 +++++ .../src/main/docker/Dockerfile.legacy-jar | 94 +++++ .../src/main/docker/Dockerfile.native | 27 ++ .../src/main/docker/Dockerfile.native-micro | 30 ++ .../commandmode/DirectoryBookmarks.java | 386 ++++++++++++++++++ .../getting/started/commandmode/Start.java | 19 + .../src/main/resources/application.properties | 5 + 14 files changed, 1415 insertions(+) create mode 100644 mavenForQuarkus/.dockerignore create mode 100644 mavenForQuarkus/.gitignore create mode 100644 mavenForQuarkus/.mvn/wrapper/maven-wrapper.properties create mode 100644 mavenForQuarkus/README.md create mode 100755 mavenForQuarkus/mvnw create mode 100644 mavenForQuarkus/mvnw.cmd create mode 100644 mavenForQuarkus/pom.xml create mode 100644 mavenForQuarkus/src/main/docker/Dockerfile.jvm create mode 100644 mavenForQuarkus/src/main/docker/Dockerfile.legacy-jar create mode 100644 mavenForQuarkus/src/main/docker/Dockerfile.native create mode 100644 mavenForQuarkus/src/main/docker/Dockerfile.native-micro create mode 100644 mavenForQuarkus/src/main/java/org/acme/getting/started/commandmode/DirectoryBookmarks.java create mode 100644 mavenForQuarkus/src/main/java/org/acme/getting/started/commandmode/Start.java create mode 100644 mavenForQuarkus/src/main/resources/application.properties diff --git a/mavenForQuarkus/.dockerignore b/mavenForQuarkus/.dockerignore new file mode 100644 index 0000000..ab14769 --- /dev/null +++ b/mavenForQuarkus/.dockerignore @@ -0,0 +1,5 @@ +* +!target/*-runner +!target/*-runner.jar +!target/lib/* +!target/quarkus-app/ diff --git a/mavenForQuarkus/.gitignore b/mavenForQuarkus/.gitignore new file mode 100644 index 0000000..087a183 --- /dev/null +++ b/mavenForQuarkus/.gitignore @@ -0,0 +1,35 @@ +# Eclipse +.project +.classpath +.settings/ +bin/ + +# IntelliJ +.idea +*.ipr +*.iml +*.iws + +# NetBeans +nb-configuration.xml + +# Visual Studio Code +.vscode + +# OSX +.DS_Store + +# Vim +*.swp +*.swo + +# patch +*.orig +*.rej + +# Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +release.properties \ No newline at end of file diff --git a/mavenForQuarkus/.mvn/wrapper/maven-wrapper.properties b/mavenForQuarkus/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..dc3affc --- /dev/null +++ b/mavenForQuarkus/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar diff --git a/mavenForQuarkus/README.md b/mavenForQuarkus/README.md new file mode 100644 index 0000000..8613242 --- /dev/null +++ b/mavenForQuarkus/README.md @@ -0,0 +1,81 @@ +# Getting started with Quarkus command mode + +This is a minimal command mode application that access Quarkus API's. + +Under the hood, this demo uses: + +- `@QuarkusMain` to enable a custom main class + +## Requirements + +To compile and run this demo you will need: + +- JDK 11+ +- GraalVM + +### Configuring GraalVM and JDK 11+ + +Make sure that both the `GRAALVM_HOME` and `JAVA_HOME` environment variables have +been set, and that a JDK 11+ `java` command is on the path. + +See the [Building a Native Executable guide](https://quarkus.io/guides/building-native-image-guide) +for help setting up your environment. + +## Building the application + +Launch the Maven build on the checked out sources of this demo: + +> ./mvnw package + +### Live coding with Quarkus + +The Maven Quarkus plugin provides a development mode that supports +live coding. To try this out: + +> ./mvnw quarkus:dev + +or + +> ./mvnw quarkus:dev -Dquarkus.args= + +if you want to pass arguments in. + +This command will run the command mode application and if you press enter run it again. + +1. Make a change in [src/main/java/org/acme/getting/started/commandmode/GreetingResource.java](src/main/java/org/acme/getting/started/commandmode/GreetingService.java). Replace `hello` with `hello there` in the `greeting()` method. + - Press Enter in your terminal. + You should now see `hello there`. + - Undo the change, so the method returns `hello` again. + - Press Enter again. You should now see `hello`. + +### Run Quarkus in JVM mode + +When you're done iterating in developer mode, you can run the application as a +conventional jar file. + +First compile it: + +> ./mvnw package + +Then run it: + +> java -jar ./target/quarkus-app/quarkus-run.jar + +Have a look at how fast it boots, or measure the total native memory consumption. + +### Run Quarkus as a native executable + +You can also create a native executable from this application without making any +source code changes. A native executable removes the dependency on the JVM: +everything needed to run the application on the target platform is included in +the executable, allowing the application to run with minimal resource overhead. + +Compiling a native executable takes a bit longer, as GraalVM performs additional +steps to remove unnecessary codepaths. Use the `native` profile to compile a +native executable: + +> ./mvnw package -Dnative + +After getting a cup of coffee, you'll be able to run this executable directly: + +> ./target/getting-started-command-mode-1.0.0-SNAPSHOT-runner diff --git a/mavenForQuarkus/mvnw b/mavenForQuarkus/mvnw new file mode 100755 index 0000000..5643201 --- /dev/null +++ b/mavenForQuarkus/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mavenForQuarkus/mvnw.cmd b/mavenForQuarkus/mvnw.cmd new file mode 100644 index 0000000..8a15b7f --- /dev/null +++ b/mavenForQuarkus/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/mavenForQuarkus/pom.xml b/mavenForQuarkus/pom.xml new file mode 100644 index 0000000..448fe1a --- /dev/null +++ b/mavenForQuarkus/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + + org.acme + getting-started-command-mode + 1.0.0-SNAPSHOT + + + quarkus-bom + io.quarkus.platform + 3.4.1 + 3.11.0 + 3.1.2 + UTF-8 + 17 + 17 + true + + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-junit5 + test + + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + + + + build + + + + + + + + + + + native + + + native + + + + native + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + + diff --git a/mavenForQuarkus/src/main/docker/Dockerfile.jvm b/mavenForQuarkus/src/main/docker/Dockerfile.jvm new file mode 100644 index 0000000..3a93de3 --- /dev/null +++ b/mavenForQuarkus/src/main/docker/Dockerfile.jvm @@ -0,0 +1,98 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./mvnw package +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/getting-started-command-mode-jvm . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/getting-started-command-mode-jvm +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/getting-started-command-mode-jvm +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-11:1.16 + +ENV LANGUAGE='en_US:en' + + +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/ +COPY --chown=185 target/quarkus-app/*.jar /deployments/ +COPY --chown=185 target/quarkus-app/app/ /deployments/app/ +COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8080 +USER 185 +ENV AB_JOLOKIA_OFF="" +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] + diff --git a/mavenForQuarkus/src/main/docker/Dockerfile.legacy-jar b/mavenForQuarkus/src/main/docker/Dockerfile.legacy-jar new file mode 100644 index 0000000..22116a4 --- /dev/null +++ b/mavenForQuarkus/src/main/docker/Dockerfile.legacy-jar @@ -0,0 +1,94 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./mvnw package -Dquarkus.package.type=legacy-jar +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/getting-started-command-mode-legacy-jar . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/getting-started-command-mode-legacy-jar +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/getting-started-command-mode-legacy-jar +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-11:1.16 + +ENV LANGUAGE='en_US:en' + + +COPY target/lib/* /deployments/lib/ +COPY target/*-runner.jar /deployments/quarkus-run.jar + +EXPOSE 8080 +USER 185 +ENV AB_JOLOKIA_OFF="" +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] diff --git a/mavenForQuarkus/src/main/docker/Dockerfile.native b/mavenForQuarkus/src/main/docker/Dockerfile.native new file mode 100644 index 0000000..1e67dfe --- /dev/null +++ b/mavenForQuarkus/src/main/docker/Dockerfile.native @@ -0,0 +1,27 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# +# Before building the container image run: +# +# ./mvnw package -Dnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native -t quarkus/getting-started-command-mode . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/getting-started-command-mode +# +### +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root target/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/mavenForQuarkus/src/main/docker/Dockerfile.native-micro b/mavenForQuarkus/src/main/docker/Dockerfile.native-micro new file mode 100644 index 0000000..f7ba08d --- /dev/null +++ b/mavenForQuarkus/src/main/docker/Dockerfile.native-micro @@ -0,0 +1,30 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# It uses a micro base image, tuned for Quarkus native executables. +# It reduces the size of the resulting container image. +# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. +# +# Before building the container image run: +# +# ./mvnw package -Dnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/getting-started-command-mode . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/getting-started-command-mode +# +### +FROM quay.io/quarkus/quarkus-micro-image:2.0 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root target/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/mavenForQuarkus/src/main/java/org/acme/getting/started/commandmode/DirectoryBookmarks.java b/mavenForQuarkus/src/main/java/org/acme/getting/started/commandmode/DirectoryBookmarks.java new file mode 100644 index 0000000..acc5732 --- /dev/null +++ b/mavenForQuarkus/src/main/java/org/acme/getting/started/commandmode/DirectoryBookmarks.java @@ -0,0 +1,386 @@ +package org.acme.getting.started.commandmode; + +// Running by Java 17: $ java org.acme.getting.started.commandmode.DirectoryBookmarks.java +// Licence: Apache License, Version 2.0, https://github.com/pponec/ + +import javax.tools.ToolProvider; +import java.io.*; +import java.net.URI; +import java.net.URLDecoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.*; +import java.util.regex.Pattern; + +public class DirectoryBookmarks { + + private final String homePage = "https://github.com/pponec/DirectoryBookmarks"; + private final String appName = getClass().getSimpleName(); + private final String appVersion = "1.8.2"; + private final String requiredJavaModules = "java.base,java.net.http,jdk.compiler"; + private final char cellSeparator = '\t'; + private final char dirSeparator = File.separatorChar; + private final char comment = '#'; + private final String newLine = System.lineSeparator(); + private final String header = "%s A directory bookmarks for the '%s' script".formatted(comment, appName); + private final String currentDir = System.getProperty("user.dir"); + private final String currentDirMark = "."; + private final Class mainClass = getClass(); + private final String sourceUrl = "https://raw.githubusercontent.com/pponec/DirectoryBookmarks/%s/%s.java" + .formatted(true ? "main" : "development", appName); + private final File storeName; + private final PrintStream out; + + public static void main(String[] args) throws Exception { + new DirectoryBookmarks( + new File(System.getProperty("user.home"), ".directory-bookmarks.csv"), + System.out).start(args); + } + + protected DirectoryBookmarks(File storeName, PrintStream out) { + this.storeName = storeName; + this.out = out; + } + + /** The main object method */ + public void start(String... args) throws Exception { + if (args.length == 0 || args[0].isEmpty()) printHelpAndExit(); + switch (args[0].charAt(args[0].length() - 1)) { // get the last character + case 'l' -> { // list all directories or find one directory + if (args.length > 1 && !args[1].isEmpty()) { + var dir = getDirectory(args[1], " %s [bookmark] ".formatted(args[1])); + out.println(dir); + } else { + printDirectories(); + } + } + case 's' -> { + if (args.length < 3) printHelpAndExit(); + var msg = Arrays.copyOfRange(args, 3, args.length); + save(args[1], args[2], msg); // (dir, key, comments) + } + case 'r' -> { + if (args.length < 2) printHelpAndExit(); + removeBookmark(args[1]); + } + case 'b'-> { + var dir = args.length > 1 ? args[1] : currentDir; + printAllBookmarksOfDirectory(dir); + } + case 'i'-> { + printInstall(); + } + case 'f'-> { + fixMarksOfMissingDirectories(); + } + case 'c' -> { + compile(); + } + case 'u' -> { // update + download(); + if (isJar() && !isSystemWindows()) { + compile(); + out.printf("Version %s was downloaded and compiled%n", appVersion); + } else { + out.printf("Version %s was downloaded%n", appVersion); + } + } + case 'v'-> { + var scriptVersion = getScriptVersion(); + if (appVersion.equals(scriptVersion)) { + out.println(getScriptVersion()); + } else { + out.printf("%s -> %s".formatted(scriptVersion, appVersion)); + } + } + default -> { + out.printf("Arguments are not supported: %s", String.join(" ", args)); + printHelpAndExit(); + } + } + } + + private void printHelpAndExit() { + var isJar = isJar(); + var javaExe = "java %s%s.%s".formatted( + isJar ? "-jar " : "", + appName, + isJar ? "jar" : "java"); + var bashrc = "~/.bashrc"; + out.printf("Script '%s' v%s (%s)%n", appName, appVersion, homePage); + out.printf("Usage: %s [lsrbfuc] bookmark directory optionalComment%n", javaExe); + out.printf("Integrate the script to Ubuntu: %s i >> %s && . %s%n", javaExe, bashrc, bashrc); + System.exit(1); + } + + private void printDirectories() throws IOException { + var storeFile = createStoreFile(); + try (BufferedReader reader = new BufferedReader(new FileReader(storeFile))) { + reader.lines() + .filter(line -> !line.startsWith(String.valueOf(comment))) + .sorted() + .forEach(out::println); + } + } + + /** + * Find the directory or get a default value. + * @param key The directory key can end with the name of the following subdirectory. + * by the example: {@code "key/directoryName"} . + * @param defaultDir Default directory name. + */ + private String getDirectory(String key, String defaultDir) { + switch (key) { + case currentDirMark: + return currentDir; + default: + var idx = key.indexOf(dirSeparator); + var extKey = (idx >= 0 ? key.substring(0, idx) : key) + cellSeparator; + var storeFile = createStoreFile(); + try (BufferedReader reader = new BufferedReader(new FileReader(storeFile))) { + var dir = reader.lines() + .filter(line -> !line.startsWith(String.valueOf(comment))) + .filter(line -> line.startsWith(extKey)) + .map(line -> line.substring(extKey.length())) + .findFirst(); + if (dir.isPresent()) { + var dirString = dir.get(); + var commentPattern = Pattern.compile("\\s+" + comment + "\\s"); + var commentMatcher = commentPattern.matcher(dirString); + var endDir = idx >= 0 ? "" + dirSeparator + key.substring(idx + 1) : ""; + return (commentMatcher.find() + ? dirString.substring(0, commentMatcher.start()) + : dirString) + + endDir; + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + return defaultDir; + } + } + + private void removeBookmark(String key) throws IOException { + save("", key); + } + + private void save(String dir, String key, String... comments) throws IOException { + if (key.indexOf(cellSeparator) >= 0 || key.indexOf(dirSeparator) >= 0) { + throw new IllegalArgumentException("the key contains a tab or a slash"); + } + if (currentDirMark.equals(dir)) { + dir = currentDir; + } + var extendedKey = key + cellSeparator; + var tempFile = getTempStoreFile(); + var storeFile = createStoreFile(); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { + writer.append(header).append(newLine); + if (!dir.isEmpty()) { + writer.append(key).append(cellSeparator).append(dir); + if (comments.length > 0) { + writer.append(cellSeparator).append(comment); + for (String comment : comments) { + writer.append(' ').append(comment); + } + } + writer.append(newLine); + } + try (BufferedReader reader = new BufferedReader(new FileReader(storeFile))) { + reader.lines() + .filter(line -> !line.startsWith(String.valueOf(comment))) + .filter(line -> !line.startsWith(extendedKey)) + .sorted() + .forEach(line -> { + try { + writer.append(line).append(newLine); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + } + Files.move(tempFile.toPath(), storeFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + + private File createStoreFile() { + if (!storeName.isFile()) { + try { + storeName.createNewFile(); + } catch (IOException e) { + throw new IllegalStateException(storeName.toString(), e); + } + } + return storeName; + } + + private File getTempStoreFile() throws IOException { + return File.createTempFile(".dirbook", "", storeName.getParentFile()); + } + + private void fixMarksOfMissingDirectories() throws IOException { + var keys = getAllSortedKeys(); + keys.stream() + .filter(key -> { + var dir = getDirectory(key, ""); + return dir.isEmpty() || !new File(dir).isDirectory(); + }) + .forEach(key -> { + try { + var msg = "Removed: %s\t%s".formatted(key, getDirectory(key, "?")); + out.println(msg); + removeBookmark(key); + } catch (IOException e) { + throw new IllegalStateException(e); + } + }); + } + + private List getAllSortedKeys() throws IOException { + var result = Collections.emptyList(); + try (BufferedReader reader = new BufferedReader(new FileReader(createStoreFile()))) { + result = reader.lines() + .filter(line -> !line.startsWith(String.valueOf(comment))) + .sorted() + .map(line -> line.substring(0, line.indexOf(cellSeparator))) + .toList(); + } + return result; + } + + private void printAllBookmarksOfDirectory(String directory) throws IOException { + getAllSortedKeys().forEach(key -> { + if (directory.equals(getDirectory(key, ""))) { + out.println(key); + } + }); + } + + private void download() throws IOException, InterruptedException { + var client = HttpClient.newHttpClient(); + var request = HttpRequest.newBuilder() + .uri(URI.create(sourceUrl)) + .build(); + var response = client.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() == 200) { + Files.writeString(Path.of(getSrcPath()), response.body()); + } else { + throw new IllegalStateException("Downloading error code: %s".formatted(response.statusCode())); + } + } + + /** Read version from the external script. */ + private String getScriptVersion() { + final var pattern = Pattern.compile("String\\s+appVersion\\s*=\\s*\"(.+)\"\\s*;"); + try (BufferedReader reader = new BufferedReader(new FileReader(getSrcPath()))) { + return reader.lines() + .map(line -> { + final var matcher = pattern.matcher(line); + return matcher.find() ? matcher.group(1) : null; + }) + .filter(Objects::nonNull) + .findFirst() + .orElse(appVersion); + } catch (Exception e) { + return appVersion; + } + } + + private void printInstall() { + var exePath = getPathOfRunningApplication(); + var javaHome = System.getProperty("java.home"); + if (isSystemWindows()) { + var exe = "\"%s\\bin\\java\" --limit-modules %s %s\"%s\"" + .formatted(javaHome, requiredJavaModules, isJar() ? "-jar " : "", exePath); + var msg = String.join(System.lineSeparator(), "" + , "# Shortcuts for %s v%s utilities - for the PowerShell:".formatted(appName, appVersion) + , "function directoryBookmarks { & %s $args }".formatted(exe) + , "function cdf { Set-Location -Path $(directoryBookmarks -l $args) }" + , "function sdf { directoryBookmarks s . $args }" + , "function ldf { directoryBookmarks l $args }"); + out.println(msg); + } else { + var exe = "\"%s/bin/java\" --limit-modules %s %s\"%s\"" + .formatted(javaHome, requiredJavaModules, isJar() ? "-jar " : "", exePath); + var msg = String.join(System.lineSeparator(), "" + , "# Shortcuts for %s v%s utilities - for the Bash:".formatted(appName, appVersion) + , "alias directoryBookmarks='%s'".formatted(exe) + , "cdf() { cd \"$(directoryBookmarks l $1)\"; }" + , "sdf() { directoryBookmarks s %s \"$@\"; }".formatted(currentDirMark) + , "ldf() { directoryBookmarks l \"$1\"; }"); + out.println(msg); + } + } + + // ~ ~ ~ ~ ~ ~ ~ UTILITIES ~ ~ ~ ~ ~ ~ ~ + + /** Compile the script and build it to the executable JAR file */ + private void compile() throws Exception { + var scriptDir = getScriptDir(); + var jarExe = "%s/bin/jar".formatted(System.getProperty("java.home")); + var jarFile = "%s.jar".formatted(appName); + var fullJavaClass = "%s/%s.java".formatted(scriptDir, appName); + var classFile = new File(scriptDir, "%s.class".formatted(appName)); + classFile.deleteOnExit(); + + var compiler = ToolProvider.getSystemJavaCompiler(); + if (compiler == null) { + throw new IllegalStateException("No Java Compiler is available"); + } + var error = new ByteArrayOutputStream(); + var result = compiler.run(null, null, new PrintStream(error), fullJavaClass); + if (result != 0) { + throw new IllegalStateException(error.toString()); + } + + // Build a JAR file: + String[] arguments = {jarExe, "cfe", jarFile, appName, classFile.getName()}; + var process = new ProcessBuilder(arguments) + .directory(classFile.getParentFile()) + .start(); + var err = new String(process.getErrorStream().readAllBytes(), StandardCharsets.UTF_8); + var exitCode = process.waitFor(); + if (exitCode != 0) { + throw new IllegalStateException(err); + } + } + + private String getScriptDir() { + var exePath = getPathOfRunningApplication(); + return exePath.substring(0, exePath.lastIndexOf(appName) - 1); + } + + private boolean isJar() { + return getPathOfRunningApplication().toLowerCase(Locale.ENGLISH).endsWith(".jar"); + } + + /** Get a full path to this source Java file. */ + private String getSrcPath() { + return "%s/%s.java".formatted(getScriptDir(), appName); + } + + private String getPathOfRunningApplication() { + final var protocol = "file:/"; + try { + final var location = mainClass.getProtectionDomain().getCodeSource().getLocation(); + var result = location.toString(); + if (isSystemWindows() && result.startsWith(protocol)) { + result = result.substring(protocol.length()); + } else { + result = location.getPath(); + } + return URLDecoder.decode(result, StandardCharsets.UTF_8); + } catch (Exception e) { + return "%s.%s".formatted(appName, "java"); + } + } + + private boolean isSystemWindows() { + return System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("win"); + } +} \ No newline at end of file diff --git a/mavenForQuarkus/src/main/java/org/acme/getting/started/commandmode/Start.java b/mavenForQuarkus/src/main/java/org/acme/getting/started/commandmode/Start.java new file mode 100644 index 0000000..4ba0fad --- /dev/null +++ b/mavenForQuarkus/src/main/java/org/acme/getting/started/commandmode/Start.java @@ -0,0 +1,19 @@ +package org.acme.getting.started.commandmode; + +import io.quarkus.runtime.QuarkusApplication; +import io.quarkus.runtime.annotations.QuarkusMain; + +@QuarkusMain +public class Start implements QuarkusApplication { + + @Override + public int run(String... args) { + try { + DirectoryBookmarks.main(args); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + return 0; + } + +} diff --git a/mavenForQuarkus/src/main/resources/application.properties b/mavenForQuarkus/src/main/resources/application.properties new file mode 100644 index 0000000..a8cd989 --- /dev/null +++ b/mavenForQuarkus/src/main/resources/application.properties @@ -0,0 +1,5 @@ +# Quarkus Configuration file +# key = value + +quarkus.log.level=WARN +quarkus.banner.enabled=false \ No newline at end of file From 2f6b0281c952bbbcc85be117b908739693a18069 Mon Sep 17 00:00:00 2001 From: pponec Date: Fri, 29 Sep 2023 12:31:24 +0200 Subject: [PATCH 3/3] Java modules --- mavenForQuarkus/src/main/java/module-info.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 mavenForQuarkus/src/main/java/module-info.java diff --git a/mavenForQuarkus/src/main/java/module-info.java b/mavenForQuarkus/src/main/java/module-info.java new file mode 100644 index 0000000..d2afb6f --- /dev/null +++ b/mavenForQuarkus/src/main/java/module-info.java @@ -0,0 +1,5 @@ +module getting.started.command.mode { + requires java.compiler; + requires java.net.http; + requires quarkus.core; +} \ No newline at end of file