Windows gives some challenges in getting Genie to work correctly. Here some are described, including workarounds.
The install.clj script will try to create the uberjar if it does not exist yet, or if –create-uberjar is given. For this it will try to invoke ‘lein uberjar’ in the genied dir. On Linux this works with the Leiningen bash script, but on Windows it does not. There are quite a few ways Leiningen could be started:
- using a bash shell
- from the default cmd.exe
- from a PowerShell
- something with WSL (1 or 2)
- install with chocolatey, scoop.
The workaround for this is to create the uberjar from the prompt yourself, with ‘lein uberjar’ in the genied directory.
If the daemon has been installed and is running, the uberjar-file will be in use. This means a re-install will fail, e.g. for a new version. The workaround here is stopping the daemon, installing the new version and restarting it.
The genie.clj client has a –start-daemon option for starting the daemon process. Thie will first look for an uberjar. Failing that it will try to do a ‘lein run’. On Linux this works with the Leiningen bash script, but on Windows it does not. The same applies as in the section above (creating uberjar)
Currently this is not implemented, which leaves the following workarounds:
- starting the daemon with ‘lein run’ manually from a shell.
- creating or getting an uberjar, and using this to start from the client.
There are quite a few shells available on Windows, each having their own challenges.
Cygwin paths like /cygdrive/c/Windows can conflict with default windows paths like c:\Windows. Using a shebang line (#! /usr/bin/env genie.clj) in the script will most likely not work, so use the genie-alias when calling your scripts.
The following should work:
export GENIE_CLIENT_DIR=C:/Users/username/bin
export GENIE_DAEMON_DIR=C:/Users/username/tools/genie
export GENIE_JAVA_CMD=java
export GENIE_CONFIG_DIR=C:/Users/username/.config/genie
export GENIE_LOG_DIR=C:/Users/username/log
export GENIE_TEMPLATE_DIR=C:/Users/username/.config/genie/template
export GENIE_SCRIPTS_DIR=C:/Users/username/bin
alias bb='c:/path/to/babashka/bb.exe'
alias genie='bb $GENIE_CLIENT_DIR/genie.clj'
You may want a batch-file to run automatically when you start cmd.exe, e.g. with:
cmd.exe /k c:\apps\cmd\env-and-aliases.cmd
Or changing the Windows registry, with a .reg file like:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Command Processor]
"AutoRun"="%USERPROFILE%\\env-and-aliases.cmd"
With contents similar to:
set GENIE_CLIENT_DIR=C:\Users\username\bin
set GENIE_DAEMON_DIR=C:\Users\username\tools\genie
set GENIE_JAVA_CMD=C:\Program Files (x86)\Common Files\Oracle\Java\javapath\java.exe
set GENIE_CONFIG_DIR=C:\Users\username\.config\genie
set GENIE_LOG_DIR=C:\Users\username\log
set GENIE_TEMPLATE_DIR=C:\Users\username\.config\genie\template
set GENIE_SCRIPTS_DIR=C:\Users\username\bin
doskey bb=c:\path\to\\babashka\bb.exe $*
doskey genie=c:\path\to\\babashka\bb.exe %GENIE_CLIENT_DIR%\genie.clj $*
See the following link for more information:
Define aliases in PowerShell as follows:
Set-Alias -Name bb -Value c:\path\to\babashka\bb.exe
Function FGenie {
bb C:\Users\username\bin\genie.clj $args
}
Set-Alias -Name genie -Value FGenie
You might also want to set environment variables and use them in the alias and function above. Some Microsoft documentation might be useful:
- Showing of line-endings in console might be tricky: with new-lines being interpreted as such, without carriage returns. Mostly for Babashka, with the Genie scripts it seems ok.
rem in 4start.bat:
set GENIE_CLIENT_DIR=C:\Users\username\bin
set GENIE_DAEMON_DIR=C:\Users\username\tools\genie
set GENIE_JAVA_CMD=C:\Program Files (x86)\Common Files\Oracle\Java\javapath\java.exe
set GENIE_CONFIG_DIR=C:\Users\username\.config\genie
set GENIE_LOG_DIR=C:\Users\username\log
set GENIE_TEMPLATE_DIR=C:\Users\username\.config\genie\template
set GENIE_SCRIPTS_DIR=C:\Users\username\bin
:in 4NT alias file:
genie bb %GENIE_CLIENT_DIR%\genie.clj
With the install.clj option –start-on-system-boot, a Windows batch-file (genied.bat) will be created in the user’s startup folder, e.g. C:\Users\username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup. This has a side-effect of keeping a command window open, which you might want to hide. Some options:
- Use NirCmd (https://www.nirsoft.net/utils/nircmd.html) with options ‘exec hide’.
- check https://www.raymond.cc/blog/hidden-start-runs-batch-files-silently-without-flickering-console/
- check https://stackoverflow.com/questions/3677773/how-can-i-run-a-windows-batch-file-but-hide-the-command-window
Symbolic links can be tricky on Windows. Staying within bash/cygwin it works, but e.g. Babashka does not read cygwin symlinks, which is to be expected. Junctions at directory level will work, see junction.exe from SysInternals.
This means a symbolic link for java will not work here, Babashka needs to be able to find the actual java.exe. It will do so checking GENIE_JAVA_CMD, JAVA_CMD and then looking in the PATH spec. So set your environment vars accordingly.
Even when using an uberjar, there still might be issues starting the daemon from the client on Windows. When the -v (verbose) options is used to investigate, this might slow down the daemon startup process:
- the daemon process is started from the client.
- the client waits till the daemon TCP port is available.
- meanwhile the daemon starts, but pauses at some point.
- the client finished waiting, and gives up.
- after this, the daemon continues to start and is available.
Even without periodically checking the TCP port, the daemon prcocess still waits. With a small dummy loop that uses debug logging, we see it pauses after the second iteration of the loop. So some strange behaviour.
This could have something to do with an old, slow and/or encrypted disk, combined with a virusscanner. Without admin-access, it’s hard to check further. Again some workarounds:
- start the daemon from the client without the -v option. Although this leaves you in the dark a bit.
- start the daemon manually, with or without the -v option
If lein deps gives you something like:
Could not transfer artifact org.apache.httpcomponents:httpcore:jar:4.4.14 from/to central (https://repo1.maven.org/maven2/): PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Could not transfer artifact org.apache.httpcomponents:httpcore:jar:4.4.14 from/to clojars (https://repo.clojars.org/): PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Failed to read artifact descriptor for org.apache.httpcomponents:httpcore:jar:4.4.14
This could be due to a typo in :dependencies, file system permissions, or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.
You need to import the certificates of both Maven and Clojars into your cacerts file. Basically:
- Visit the URL in your browser and using the lock-icon download the certificate (PEM or CRT)
- Use the Java keytool to import the certificate
- See here for details.
- Configuring certificates in your Leiningen profiles.clj might also help. See technomancy/leiningen#1966