New Features in Java 18

JAVA 18
Java 18

Oracle has released Java 18 on March 22, 2022, and it comes with a lot of new features and improvements. In this article, we’ll take a look at some of the most important ones.

Java 18 (Oracle JDK 18) includes thousands of performance, stability, and security enhancements, as well as nine platform enhancements that will boost developer productivity even further.

  • Code Snippets in Java API Documentation (JEP 413)
  • Simple Web Server (JEP 408)
  • Vector API (JEP 417)
  •  Foreign Function and Memory API (JEP 419)
  • Pattern Matching for Switch (JEP 420)
  • UTF-8 as Default Charset encoding (JEP 400)
  • Reimplement Core Reflection with Method Handles (JEP 416)
  • Internet-Address Resolution SPI (JEP 418)
  • Deprecate Finalization for Removal (JEP 421)

Let’s look at the following three features with examples

You can download Java 18 from here

Simple Web Server

A command-line tool and API to start a minimal web server that serves static files only. This tool will be useful for prototyping, ad-hoc coding, and testing purposes, particularly in educational contexts.

you can start the webserver with the jwebserver command.

If the startup is successful, jwebserver prints a message to System.out that includes the local address and absolute path of the directory being served. As an example,

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

The server runs in the foreground by default and connects to the loopback address and port 8000. The -b and -p options can be used to change this.For instance, to run the server on port 3000, enter:

$ jwebserver -p 3000

To bind the server to all interfaces, you can enter

$ jwebserver -b 0.0.0.0

You might get security alert like below when you enter the above command. Click on Allow access button

Serving C:\Users and subdirectories on 0.0.0.0 (all interfaces) port 8000
URL http://100.92.64.87:8000/

By default, files are served from the current directory. A different directory can be specified with the -d option.

Only HEAD and GET requests are supported by jwebserver command. Any other requests receive a 501 - Not Implemented or a 405 - Not Allowed response. GET requests are mapped to the directory being served, as follows:

  • If the requested resource is a file, its content is served.
  • If the requested resource is a directory that contains an index file, the content of the index file is served.
  • Otherwise, the names of all files and subdirectories of the directory are listed. Symbolic links and hidden files are not listed or served.

The Simple Web Server supports HTTP/1.1 only. There is no HTTPS support.

Now let see webserver in action.

I am going to use the presenta-slideshow-demo project content for demo.

Using different port then default

Serving files from different directory

Accessing a directory

UTF-8 as Default CharSet

The conversion between raw bytes and the Java programming language’s 16-bit char values is governed by a charset. US-ASCII, UTF-8, and ISO-8859-1 are examples of supported charsets.

In JDK 17 and earlier standard Java APIs normally utilized the default charset if no charset option is given. At startup, the JDK determines the default charset based on the run-time environment, which includes the operating system, the user’s locale, and other considerations. e.g: On Windows, it is a codepage-based charset such as windows-1252 and On macOS, it is UTF-8.

So when you a write content to file ( which contains UTF-8 supported characters) in macOS and read the file in the windowsOS you will get the corrupted file. So developers are forced to  use methods and constructors that take a charset argument explicitly.

However, having to pass an argument prevents methods and constructors from being used via method references (::) in stream pipelines.

Starting from Java 18, standard Java APIs are going to use UTF-8 as the default charset.APIs that rely on the default charset will now act consistently across all implementations, operating systems, locales, and configurations as a result of this change.

We can view default charset by running following command

java -XshowSettings:properties

If you want to get programmatically, the method java.nio.charsets.Charset.defaultCharset() returns the default charset

For Java 17 on windows 11 it is CP-1252 ( aka windows-1252)

For Java-18 on Windows 11

We can demonstrate default charset issue following program.

In below program we trying to write few chinese chars to a text file.

public class FileWriterExample {
    public static void main(String[] args) throws IOException {
        String str ="漢字 败/敗 传/傳";
        FileWriter fw = new FileWriter("test.txt" ); 
        fw.write(str);
        fw.flush();

    }
}

In run above program in Windows OS, and Java 11/17 , you will see only ? chars.

If you want to see proper chars, you need to set the proper charset in FileWrite class constructor.

 FileWriter fw = new FileWriter("test.txt" ,Charset.forName("UTF-8"));

Or you need to set the

-D"file.encoding"=UTF-8 system setting while running java command

If you run above program with Java 18, without specifying charset you can see the proper characters

Code Snippets in Java API Documentation

Java 18 Introduces the @snippet tag for JavaDoc’s Standard Doclet to simplify the inclusion of example source code in API documentation that will be displayed in the generated document.

This features can be used by API developers to include sample code in the documentation and developers can see the usage of API within the documentation instead of shuffling between API and examples.

This feature facilitates the validation and formatting of source code fragments in API documentation. Although correctness is ultimately the responsibility of the author, enhanced support in javadoc and related tools can make it easier to achieve, enabling modern styling, such as syntax highlighting, as well as the automatic linkage of names to declarations, and enabling better Integrated Development Environment (IDE) support for creating and editing snippets.

There are 2 types of snippets

  • Inline snippets – code snippet is contained in the tag itself
  • external snippets – code snippet is read from another source file

Inline snippets

An inline snippet contains the content of the snippet within the tag itself.

Here is an example of an inline snippet:

The content of the snippet, which is included in the generated documentation, is the text between the newline after the colon (:) and the closing curly brace (}).

public class FileWriterExample {
    public static void main(String[] args) throws IOException {
        FileWriterExample fw = new FileWriterExample();
        String str = "漢字 败/敗 传/傳";
        String fileName = "test.txt";
        fw.writeToFile(str,fileName);
    }

    /**
     *
     * The following code shows how to use {@code writeToFile(String str,String fileName) }:
     * {@snippet :
     *      public void writeToFile(String str,String fileName) throws IOException {
     *         FileWriter fw = new FileWriter(fileName);
     *         fw.write(str);
     *         fw.flush();
     *     }
     *
     * }
     * @param str - text to be written to file
     * @param fileName - name of the file
     * @throws IOException
     *
     */
    public void writeToFile(String str,String fileName) throws IOException {

        FileWriter fw = new FileWriter(fileName);
        fw.write(str);
        fw.flush();
    }
}

If you generate javadoc for above class, you can see the sample code in documentation itself.

There are 3 limitations on the content of inline snippets

  1. An inline snippet cannot use  block comments (/* ... */) comments. */ would terminate the enclosing documentation comment
  2. The content of an inline snippet can only contain balanced pairs of curly-brace characters.
  3. Can not be shared with elsewhere in the documentation

Inline snippets are suitable for following conditions

  • Sample code is small
  • If the sample code need not shared with other parts of documentation

External snippets

An external snippet refers to a separate file that contains the content of the snippet.

In an external snippet the colon, newline, and subsequent content can be omitted.

Following code is example for an external snippet in java doc

package dev.fullstack.test;

import java.io.FileWriter;
import java.io.IOException;

public class ExternalCodeSnippets {
    public static void main(String[] args) throws IOException {
        FileWriterExample fw = new FileWriterExample();
        String str = "漢字 败/敗 传/傳";
        String fileName = "test.txt";
        fw.writeToFile(str,fileName);
    }

    /**
     *
     * The following code shows how to use {@code writeToFile(String str,String fileName) }:
     * {@snippet file="ShowFileWriter.java" region="example"}
     * @param str - text to be written to file
     * @param fileName - name of the file
     * @throws IOException
     *
     */
    public void writeToFile(String str,String fileName) throws IOException {

        FileWriter fw = new FileWriter(fileName);
        fw.write(str);
        fw.flush();
    }

    /**
     *
     * The following code shows how to use {@code writeToFile(String str,String fileName) }:
     * {@snippet class="ShowFileWriter" region="example2"}
     * @param str - text to be written to file
     * @param fileName - name of the file
     * @throws IOException
     *
     */
    public void writeToFile2(String str,String fileName) throws IOException {

        FileWriter fw = new FileWriter(fileName);
        fw.write(str);
        fw.flush();
    }
}
public class ShowFileWriter {
    // @start region="example2"
    void writeToFile(String str,String fileName) throws IOException {
        // @start region="example"
        FileWriter fw = new FileWriter(fileName);
        fw.write(str);
        fw.flush();
        // @end
    }
    // @end
}

You can refer to the external snippet using class or file attribute.

If are using file attribute , you have to mention the .java extension, while using class attribute you should omit the extention.

The @start and @end tags in ShowFileWriter.java define the bounds of the region.

You can define multiple regions with in the snippet file and refer them from source API files.

External snippet files can be placed either in a snippet-files subdirectory of the package containing the snippet tag, or in a completely separate directory.

Note

 some build systems may (incorrectly) treat files in the snippet-files directory as part of the enclosing package hierarchy, even though snippet-files is not a valid Java identifier and cannot be part of a Java package name. The local snippet-files directory cannot be used in these cases.

If you are placing snippet files outside src directory there is no restriction on the folder name.

when running javadoc command you need to specify the absolute path of snippet file using --snippet-path option.

javadoc --snippet-path=D:\IdeaProjects\Java18Features/snippet-src/src ....

Below you can see the generated java documentation.The snippet code generated based on the regions.

Advantages

  1. You can separate code and java documentation
  2. Can be written as Text files or Class files
  3. Can be shared between multiple files

References

https://jdk.java.net/18/

https://blogs.oracle.com/java/post/the-arrival-of-java-18

https://openjdk.java.net/jeps/413

https://openjdk.java.net/jeps/400

https://openjdk.java.net/jeps/408

Similar Posts