OpenJDK
Java Commands
1. Create Source Code Structure
$ mkdir -p src/{main,test}/{java,resources}
2. Preview features
$ javac --enable-preview -release 24 Foo.java
$ java --enable-preview Foo
$ java --list-modules
$ java --describe-module java.se
$ java --show-module-resolution java.base
# Replace upgradeable modules in the runtime image
$ java --upgrade-module-path $DIR
4. Disassembles a class
$ javap -p -v <classfile>
# Show the class version
$ javap -p -v build.classes.kotlin.main.App | grep version
5. App CDS
# Before JDK 18
if [ ! -f app.jsa ]; then
java -XX:ArchiveClassesAtExit=app.jsa -jar app.jar
else
java -XX:ShareArchiveFile=app.jsa -jar app.jar
fi
# Since JDK 19, auto generate the CDS archive
$ java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=app.jsa -jar app.jar
# Create default CDS archive
$ jlink-runtime/java -Xshare:dump [-XX:-UseCompressedOops]
# Check if it worked, this will fail if it can't map the archive (lib/server/classes.jsa)
$ jlink-runtime/java -Xshare:on --version
https://ionutbalosin.com/2022/04/application-dynamic-class-data-sharing-in-hotspot-jvm
https://dev.java/learn/class-data-sharing-and-application-class-data-sharing-in-hotspot
https://mbien.dev/blog/entry/custom-java-runtimes-with-jlink
6. Show Java VMProperty Settings
$ java --version
$ java -Xinternalversion
# Show Java Version (Useful for shell scripts)
$ java -XshowSettings:properties -version 2>&1 | grep "java.specification.version =" | awk '{print $3}'
$ jshell --feedback=silent - <<< 'System.out.println(System.getProperty("java.specification.version"))'
# Show all settings
$ java -XshowSettings:all --version
# Show all Javac linter options
$ javac --help-lint
# Show all system properties
$ java -XshowSettings:properties --version
# VM extra options
$ java -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal --version
# Java JIT compiler options
$ java -Xcomp forces compilation of methods on first invocation (slow startup)
$ java -Xint interpreted mode execution only (fast startup)
$ java -Xmixed mixed mode execution (default)
7. Scan deprecated APIs
# Print dependency summary
$ jdeps -summary app.jar
# Check the dependencies on JDK internal APIs
$ jdeps --jdk-internals --classpath libs.jar app.jar
# List of module dependences to be used in JLink
$ jdeps --ignore-missing-deps --print-module-deps app.jar
# List all service providers
$ jlink --suggest-providers java.security.Provider
# List all jlink plugins
$ jlink --list-plugins
# Generate module-info
$ jdeps --generate-module-info ./ app.jar
# List all deprecated APIs for a release
$ jdeprscan --for-removal --release 24 --list
# Scan deprecated APIs
$ jdeprscan --for-removal --release 24 app.jar
8. JPMS
# Start ModuleMainClass
$ java -m jdk.httpserver -b 127.0.0.1
# Compile all modules at once (Start from the main module)
$ javac --enable-preview \
--release 24 \
-parameters \ // Optional, Generate metadata for reflection on method parameters
--add-modules ALL-MODULE-PATH \ // Optional, Root modules to resolve in addition to the initial modules
--module-path ... \ // Optional, where to find application modules
--module-source-path "src" \ // Source files for multiple modules
-d classes \
--module MainApp // Compile only the specified module(s)
# Package all modules (Create for all modules)
$ jar --create \
--file mods/app.jar \
--main-class dev.suresh.MainKt \
--module-version 1.0 \ // Optional
-C app/ classes resources // Or *.class
# Launch app
$ java --enable-preview \
--show-version \
--show-module-resolution \
--module-path mods \
--module app // OR <module>/<mainclass>
# Build native image from modular jars
$ native-image \
-p base-module.jar:main-module.jar \
-m dev.suresh.Main
# JavaFX 24 using jlink & jpackage
$ wget "https://download.java.net/java/early_access/.../openjfx-xxx_macos-aarch64_bin-jmods.tar.gz"
$ tar -xvzf openjfx-xxx_macos-aarch64_bin-jmods.tar.gz
$ jlink --output javafx-jdk \
--module-path $JAVA_HOME/jmods:javafx-jmods-24 \
--add-modules javafx.controls,java.desktop,java.logging
# --add-modules ALL-MODULE-PATH
$ javafx-jdk/bin/java --list-modules
$ jpackage --main-jar app.jar \
--runtime-image javafx-jdk \
--type app-image \
--name app \
--java-options "-Xmx64m" \
--arguments "arg" \
--icon app.ico \
--input app \
--dest bin
9. JShell
# JShell with preview feature enabled
$ jshell --enable-preview
$ jshell --show-version --enable-preview --enable-native-access --startup JAVASE --feedback concise
# Use custom startup script
$ jshell --enable-preview --startup DEFAULT --startup ~/calc.repl
# Query system properties/run java code
$ fileEncoding="$(echo 'System.out.println(System.getProperty("file.encoding"))' | jshell -s -)"
10. Java TEMP Config
$ echo "-------- TMP PATH for $OSTYPE --------"
$ MKTEMP_PATH="$(dirname "$(mktemp -u)")/"
$ JAVA_TMP_DIR="$(java -XshowSettings:properties -version 2>&1 | awk 'tolower($0) ~ /java.io.tmpdir/{print $NF}')/"
$ JAVA_FILE_ENC="$(echo 'System.out.println(System.getProperty("file.encoding"))' | jshell -s -)"
$ echo "MKTEMP_PATH = $MKTEMP_PATH"
$ echo "TMP = $TMP"
$ echo "TEMP = $TEMP"
$ echo "TMPDIR (Mac) = $TMPDIR"
$ echo "RUNNER_TEMP = $RUNNER_TEMP"
$ echo "JAVA_IO_TMPDIR = $JAVA_TMP_DIR"
$ echo "JAVA_FILE_ENC = $JAVA_FILE_ENC"
$ echo "/TMP = $(ls -l /tmp)"
Networking & Security
🚨Security Developer’s Guide
# This is Unsafe. Don't use in prod.
-Djdk.tls.allowUnsafeServerCertChange=true
-Dsun.security.ssl.allowUnsafeRenegotiation=true
2. Debugging TLS
https://docs.oracle.com/en/java/javase/23/security/java-secure-socket-extension-jsse-reference-guide.html#GUID-4D421910-C36D-40A2-8BA2-7D42CCBED3C6
https://docs.oracle.com/en/java/javase/23/security/java-secure-socket-extension-jsse-reference-guide.html
https://github.com/sureshg/InstallCerts/blob/master/src/main/kotlin/io/github/sureshg/extn/Certs.kt
# Turn on all debugging
$ java -Djavax.net.debug=all
# Override HostsFileNameService
$ java -Djdk.net.hosts.file=/etc/host/style/file
# Force IPv4
$ java -Djava.net.preferIPv4Stack=true
# The entropy gathering device can also be specified with the system property
$ java -Djava.security.egd=file:/dev/./urandom
3. Java Networking Properties
http://htmlpreview.github.io/?https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/net/doc-files/net-properties.html
https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/net/doc-files/net-properties.html
All Java Networking System Properties
https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
Config | Description |
---|
http.proxyHost | The host name of the proxy server |
http.proxyPort | The port number, the default value being 80 |
http.nonProxyHosts | |
HTTP
# Use JAVA_TOOL_OPTIONS
$ export JAVA_TOOL_OPTIONS="
${JAVA_TOOL_OPTIONS}
-Dhttp.useProxy=true
-Dhttps.useProxy=true
-Dhttp.proxyHost=172.10.10.1
-Dhttp.proxyPort=8100
-Dhttps.proxyHost=172.10.10.1
-Dhttps.proxyPort=8100
-Dhttp.nonProxyHosts='localhost|127.0.0.1|cdn.test.org|*-prod.app.com|slack.com'"
# OR use system properties
$ java -Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080 -Dhttp.nonProxyHosts=”localhost|host.example.com” <URL>
Env vars
export HTTP_PROXY=http://USERNAME:PASSWORD@10.0.1.1:8080/
export HTTPS_PROXY=https://USERNAME:PASSWORD@10.0.0.1:8080/
export NO_PROXY=master.hostname.example.com
-Djdk.internal.httpclient.disableHostnameVerification
-Djdk.httpclient.HttpClient.log=headers
-Djdk.internal.httpclient.debug=false
-Djdk.tls.client.protocols="TLSv1.2"
Gradle Kotlin DSL
$ ./gradlew --console=plain \
--continuous \
--dry-run \
--no-daemon \
-Dauthor=Suresh \
-Pmyprop=myvalue \
cle dU
Eager
val p: Jar = getByName<Jar>("jar") // Get existing task
val q: Jar = create<Jar>("jar") {} // Create new task
val r: Jar by getting(Jar::class) // Get task using property delegate
val s: Copy by creating(Copy::class) {} // Create task using property delegate
val t: TaskProvider<Jar> = named<Jar>("jar"){} // Get existing task
val u: TaskProvider<Jar> = register<Jar>("jar"){} // Create new task
val v: TaskProvider<Jar> by registering(Jar::class){} // Create task using property delegate
val jar: TaskProvider<Task> by existing // Get task using property delegate
val foo: FooTask by existing // Take Task type from val (Kotlin 1.4)
val bar: BarTask by registering {} // Take Task type from val (Kotlin 1.4)
withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
// See https://github.com/melix/mrjar-gradle for more on multi release jars
val mrVersion = "11"
if (JavaVersion.current().isJava11Compatible) {
sourceSets {
create("java$mrVersion") {
java {
srcDirs("src/main/java$mrVersion")
}
}
}
tasks {
// For each source set, Gradle will automatically create a compile task.
val mrJavaCompile = named<JavaCompile>("compileJava${mrVersion}Java") {
sourceCompatibility = mrVersion
targetCompatibility = mrVersion
options.compilerArgs = listOf("--release", mrVersion)
}
named<Jar>("jar") {
into("META-INF/versions/$mrVersion") {
from(sourceSets.named("java$mrVersion").get().output)
}
manifest.attributes(
"Multi-Release" to "true"
)
dependsOn(mrJavaCompile)
}
}
}
6. Dependencies
# Direct dependencies
$ ./gradlew -q dependencies --configuration implementation
# Transitive dependencies
$ ./gradlew -q dependencies --configuration runtimeClasspath
# Dependencies insight for a dependency group.
$ ./gradlew -q dependencyInsight --configuration runtimeClasspath --dependency kotlin
$ ./gradlew -q dependencyInsight --dependency log4j-core
# Task Dependencies
$ ./gradlew clean build --dry-run
# Dependency updates
$ ./gradlew clean dependencyUpdates -Drevision=release
# Force Gradle to execute all tasks ignoring up-to-date checks
$ ./gradlew clean build --rerun-tasks
# Don't reuse outputs from previous builds (org.gradle.caching=false)
$ ./gradlew clean build --no-build-cache
# To refresh all dependencies in the dependency cache
$ ./gradlew clean build --refresh-dependencies
$ mvn archetype:generate -DgroupId=dev.suresh -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<release>15</release>
<compilerArg>--enable-preview</compilerArg>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.outputTimestamp>2020-04-02T08:04:00Z</project.build.outputTimestamp>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
$ mvn wrapper:wrapper -Dmaven=3.8.5
$ ./mvnw versions:set -DnewVersion=1.0.1-SNAPSHOT -DprocessAllModules -DgenerateBackupPoms=false
$ ./mvnw versions:revert // Rollback
$ ./mvnw versions:commit
# Show all orginal versions, not the resolved ones.
$ ./mvnw dependency:tree
$ ./mvnw dependency:tree -Ddetail=true
$ ./mvnw dependency:tree -Dverbose -Dincludes=org.jetbrains.kotlin:kotlin-stdlib
$ ./mvnw clean verify
# Dependency and plugin updates
$ ./mvnw clean versions:display-dependency-updates versions:display-plugin-updates
# Search Artifacts by class
https://search.maven.org/search?q=fc:kotlin.text.Regex
Microservices Starters
$ curl https://start.spring.io/starter.zip \
-d dependencies=devtools,web \
-d type=gradle-project \
-d language=kotlin \
-d javaVersion=11 \
-d packaging=jar \
-d platformVersion=2.2.6.RELEASE \
-d name=helloworld \
-d groupId=dev.suresh \
-d artifactId=helloworld \
-d packageName=dev.suresh \
-d description=Hello%20World%20App \
-d baseDir=helloworld \
-o helloworld.zip
Misc
Github Registry
$ VERSION=$(date +%s)
$ docker build . --file Dockerfile --tag docker.pkg.github.com/sureshg/repo/app:${VERSION}
$ docker login docker.pkg.github.com --username sureshg --password ${{ secrets.GITHUB_TOKEN }}
$ docker push docker.pkg.github.com/sureshg/repo/app:${VERSION}
Install Command Line Tools
$ xcode-select --install
$ sdk install java 24-open
$ git clone https://github.com/openjdk/jdk.git
$ cd jdk
# $ make clean
$ bash configure
$ make images
$ build/*/images/jdk/bin/java --version
# Reset the password
# https://docs.oracle.com/en-us/iaas/Content/Compute/References/serialconsole.htm#four__opcpasswordreset
$ /usr/sbin/load_policy -i
$ sudo /bin/mount -o remount, rw /
$ sudo passwd opc
$ sudo reboot -f
# Install softwares
$ sudo yum upgrade -y
$ sudo yum install curl wget tree docker git zsh -y
$ sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
$ curl -s "https://get.sdkman.io" | bash
$ sdk i java 24.ea-open
# For Github self hosted runners on Aarch64
export LD_LIBRARY_PATH=/opt/oracle/oracle-armtoolset-8/root/usr/lib64:/usr/local/lib:/usr/lib:/usr/local/lib64:/usr/lib64
export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
export JAVA_HOME_11_X64=/home/opc/.sdkman/candidates/java/11.0.11.hs-adpt
# Install EPEL
$ sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
Awesome Svgs
Illustrations
https://undraw.co/illustrations
https://www.manypixels.co/gallery/
https://www.pixeltrue.com/free-illustrations
Icons
https://icons.getbootstrap.com/
https://material.io/resources/icons/?style=baseline (not sag)
https://fontawesome.com/v4.7.0/icons/ (not sag)
https://simpleicons.org/ (Brand Icons - good one)
https://github.com/microsoft/fluentui-system-icons
https://tablericons.com/
https://tabler-icons.io/
https://systemuicons.com/
https://github.com/c5inco/intellij-icons-compose
https://www.visiwig.com/icons/
https://standart.io/
https://thenounproject.com/
https://www.flaticon.com/
https://www.iconfinder.com/
https://ionicons.com/
https://icons8.com/
https://github.com/game-icons/icons
Awesome List
https://github.com/vkarampinis/awesome-icons
https://github.com/notlmn/awesome-icons
https://github.com/ikatyang/emoji-cheat-sheet
https://jakearchibald.github.io/svgomg/
https://css-tricks.com/tools-for-optimizing-svg/
https://imageoptim.com/mac
https://xmlgraphics.apache.org/batik/
https://github.com/svg/svgo-osx-folder-action
$ pip3 install mkdocs-macros-plugin
$ ./gradlew dokka
$ cp docs/mkdocs.yml build/dokka
$ cp -R docs/images build/dokka/my-app
$ cp CHANGELOG.md build/dokka/my-app/CHANGELOG.md
$ cp README.md build/dokka/my-app/Overview.md
$ Fix the img reference on Overview.md
$ cd build/dokka
$ mkdocs build
Last modified: 21 September 2024