DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java
  • Java Is Greener on Arm
  • Mastering Date/Time APIs: Challenges With Java's Calendar and JDK Date/Time APIs
  • Java 23: What Developers Need to Know

Trending

  • Cookies Revisited: A Networking Solution for Third-Party Cookies
  • Blue Skies Ahead: An AI Case Study on LLM Use for a Graph Theory Related Application
  • Artificial Intelligence, Real Consequences: Balancing Good vs Evil AI [Infographic]
  • Immutable Secrets Management: A Zero-Trust Approach to Sensitive Data in Containers
  1. DZone
  2. Coding
  3. Java
  4. Launch Single-File Source-Code Programs in JDK 11

Launch Single-File Source-Code Programs in JDK 11

JDK 11 will allow you to run your Java source directly with the Java interpreter. Let's take a look!

By 
Mohamed Sanaulla user avatar
Mohamed Sanaulla
·
Jul. 09, 18 · Tutorial
Likes (8)
Comment
Save
Tweet
Share
23.0K Views

Join the DZone community and get the full member experience.

Join For Free

JEP 330 - Launch Single-File Source-Code Programs is one of the most exciting features in the upcoming JDK 11(18.9) release. This feature allows executing your Java source code directly using the java interpreter. The source code is compiled in memory and then executed by the interpreter. The limitation is that all the classes have to be defined in the same file.

This feature is particularly useful for someone who is starting to learn Java and wants to try simple programs. This feature, along with jshell, will be a great toolset for any beginners in learning the language. Not only beginners will benefit.  Professionals can also make use of these tools to explore new language changes or to try out an unknown API.

In this post, I will not go into the details of how this feature is implemented. Instead, I will focus on using this feature by trying out different samples. Let's start with the simplest example, as usual, the "Hello, World!"

"Hello, World" Example

The below code is saved in a file HelloWorld.java.

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


I will run the above code as shown below:

PS G:\samples\java11\single-file> java HelloWorld.java
Hello World!!!


In the above example, there is only one class and it contains the main method. While executing the code using java, we need to pass to it the name of the file ending in .java extension. If the filename doesn't end with .java extension, then we have to use the option --source. We will see this in the next example.

With Command Line Arguments

Let's enhance our "Hello World" program to create a personalized greeting for each person:

public class Greeting{
    public static void main(String[] args){
        if ( args == null || args.length < 1 ){
            System.err.println("Name required");
            System.exit(1);
        }
        System.out.println(String.format("Hello %s!!", args[0]));
    }
}


Let's store the above code in a file named HelloGreeting.java. Notice that the name of the file doesn't match the name of the public class. Let's run the above code using:

PS G:\samples\java11\single-file> java HelloGreeting.Java sana
Hello sana!!


Any arguments passed to the code, as provided after the name of the file, needs to be executed. Let's rename HelloGreeting.java to just greeting and try to execute this using the same approach:

PS G:\samples\java11\single-file> java greeting sana
Error: Could not find or load main class greeting
Caused by: java.lang.ClassNotFoundException: greeting


You can see that, in the absence of .java, the interpreter is looking for a compiled class by the name provided as the argument. In such scenarios, we need to use the --source option, as shown below:

PS G:\samples\java11\single-file> java --source 11 greeting sana
Hello sana!!


Let me show you how code written for JDK 10 will not work for JDK 9 when we use the --source option:

public class Java10Compatible{
    public static void main(String[] args){
        var message = "Hello world";
        System.out.println(message);
    }
}


Let's execute the above for JDK 10 and JDK 9 as shown below:

PS G:\samples\java11\single-file> java --source 10 Java10Compatible.java
Hello world
PS G:\samples\java11\single-file> java --source 9 Java10Compatible.java
.\Java10Compatible.java:3: error: cannot find symbol
        var message = "Hello world";
        ^
  symbol:   class var
  location: class Java10Compatible
1 error
error: compilation failed

Multiple Classes in a Single File

As I mentioned before, this feature supports running code that resides in a single file. There are no restrictions on the number of classes in the file. Let's look at a sample code that contains two classes:

public class SimpleInterest{
    public static void main(String[] args){
        if ( args == null || args.length < 3 ){
            System.err.println("Three arguments required: principal, rate, period");
            System.exit(1);
        }
        int principal = Integer.parseInt(args[0]);
        int rate = Integer.parseInt(args[1]);
        int period = Integer.parseInt(args[2]);
        double interest = Maths.simpleInterest(principal, rate, period);
        System.out.print("Simple Interest is: " + interest);
    }
}

public class Maths{

    public static double simpleInterest(int principal, int rate, int period){
        return ( principal * rate * period * 1.0 ) / 100;
    }
}


Now, let's run this:

PS G:\samples\java11\single-file> java .\SimpleInterest.java 1000 2 10
Simple Interest is: 200.0


In the case of a file with more than one class defined, the first class should contain the main method. The interpreter, after compiling in memory, will use the first class to launch the execution.

Using Modules

The in-memory compiled code is ran as part of an unnamed module with the option --add-modules=ALL-DEFAULT. This enables the code to use different modules without the need to explicitly declare dependency using the module-info.java

Let's look at the code that makes an HTTP call using the new HTTP Client APIs. These APIs were introduced in Java 9 as an incubator feature and have been moved out from the incubator into the java.net.http module. The example code is:

import java.net.http.*;
import java.net.http.HttpResponse.BodyHandlers;
import java.net.*;
import java.io.IOException;

public class ExternalModuleDepSample{
    public static void main(String[] args) throws Exception{
        HttpClient client = HttpClient.newBuilder().build();
        HttpRequest request = HttpRequest.newBuilder()
            .GET()
            .uri(URI.create("https://reqres.in/api/users"))
            .build();

        HttpResponse<String> response = 
            client.send(request, BodyHandlers.ofString());
        System.out.println(response.statusCode());
        System.out.println(response.body());     
    }
}


We can run the above code by issuing the following command:

PS G:\samples\java11\single-file>java ExternalModuleDepSample.java
200
{"page":1,"per_page":3,"total":12,"total_pages":4,
"data":[{"id":1,"first_name":"George","last_name":"Bluth",
"avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"},
{"id":2,"first_name":"Janet","last_name":"Weaver",
"avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"},
{"id":3,"first_name":"Emma","last_name":"Wong",
"avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"}]}


This allows us to quickly test new features in different modules without going through creating modules, module-info files, and so on.

Shebang Files

In this section, we will look at creating shebang files. Shebang files are files that can be executed directly on the Unix systems by providing the executor using the syntax #!/path/to/executable as the first line of the file.

Let's create a shebang file:

#!/g/jdk-11/bin/java --source 11

public class SimpleInterest{
    public static void main(String[] args){
        if ( args == null || args.length < 3 ){
            System.err.println("Three arguments required: principal, rate, period");
            System.exit(1);
        }
        int principal = Integer.parseInt(args[0]);
        int rate = Integer.parseInt(args[1]);
        int period = Integer.parseInt(args[2]);
        double interest = Maths.simpleInterest(principal, rate, period);
        System.out.print("Simple Interest is: " + interest);
    }
}

public class Maths{

    public static double simpleInterest(int principal, int rate, int period){
        if ( rate > 100 ){
            System.err.println("Rate of interest should be <= 100. But given values is " + rate);
            System.exit(1);
        }
        return ( principal * rate * period * 1.0 ) / 100;
    }
}


The source option in the shebang is used in cases where the name of the file doesn't follow the standard Java filename naming convention. In our case, we have saved the above code in a file called simpleInterest. We can run this as:

sanaulla@Sana-Laptop  /g/samples/java11/single-file (master)
$ ./simpleInterest 1000 20 2
Simple Interest is: 400.0

On Windows machines, I have used the bash shell that comes with the git installation. There are multiple other ways like Cygwin, Windows 10 Ubuntu Support and so on.

The source code for this can be found here.

Java (programming language) Java Development Kit

Published at DZone with permission of Mohamed Sanaulla, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java
  • Java Is Greener on Arm
  • Mastering Date/Time APIs: Challenges With Java's Calendar and JDK Date/Time APIs
  • Java 23: What Developers Need to Know

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!