Linux Java Development on Windows (WSL) - sorc-lab/wiki-developer GitHub Wiki
deploy/debug java code on a remote server using Intellij: https://stackoverflow.com/questions/42380496/deploy-debug-java-code-on-a-remote-server-using-intellij/42392922#42392922
Using IntelliJ with Windows Subsystem for Linux 2: https://www.tomaszmik.us/2020/01/26/intellij-on-wsl/
windows 10, intellij idea ultimate and wsl: https://github.com/netdisco/netdisco/wiki/windows-10,-intellij-idea-ultimate-and-wsl
How to make Intellij Idea Windows font to look like Mac OS X: https://www.youtube.com/watch?v=X6txCbt2nFA
YT Setup guide (non-IntelliJ): https://www.youtube.com/watch?v=-atblwgc63E
Wiki vs gh-pages: https://stackoverflow.com/questions/31969868/how-to-store-github-wiki-as-part-of-source
Check WSL version and install WSL2
wsl -l -v
(in PowerShell). If it returns errors, then WSL1 is installed. Uninstall (???) and install WSL2
https://scotch.io/bar-talk/trying-the-new-wsl-2-its-fast-windows-subsystem-for-linux
Convert existing WSL1 Ubuntu installed to WSL2
wsl --set-version <Linux Distro name> 2
(NOTE: You see installed distros via wsl -l -v
in Windows cmd prompt)
NOTE: Inside WSL2 linux cmd prompt you can exec explorer.exe .
and it will popup a Windows file explorer window.
WSL2 uses Hyper-V to run the actual linux kernel inside windows, not just in a compatability layer/subsystem like in WSL1. WSL2 uses a virtual hard disk and does not have to do any NTFS conversion or whatever when reading and writing files. For this reason, it is more performant, especially if files that are read and written to exist in the WSL2 root filesystem.
Follow Windows instructions. 2020/04/18 required to be a member of Windows Insider program.
Test correct Windows version in command prompt:
ver
-> should return Microsoft Windows [Version 10.0.19041.207]
(Note: Need to research minimum version for WSL2)
Check existing WSL2 installed distros: wsl -l -v
Should return a list:
PS C:\WINDOWS\system32> wsl -l -v
NAME STATE VERSION
* Legacy Stopped 1
Ubuntu-18.04 Stopped 1
Note: Set version command didn't work at time of writing this.
Search "Ubuntu" in windows, Rclick -> Uninstall (if previously installed this way) Check that it was removed from WSL2
Set WSL2 to be the default architecture: wsl --set-default-version 2
Returned: Please enable the Virtual Machine Platform Windows feature and ensure virtualization is enabled in the BIOS. For information please visit https://aka.ms/wsl2-install
Run in PowerShell -> Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
(requires restart)
Note: Running the set default command returned this after restart: WSL 2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel
Google WSL2 update and download the update .exe file from Windows. wsl_update_x64.exe
Note: wsl -l -v
is same as wsl --list --verbose
Search windows for "ubuntu" and install.
Full Ubuntu on WSL install instructions: https://wiki.ubuntu.com/WSL
Use wiki link for Ubuntu 18.04 LTS from Microsoft store.
Launch ubuntu to test it.
Set Ubuntu 18 as WSL2 default distro/VM: wslconfig /setdefault Ubuntu-18.04
Best way to install WSL2 VS code and run it:
cd ~
code .
Above instructions will cause ubuntu to automatically install vs code and launch it.
Once vs code boots up, press Ctrl + ~
to get better command prompt than default Ubuntu one that comes with windows.
TODO: Follow these links to sort out a temporary work around to handle IntelliJ lack of WSL2 support
https://stackoverflow.com/questions/52852105/should-i-tell-intellij-that-my-wsl-filesystem-is-case-sensitive
Also, https://www.reddit.com/r/bashonubuntuonwindows/comments/76sn72/should_i_work_with_intellij_on_wsl/
NOTE: Install Visual Studio Code Remote - WSL extension or any other recommended extensions in VSCode pop ups
$ sudo apt update
$ sudo apt upgrade
$ sudo apt dist-upgrade
$ sudo apt autoremove
Configure the release upgrader. Open and edit the /etc/update-manager/release-upgrades file and ensure that the Prompt variable is set to normal.
# Default behavior for the release upgrader.
[DEFAULT]
# Default prompting behavior, valid options:
#
# never - Never check for a new release.
# normal - Check to see if a new release is available. If more than one new
# release is found, the release upgrader will attempt to upgrade to
# the release that immediately succeeds the currently-running
# release.
# lts - Check to see if a new LTS release is available. The upgrader
# will attempt to upgrade to the first LTS release available after
# the currently-running one. Note that this option should not be
# used if the currently-running release is not itself an LTS
# release, since in that case the upgrader won't be able to
# determine if a newer release is available.
Prompt=normal
$ sudo do-release-upgrade
NOTE: This runs into an issue with not being able to connect to snap store. This is a known WSL issue. Follow below
instructions to get around this.
1. Abort the do-release-upgrade script
2. Re-launch Ubuntu
3. Remove lxd with: sudo dpkg --force depends -P lxd; sudo dpkg --force depends -P lxd-client
4. Finish with sudo apt upgrade
NOTE: Upgrade hung at 98% "Installing new version of config file /etc/lvm/lvm.conf ..."
Search Ubuntu in windows search start menu. Select Ubuntu LTS -> App Settings -> Repair.
Re-ran the upgrade and it didn't error out. cat /etc/os-release shows 19.10 and everything seems fine.
$ sudo apt-get update -y && sudo apt-get upgrade -y
$ sudo apt install openjdk-13-jdk
$ java -version
openjdk version "13" 2019-09-17
OpenJDK Runtime Environment (build 13+13-Ubuntu-0ubunt1)
OpenJDK 64-Bit Server VM (build 13+13-Ubuntu-0ubunt1, mixed mode, sharing)
$ sudo update-alternatives --config java
There are 2 choices for alternative java (providing /usr/bin/java).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-13-openjdk-amd64/bin/java 1211 auto mode
1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode
2 /usr/lib/jvm/java-13-openjdk-amd64/bin/java 1211 manual mode
$ export JAVA_HOME=/usr/lib/jvm/java-13-openjdk-amd64/bin/java
$ echo $JAVA_HOME
/usr/lib/jvm/java-13-openjdk-amd64/bin/java
$ vim ~/.bashrc
Add this line: export JAVA_HOME=/usr/lib/jvm/java-13-openjdk-amd64/jre/bin/java
then, run: $ source ~/.bashrc
$ echo $JAVA_HOME
/usr/lib/jvm/java-13-openjdk-amd64/jre/bin/java
$ sudo apt install maven
$ mvn -version
NOTE: JAVA_HOME should point to a JDK not a JRE
Fix $JAVA_HOME from recent configuration:
$JAVA_HOME/bin/javac -version
should return "javac 1.X.0_XX" not: "No such file or directory"
Set ~/.bashrc $JAVE_HOME path to export JAVA_HOME=/usr/lib/jvm/java-13-openjdk-amd64
Should allow maven to run via mvn -version
NOTE: Maven seems to be using its previously installed version on /mnt/c/Program Files
which will cause it to run
slowly, and ideally we don't want anything running on Windows unless we have to. Need to fix its path somehow.
Uninstall Windows version of Maven. Find where maven version on WSL is installed, if it exists, or follow these instructions to install manually in opt: https://www.vultr.com/docs/how-to-install-apache-maven-on-ubuntu-16-04?gclid=CjwKCAjwkPX0BRBKEiwA7THxiPkVW-rwrNXvYTZdOx73-GMbrlJ8ZMpGvZPEDHv9Cfs0PYjsAOW69xoCwBcQAvD_BwE
NOTE: Logged back in a day later and maven fixed itself. It's pointing at its own WSL2 version now:
sorc@SORC-WORK01:/mnt/d$ mvn -version
Apache Maven 3.6.1
Maven home: /usr/share/maven
Java version: 13, vendor: Private Build, runtime: /usr/lib/jvm/java-13-openjdk-amd64
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "4.19.84-microsoft-standard", arch: "amd64", family: "unix"
Create case-sensitive directory on Windows mounted drive, not WSL2 root file system. (bad but no other option since IntelliJ lacks WSL2 support like VS Code has.)
NOTE: Test if /mnt/<drive>
is case-sensitive already. mkdir tmp
, then try to mkdir TMP
and if it says directory
already exists, then it's not case-sensitive
below taken from https://devblogs.microsoft.com/commandline/per-directory-case-sensitivity-and-wsl/ --------------------------------------------------------------------------------------------------------------------- The Windows Subsystem for Linux uses another mechanism, which itself bypasses that registry key, allowing us to perform case sensitive file system operations. This is what allows Linux applications running in WSL to use file names that differ only by case, just like they can on real Linux, even with that global registry key set.
Unfortunately, this leaves you with files that can’t be accessed by Windows applications. While you could change the global registry key, that still would only work for those applications that use FILE_FLAG_POSIX_SEMANTICS, and this would change the behavior for all files on all drives, which may not be intended and may break some applications. ---------------------------------------------------------------------------------------------------------------------
Check if directory is case-sensitive:
fsutil.exe file queryCaseSensitiveInfo /mnt/d/VM
Case sensitive attribute on directory D:\VM is disabled.
fsutil.exe file setCaseSensitiveInfo sorc-lab enable
Link explains how to set WSL config to set default values when creating dirs: https://devblogs.microsoft.com/commandline/per-directory-case-sensitivity-and-wsl/
For this example, I just want one case-sensitive directory that I will put all projects in so for me this is just a one time thing and won't need a global config setting for future directories, because all directories created in the sorc-lab directory will automatically be case-sensitive anyways.
NOTE: I will also not be accessing this directory from Windows, but I will be opening these files in IntelliJ.
Run the following commands for all mounted drives on Windows:
sudo umount /mnt/c
sudo mount -t drvfs C: /mnt/c -o metadata
Test that it worked via: mount -l
C: on /mnt/c type 9p (rw,relatime,dirsync,aname=drvfs;path=C:;metadata;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=3,wfd=3)
Should be able to see the metadata
keyword in the output above.
Note: The above mount commands will not work within VS Code terminal, must run within the WSL terminal only.
Edit wsl.conf file (probably doesn't exist, so create it with sudo vim /etc/wsl.conf
):
[automount]
enabled = true
options = "metadata,umask=22,fmask=11"
Above config will set files to now show up with a comfortable permission setting of 0644 and directories with 0755 if they’re mounted under /mnt.
Read more about wsl.conf from Microsoft to get more info.
Edit ~/.profile so that files and directories are created with default permissions:
if [[ "$(umask)" = "0000" ]]; then
umask 0022
fi
Without the above profile settings, files will be created with 0666 and directories with 0777 by default.
https://www.turek.dev/post/fix-wsl-file-permissions/ https://devblogs.microsoft.com/commandline/chmod-chown-wsl-improvements/
To set default line ending for all new files: go to Settings/Preferences | Editor | Code Style and change Line separator (for new files) option to the desired style (e.g. Unix and OS X (\n)).
To change for individual file: File->Line separators, or select in bottom right IDE system tray.
Convert existing dpk-sim project (CRLF) to LF:
sudo apt install dos2unix
find . -type f -exec dos2unix {} \;
Make sure IntelliJ Git root is set to use path to Git in WSL2 and not the Git binary installed on windows Host sytem. Settings->Version Control->Path to Git executable:
NOTE: Not going to cover setting up Windows Git to handle CRLF to LF conversion on commit, because we shouldn't need that ever. With WSL2, all Linux apps will be developed in LF IntelliJ IDE, and Windows apps, ie UE4 C++ projects will want to remain CRLF inside Visual Studio etc, and text editor VS Code can be used in Windows or WSL2 and toggle to whatever it needs for each file specifically.
OPTIONAL: Install IntelliJ plugin Native Terminal. Supports WSL terminal from IDE. I just use VS Code terminal.
TODO: IntelliJ is using Windows Git binary and is showing incorrect files showing as edited when WSL2 Git does not report this. This needs to be solved, but a hack is necessary since IntelliJ doesn't support WSL2 yet.
Potential solutions: https://stackoverflow.com/questions/43666009/using-git-in-windows-subsystem-for-linux-through-intellij
NOTE: The above issue is actually being caused by changing the file permissions in WSL2 and Windows Git bash is detecting that change. I'll solve this on Windows side to get the diff to go away and resolve these issues later. This won't happen (hopefully) on new WSL2 projects under IntelliJ. This needs to be resolved but I'll punt on this as I do not want to introduce more hacks, but IntelliJ should be setup to support WSL2.
NOTE: Explain that IntelliJ will still need to point at a Windows Java 11 install binary, but all builds will be done via WSL2 terminal that runs OpenJDK13 and will be compatible, or shouldn't matter since we will not build within Windows IntelliJ anyways.
TODO: Once this is all done and cleaned up. Figure out how to attach a remote debugger from Windows IntelliJ to WSL2 docker container, if that's possible.
(Make sure this is an improvement of the current font settings): https://www.youtube.com/watch?v=X6txCbt2nFA
Maven Project
Spring boot 2.2.6
Group: com.sorclab
Artifact: hello-world
Name: hello-world (same as Artifact usually)
Description: Optional, can be changed later in pom.xml
Package name: com.sorclab.hello-world (this auto fills)
Packaging: Jar
Java versions: Use 11 for now, since there was no Java 13 options. Also windows is running Java 11 version.
Dependencies: Lombok, Spring Web, **NOTE**: PSQL dependencies are unknown, we'll add them to pom.xml manually.
Move hello-world.zip to /mnt/c
unzip it in WSL2 instead of Windows
sudo apt install unzip
unzip hello-world.zip
This will force the use of Linux file permissions and in general a best practice when dealing with WSL2. Do as much within Linux as possible to maintain compatibility and consistency.
Open project in IntelliJ (make sure Java 11 or 13 installed in windows and project struct in IntelliJ point to proper Winsows binary).
Simple to open in IntelliJ. Browse for hello-world and open the pom.xml file within IntelliJ and Open as project
Run in WSL2 to test.
$ cd /mnt/c/sorc-lab/hello-world
$ mvn clean install -DskipTests && mvn spring-boot:run
Should build the jar and spin up the Spring boot app. If successful, will see the following line:
Started HelloWorldApplication in 3.946 seconds (JVM running for 4.618)
Edit pom.xml file and update the java version:
<properties>
<java.version>13</java.version>
</properties>
https://hub.docker.com/_/postgres
NOTE: At the time of writing this, official Docker docs for installing on Windows 10 gave instructions to download and install Docker for windows and all the installation settings that were needed to integrate with WSL2 were pre-selected by default. You should not have to do anything special other than install the latest Docker for windows executable and install it. Test it in WSL2 via docker run hello-world
.
docker ps
docker images
docker rmi <image_id>
docker rm $(docker ps --all -q)
// NOTE: Need container cleanup script
Download PostgreSQL image: docker pull postgres
- Hello world via Liquibase + manual docker run psql container cmd
- Setup dc file
- Create init script
- Centralize init scripts and point all future dc files to one db port
- More docker scripts and ideally a cleanup script
- Show how to query data in both psql and PGAdmin