Enhancing Productivity and Insight A Tour of JDK Tools Progress Beyond Java 17

AnaMariaMihalceanu1 23 views 43 slides Jun 13, 2024
Slide 1
Slide 1 of 62
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56
Slide 57
57
Slide 58
58
Slide 59
59
Slide 60
60
Slide 61
61
Slide 62
62

About This Presentation

JDK Tools enhancements talk at DevBCN


Slide Content

Enhancing Productivity
and Insight
A Tour of JDK Tools
Progress
Beyond Java 17

Java Champion Alumni
Java Developer Advocate at Oracle
Twitter: @ammbra1508
Mastodon: @ammbra1508.mastondon.social

Ana-Maria Mihalceanu
Hello! I am Ana
2 Java Day Copyright © 2024, Oracle and/or its affiliates

Goal
Learn about key enhancements on the JDK tools
since Java 17 so that you can efficiently code,
deploy and monitor your applications.

Java Day Copyright © 2024, Oracle and/or its affiliates3

Source and Classfile Tools
Java Day Copyright © 2024, Oracle and/or its affiliates4

Compiling and Launching a Java Program
Java Day Copyright © 2024, Oracle and/or its affiliates5
IDE
.java source
file
bytecode .class
file
Program running
javac java

Everlasting standard compiler optimizations
☕ Do not require any flag.
☕ Literal constants are folded.
☕ String concatenation is folded.
☕ Constant fields are inlined.
☕ Dead code branches are eliminated.





Java Day Copyright © 2024, Oracle and/or its affiliates6

public class Example {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("foo");
System.err.println("" + builder + builder.append("bar"));
}
}

// before JDK 19 prints foobarfoobar
// strategy after JDK 19:prints foofoobar






String concatenation order of operations
7 Java Day Copyright © 2024, Oracle and/or its affiliates
[Indy String Concat Changes Order of Operations⑲ — JDK-8273914]

public class Example {
public static void main(String[] args) {
long value = 5L;
long b = value + 0.1 * 3L;
}
}

// incompatible types: possible lossy conversion from double to long

public class Example {
public static void main(String[] args) {
long b = 5L;
b += 0.1 * 3L;
}
}

// before JDK 20: no error



Noticing possible lossy conversions
8 Java Day Copyright © 2024, Oracle and/or its affiliates

public class Example {
public static void main(String[] args) {
long b = 5L;
b += 0.1 * 3L;
}
}

# After JDK 20
$ javac Example.java -Xlint:all

> Example.java:4: warning: [lossy-conversions] implicit cast from double to long in compound assignment is possibly lossy
> b += 0.1 * 3L;
^
> 1 warning

Warnings on lossy conversions
9 Java Day Copyright © 2024, Oracle and/or its affiliates
[Warn compound assignment is possibly lossy  — JDK-8244681]

public class Example {
public Example() {
System.out.println(this.hashCode());
}

public static void main(String[] args) {
new Example();
}
}

// Until JDK 21, javac says all good
Calling overridable methods in constructors
10 Java Day Copyright © 2024, Oracle and/or its affiliates

☕ Since JDK 21 the compiler has a new -Xlint:this-escape option.

public class Example {
public Example() {
System.out.println(this.hashCode());
}

public static void main(String[] args) {
new Example();
}
}

$ javac Example.java -Xlint:[all|this-escape]

> Example.java 3: warning: [this-escape] possible 'this' escape before subclass is fully initialized
> System.out.println(this.hashCode()); ^
> 1 warning

Warnings about possible this escapes
11 Java Day Copyright © 2024, Oracle and/or its affiliates

☕ JEP 458 ㉒ Run a Java program supplied as multiple files

// HelloWorld.java
class HelloWorld {
public static void main(String[] args) {
Helper.run();
}
}
// Helper.java
class Helper {
static void run() {
System.out.println("Hello, World!");
}
}

$ java HelloWorld.java
> Hello, World!




Towards Enhanced Usability
12 Java Day Copyright © 2024, Oracle and/or its affiliates

Generate Great API
Documentation
Java Day Copyright © 2024, Oracle and/or its affiliates13

Goals for API documentation
☕ Helps with product maintenance.
☕ Technical users can understand your APIs goals.
☕ Can increase awareness/adoption of your software.
☕ Third-party developers can start quickly by trying out API examples.





Java Day Copyright © 2024, Oracle and/or its affiliates14

Words may come easy,
yet examples require extra
care.
Java Day Copyright © 2024, Oracle and/or its affiliates15

Inserting fragments of source code in documentation
☕ Wrap code examples inside <pre> and {@code ...}.
☕ Automatically escape special characters with {@code ...}.
☕ No control over indentation.
☕ No code highlighting.





Java Day Copyright © 2024, Oracle and/or its affiliates16

/**
* <p>Java class for user complex type.<p/>
* <p>The following schema fragment specifies the expected content for the User class.<p/>
* <pre> {@code
* <complexType name="user">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
* <element name="email" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="firstName” type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="lastName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="userName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* }
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "user", propOrder = {"id", "email", "firstName", "lastName","userName”})
public class User {
Example documentation for a SOAP API resource
17 Java Day Copyright © 2024, Oracle and/or its affiliates

/**
* <p>Java class for user complex type.<p/>
* <p>The following schema fragment specifies the expected content for the User class.<p/>
* <pre> {@code
* <complexType name="user">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
* <element name="email" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="firstName” type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="lastName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="userName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* }
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "user", propOrder = {"id", "email", "firstName", "lastName","userName”})
public class User {
Example documentation for a SOAP API resource
18 Java Day Copyright © 2024, Oracle and/or its affiliates

javadoc User.java
Generated HTML page
19 Java Day Copyright © 2024, Oracle and/or its affiliates

Elegant inclusion of code examples
☕ JEP 413 introduced {@snippet ...} tag in JDK 18.
☕ A better presentation of the targeted code examples via regions.
☕ Control code via @highlight, @replace, @link tags and regions.




Java Day Copyright © 2024, Oracle and/or its affiliates20

/**
* <p>Java class for user complex type.</p>
* <p>The following schema fragment specifies the expected content for the User class.</p>
* {@snippet lang=xml :
* //@start region="type"
* <complexType name="user">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* //@highlight region="element" regex="name=.\w+."
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
* <element name="email" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="firstName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="lastName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="userName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* //@end region="element"
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* //@end region="type"
* }
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "user", propOrder = {"id", "email", "firstName", "lastName","userName”})
public class User {
Refactor example documentation for a SOAP API resource
21 Java Day Copyright © 2024, Oracle and/or its affiliates

/**
* <p>Java class for user complex type.</p>
* <p>The following schema fragment specifies the expected content for the User class.</p>
* {@snippet lang=xml :
* //@start region="type"
* <complexType name="user">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* //@highlight region="element" regex="name=.\w+."
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
* <element name="email" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="firstName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="lastName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="userName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* //@end region="element"
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* //@end region="type"
* }
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "user", propOrder = {"id", "email", "firstName", "lastName","userName”})
public class User {
Refactor example documentation for a SOAP API resource
22 Java Day Copyright © 2024, Oracle and/or its affiliates

javadoc User.java
Regenerated HTML page
23 Java Day Copyright © 2024, Oracle and/or its affiliates

Elegant inclusion of code examples
☕ JEP 413 introduced {@snippet ...} tag in JDK 18.
☕ A better presentation of the targeted code examples via regions.
☕ Control code via @highlight, @replace, @link tags and regions.
☕ The tag accepts separate files that contain the content of the snippet.




Java Day Copyright © 2024, Oracle and/or its affiliates24

$ javadoc --snippet-path ./src/xml User.java

/**
* <p>Java class for user complex type.
* </p>
* <p>The following schema fragment specifies the expected content for the User class.
* </p>
* {@snippet file="user.xml" lang=xml}
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "user", propOrder = {"id", "email", "firstName", "lastName","userName”})
public class User {

Refactor and regenerate documentation
Java Day Copyright © 2024, Oracle and/or its affiliates25

☕ Since JDK 18, configure the --add-script <file> option of javadoc.

$ cat interact.js
> alert("Okey-dokey! Get ready to move your fingers!");

$ javadoc --add-script interact.js User.java

☕ Use the option to add multiple scripts in your generated documentation.


Benefit of interactive documentation
26 Java Day Copyright © 2024, Oracle and/or its affiliates
[Add scripts to generated documentation⑱— JDK-8275786]

Markdown in documentation comments
☕ JEP 467 introduces Markdown in Java documentation comments.
☕ Enjoy a concise syntax for common constructs.
☕ Reduce the dependence on HTML markup and JavaDoc tags.
☕ Keep enabling the use of specialized tags when not available in Markdown.
☕ A new form of documentation comment: ///


Java Day Copyright © 2024, Oracle and/or its affiliates27

Java Day Copyright © 2024, Oracle and/or its affiliates28

Development and Deployment Tools
Java Day Copyright © 2024, Oracle and/or its affiliates29

Fast prototyping java code with jshell
☕ Quickly try, debug and learn Java and its APIs.
☕ Experiment with Java by bypassing the compile stage.
☕ Get immediate feedback on your code.
☕ Exposes a programmatic API.




Java Day Copyright © 2024, Oracle and/or its affiliates30

jshell> var check = new Boolean("true");
| Warning:
| Boolean(java.lang.String) in java.lang.Boolean has been deprecated and marked for removal
| var check = new Boolean("true");
| ^-----------------^
check ==> true

jshell> Short number = new Short("12345");
| Warning:
| Short(java.lang.String) in java.lang.Short has been deprecated and marked for removal
| Short number = new Short("12345");
| ^----------------^
number ==> 12345





Highlighting deprecated elements, variables and keywords
31 Java Day Copyright © 2024, Oracle and/or its affiliates
[jshell outlines deprecated elements ⑲ — JDK-8274148]

JDK tools access in jshell
☕ jshell supports loading scripts.
☕ Scripts can be local files or one of the predefined scripts.
☕ Scripts may hold any valid code snippets or jshell commands.





Java Day Copyright © 2024, Oracle and/or its affiliates32
Predefined scripts Description
DEFAULT Loads the default entries, which are commonly used as imports.
JAVASE Imports all Java SE packages.
PRINTING Defines print, println, and printf as jshell methods for use within the tool.
TOOLING㉑ Defines javac, jar, and other methods for running JDK tools via their command-line interface within
the jshell tool.

☕ Load TOOLING when you start jshell

$ jshell TOOLING

☕ Open TOLLING inside a jshell session

jshell> /open TOOLING

☕ Check available tools

jshell> tools()

☕ Execute a tool command in a jshell session

jshell> run("javac", "-version")
javac 21

Load and use TOOLING script
33 Java Day Copyright © 2024, Oracle and/or its affiliates
[JDK tools in jshell ㉑ — JDK-8306560]

What tool would you use
for local prototyping,
testing or debugging a
client-server setup?
Java Day Copyright © 2024, Oracle and/or its affiliates34

Introduction to jwebserver
☕ Provides a minimal HTTP server, serving only static files.
☕Supports only HTTP/1.1 .
☕Only HEAD and GET requests are served.
☕Other requests receive a 501 - Not Implemented or a 405 - Not Allowed response.
Java Day Copyright © 2024, Oracle and/or its affiliates35
[Introducing jwebserver ⑱ - JEP 408]

# Web development testing, to simulate locally a client-server setup.

$ jwebserver
> Binding to loopback by default. For all interfaces use "-b 0.0.0.0" > or "-b ::".
> Serving /cwd and subdirectories on 127.0.0.1 port 8000
> URL: http://127.0.0.1:8000/

# Use static files as API stubs for web-service prototyping or application testing.

$ jwebserver -p 9000
> Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
> Serving /example and subdirectories on 127.0.0.1 port 9000
> URL http://127.0.0.1:9000/
> 127.0.0.1 -- [09/Feb/2024:3:02:05 +0200] "GET /api/a1.json HTTP/1.1" 200
> 127.0.0.1 -- [09/Feb/2024:3:02:06 +0200] "GET /api/a2.json HTTP/1.1" 200






Use cases for jwebserver(1)
36 Java Day Copyright © 2024, Oracle and/or its affiliates

# Search a directory on a remote server from your local machine.

$ jwebserver -b 0.0.0.0
> Serving /work and subdirectories on 0.0.0.0 (all interfaces) port 8000
> URL http://192.168.178.41:8000/


# Can also be started via java launcher

$ java -m jdk.httpserver
> Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
> Serving /example and subdirectories on 127.0.0.1 port 8000
> URL http://127.0.0.1:8000/

# Great for learning purposes.







Use cases for jwebserver(2)
37 Java Day Copyright © 2024, Oracle and/or its affiliates

The SimpleFileServer class supports the creation of:
☕ file server
☕ file handler
☕ an output filter

$ jshell
jshell> var server = SimpleFileServer.createFileServer(new InetSocketAddress(8080),
...> Path.of("/some/path"), OutputLevel.VERBOSE);
jshell> server.start()

Working with the simple web server API
38 Java Day Copyright © 2024, Oracle and/or its affiliates

Packaging self-contained
Java applications
Java Day Copyright © 2024, Oracle and/or its affiliates39

Introduction to jpackage
☕ Packages self-contained Java applications.
☕Prior JDK 19, installing a jpackaged app was system-wide.
☕For modular applications, jpackage will automatically run jlink and generate a runtime with the
modules needed.
Java Day Copyright © 2024, Oracle and/or its affiliates40

jpackage --input target/ --name JDemoApp
--main-jar JDemoApp.jar
--main-class org.example.JDemoApp
--type app-image

Using jpackage
41 Java Day Copyright © 2024, Oracle and/or its affiliates





JDemoApp.app/
Contents/
Info.plist
MacOS/ //Application launchers
JDemoApp
Resources/ // Icons, etc.
app/
JDemoApp.cfg //Configuration info, made by jpackage
JDemoApp.jar //JAR file, copied from the --input directory
runtime/ //Java runtime image

# Application launcher will look up the .cfg file in user-specific directories.

Linux
~/.local/${PACKAGE_NAME}
~/.${PACKAGE_NAME}

macOS
~/Library/Application Support/${PACKAGE_NAME}

Windows
%LocalAppData%\%PACKAGE_NAME%
%AppData%\%PACKAGE_NAME%

# ${PACKAGE_NAME} and %PACKAGE_NAME% refer to jpackaged application name.

Installation of a packaged application after JDK 19
42 Java Day Copyright © 2024, Oracle and/or its affiliates

Installation of a jpackaged application after JDK 19
Application launcher will look up the .cfg file:
☕ In user-specific directories.
☕ From the installation directory if .cfg file is not found.
☕ From the application image directory if the application launcher is executed from that location.
Java Day Copyright © 2024, Oracle and/or its affiliates43

Security Tools
Java Day Copyright © 2024, Oracle and/or its affiliates44

# Since JDK 18, you can check the version of keytool and jarsigner.

$ keytool -help -version
> keytool -version [OPTION]...
> Prints the program version
> Options:
> Use "keytool -?, -h, or --help" for this help message


$ keytool -version & jarsigner -version
> [1] 83711 jarsigner 21 keytool 21

New –version option for keytool and jarsigner
45 Java Day Copyright © 2024, Oracle and/or its affiliates
[Add -version option to keytool and jarsigner ⑱ — JDK-8272163]

# keytool warns you when using weak password-based encryption algorithms via -genseckey and -importpass options

$ keytool -genseckey -alias secret -keypass changeit \
-keyalg RC4 -keysize 128 -keystore example.p12 \
-storepass changeit -storetype PKCS12 -v

> Generated 128-bit ARCFOUR secret key [Storing example.p12]
> Warning: The generated secret key uses the ARCFOUR algorithm which is considered a security risk.


Updated options for keytool
46 Java Day Copyright © 2024, Oracle and/or its affiliates
[keytool warns about weak PBE algorithms ㉑ — JDK-8286907]

# Specify the classpath for providers via –providerPath

$ jarsigner -keystore keystore -storetype CUSTOMKS \
-providerPath /path/to/test.myks \
-providerClass my.custom.AnotherProvider
signed.jar mykey

# The options -altsigner and -altsignerpath have been removed in JDK 21.



Updated options for jarsigner
47 Java Day Copyright © 2024, Oracle and/or its affiliates
[Add -providerPath option to jarsigner ⑲ — JDK-8281175]

Monitoring Tools
Java Day Copyright © 2024, Oracle and/or its affiliates48

Monitoring Java applications
Java Day Copyright © 2024, Oracle and/or its affiliates49
Technology Goal
JDK Flight Recorder (JFR)Collects diagnostic and profiling data about a running Java
application.
JFR Event Streaming APIAPI for the continuous consumption of JFR data on disk.
JDK Mission Control (JMC)A set of tools for managing, monitoring, profiling, and
troubleshooting Java applications.

New jfr view command
☕ Displays aggregated event data without the need to dump a recording file.
☕Start JFR a recording via -XX:StartFlightRecording or jcmd.
$ java -XX:StartFlightRecording -jar imaging.jar
☕ Use the PID or jar name in the command.
☕ Use jps JDK tool to list all running Java processes (PID).


Java Day Copyright © 2024, Oracle and/or its affiliates50
[JFR view command ㉑ — JDK-8306704 ]

$ jcmd imaging.jar JFR.view hot-methods

30598:

Java Methods that Execute the Most

Method Samples Percent
--------------------------------------------------------------------- ------- -------
org.springframework.boot.loader.jar.JarFileEntries.sort(int, int) 1 33,33%
jdk.internal.util.ArraysSupport.signedHashCode(int, byte[], int, int) 1 33,33%
java.net.URLStreamHandler.toExternalForm(URL) 1 33,33%

Timespan: 15:46:40 - 15:56:40




JFR view command example
51 Java Day Copyright © 2024, Oracle and/or its affiliates

Java Day Copyright © 2024, Oracle and/or its affiliates
JFR event for finalization - jdk.FinalizerStatistics
☕ Identifies classes at runtime that use finalizers.
☕ No event is sent if java --finalization=disabled.
☕ Enabled by default in default.jfc and profile.jfc JFR configuration files.
☕ Disable via:
$ jfr configure jdk.FinalizerStatistics#enabled=false
# or on launch
$ java -XX:StartFlightRecording:settings=none,+jdk.FinalizerStatistics#enabled=false

52
[A finalization JFR event - JDK-8266936]

Java Day Copyright © 2024, Oracle and/or its affiliates
Initial security properties -jdk.InitialSecurityProperty
☕ Records initial security properties at application startup.
☕Enabled by default in default.jfc and profile.jfc JFR configuration files.
☕Disable via:
$ jfr configure jdk.InitialSecurityProperty#enabled=false
# or on launch
$ java -XX:StartFlightRecording:settings=none,+jdk.InitialSecurityProperty#enabled=false


53

Java Day Copyright © 2024, Oracle and/or its affiliates
Record details about security provider instance requests
☕ jdk.SecurityProviderService is disabled by default.
☕Records details about java.security.Provider.getService(String key, String value) calls.
☕Enable via:
$ jfr configure jdk.SecurityProviderService#enabled=true
# or on launch
$ java -XX:StartFlightRecording:settings=none,+jdk.SecurityProviderService#enabled=true


54

Java Day Copyright © 2024, Oracle and/or its affiliates
JMC Graph Views for performance analysis
☕ JMC 9 requires JDK 17 or later!
☕Since JMC 8.3, JMC Graph View was updated to allow limiting the number of nodes displayed.
☕Focus on most impactful nodes by using smart pruning.
☕Example : focus on how often a specific method is ran based on sampling.
Open JFR Recording -> Method Profiling -> Select method -> Graph View
55

Java Day Copyright © 2024, Oracle and/or its affiliates56

Java Day Copyright © 2024, Oracle and/or its affiliates
JMC Flame View graphs for performance analysis
☕ Flame View has options that limit the data displayed on the view.
☕In Samples drop-down, select either Allocation Size, Sample Weight or TLAB Size.
☕Example use case: visualize where your program is spending its memory.
Open JFR Recording -> Memory-> Flame View
☕Starting with JMC 9, Flame Graph will now be rendered using Java Swing


57

Java Day Copyright © 2024, Oracle and/or its affiliates58

Java Day Copyright © 2024, Oracle and/or its affiliates
New JMC Dependency View
☕ Shows the relationships between packages within a stack trace.
☕View dependencies as a chord graph, a circle showing how packages call one another.
☕A chord graph has thicker lines to represent stronger connections.
☕Example use case: check dependency view for classes in Memory page.
Open JFR Recording -> Memory-> Select Class -> Dependency View
59

Java Day Copyright © 2024, Oracle and/or its affiliates60

Stay tuned for more!
Java Day Copyright © 2024, Oracle and/or its affiliates61
Inside.javaDev.java youtube.com/java

Useful links
☕ Programmer’s Guide to Snippets: https://docs.oracle.com/en/java/javase/21/javadoc/programmers-guide-snippets.html
☕ Java 21 Tool Enhancements: Better Across the Board #RoadTo21 https://www.youtube.com/embed/nFJBVuaIsRg
☕ Using Jshell API https://inside.java/2022/11/21/jshell-java-source-browser/
☕ Christian Stein’s article on jshell tooling https://sormuras.github.io/blog/2023-03-09-jshell-tooling
☕ Julia Boes article on more advanced jwebserver usage https://inside.java/2021/12/06/working-with-the-simple-web-server/
☕ JEP 408 on jwebserver https://openjdk.org/jeps/408
☕ More on jpackage: https://dev.java/learn/jvm/tool/jpackage/
☕ Package a JavaFX application as a native executable https://inside.java/2023/11/14/package-javafx-native-exec/
☕ Stack Walker ep 2 on JFR https://inside.java/2023/05/14/stackwalker-02/
☕ Monitoring Java Application Security with JDK tools and JFR Events: https://dev.java/learn/security/monitor/
☕JEP 467 on markdown documentation cmments: https://openjdk.org/jeps/467

Java Day Copyright © 2024, Oracle and/or its affiliates62