BYO: Building a wc CLI Tool with Java and GraalVM 21
Senior Backend Engineer
Search for a command to run...
Senior Backend Engineer
No comments yet. Be the first to comment.
Install Redis cli $ brew install redis-cli General PING # Test connection, returns PONG AUTH <password> # Authenticate with password SELECT <db> # Switch to a specific database (default is 0) DBSIZE # Get total nu...

InfluxDB 3 client: influxctl influxctl is the official command-line tool for managing and interacting with InfluxDB 3 clusters. Think of it as your Swiss Army knife for database setup, bucket management, and query execution. This cheatsheet gives you...
Here is an extended and fully annotated version of the Linux Cheatsheet blog in Markdown, with: Brief descriptions for each command An Advanced Topics section covering cron, systemd, firewalld, SELinux, and more Linux Cheat sheet System Informat...

1 Year on LeetCode: Lessons, Struggles, and Growth Exactly one year ago, I made a commitment — to open LeetCode daily, without excuses, and start solving problems that once made me uncomfortable. What started as a casual attempt to improve my DSA ski...

Git Cheatsheet – The Ultimate Guide Whether you're just getting started with Git or you're a seasoned developer, having a handy cheatsheet saves time and avoids Googling the same commands over and over again. This guide is organized into Basic, Inter...

wc CLI Tool with Java and GraalVM 21Creating command-line tools with Java can be both powerful and efficient, especially when paired with GraalVM's ability to compile Java applications into native executables. In this blog post, we’ll build a simple wc (word count) CLI tool in Java that counts lines, words, and characters in a file. We’ll then use GraalVM 21 to compile it into a native executable for faster startup and lower memory usage.
wc ToolThe wc command in Unix-like systems outputs the number of lines, words, and characters in a file. Our Java implementation will replicate this functionality and support file input.
Here’s the complete Java code for the wc tool:
package com.arpitrathore.byo;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
/**
* Word count
*/
public class App {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Usage: java WC <filename>");
System.exit(1);
}
String filePath = args[0];
try {
String content = Files.readString(Paths.get(filePath));
long lineCount = content.lines().count() - 1; //wc actually counts number of new line character
long wordCount = Arrays.stream(content.split("\\s+")).filter(word -> !word.isBlank()).count();
long charCount = content.length();
System.out.printf("%7d %7d %7d %s%n", lineCount, wordCount, charCount, filePath);
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
System.exit(1);
}
}
}
File Reading: The Files.readString method reads the file content as a single string.
Line Count: The content.lines() method streams the lines and counts them.
Word Count: Splits the content by whitespace and filters out empty strings.
Character Count: Simply uses the length() method on the string.
Unix-like Output: Outputs results in the format: lines words characters filename.
We’ll use Maven for dependency management and to build the project. Additionally, we’ll use the native-maven-plugin to create a native executable.
Create a pom.xml file for your project:
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.arpitrathore.byo</groupId>
<artifactId>02-wc</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<native-maven-plugin.version>0.10.4</native-maven-plugin.version>
<main.class>com.arpitrathore.byo.App</main.class>
<image.name>ar-wc</image.name>
</properties>
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native-maven-plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>build-native</id>
<phase>package</phase>
<goals>
<goal>compile-no-fork</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${main.class}</mainClass>
<imageName>${image.name}</imageName>
<agent>
<enabled>true</enabled>
</agent>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Compile the Java Code:
$ mvn clean package -Pnative
Run the Program and compare it with linux wc:
$ ./target/ar-wc pom.xml main main
49 51 1626 pom.xml
$ wc pom.xml main main
49 51 1626 pom.xml
Entire source code used in this blog can be found here: link
Building CLI tools with Java and GraalVM opens up a world of possibilities for efficient and portable applications. This wc tool is a simple example that demonstrates how you can leverage GraalVM to enhance Java’s capabilities. Try extending the tool with additional features, such as flag-based options (-l for lines, -w for words, etc.) or support for multiple files.
Let me know how you’ve used GraalVM for your projects!