DEV Community

anand jaisy
anand jaisy

Posted on

The JVM’s Greatest Irony: Brilliant Engineering, Painful Scripting

The Java Virtual Machine (JVM) is one of the most remarkable pieces of engineering in the software world. Over the last three decades, it has evolved through countless optimizations, design refinements, and community contributions. With the recent release of Java 25, the platform continues to demonstrate its commitment to performance, stability, and innovation — not just in runtime efficiency but also in language design and developer experience.

That said, sometimes it’s the small things that matter most to developers. While Java is an industrial-grade powerhouse, scripting in Java can still feel like a nightmare compared to lightweight languages such as Python.

🧩 Example: Generating RSA Private and Public Keys

Here’s a simple Python script that generates a private RSA key and a public JWKS (JSON Web Key Set):

from jwcrypto import jwk
import json, uuid

key = jwk.JWK.generate(kty='RSA', size=2048)
key_id = str(uuid.uuid4())
key['kid'] = key_id
key['use'] = 'sig'
key['alg'] = 'RS256'

print("Private Key (keep secret):")
print(key.export_private())
print("\nPublic JWKS:")
print(json.dumps({"keys": [json.loads(key.export_public())]}, indent=2))
Enter fullscreen mode Exit fullscreen mode

Running it is as simple as:

python generate_jwks.py
Enter fullscreen mode Exit fullscreen mode

Clean, readable, and done.

☕ Doing the Same in Java

Let’s attempt the same thing in Java using the Nimbus JOSE + JWT library:

import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.jwk.gen.*;
import net.minidev.json.JSONObject;
import java.util.UUID;

    void main() {
        RSAKey rsaJWK = new RSAKeyGenerator(2048)
                .keyID(UUID.randomUUID().toString())
                .algorithm(com.nimbusds.jose.JWSAlgorithm.RS256)
                .keyUse(KeyUse.SIGNATURE)
                .generate();


        IO.println("Private Key (keep secret):");
        IO.println(rsaJWK.toJSONString());


        RSAKey rsaPublicJWK = rsaJWK.toPublicJWK();
        JSONObject publicJWKS = new JSONObject();
        publicJWKS.put("keys", new Object[]{rsaPublicJWK.toJSONObject()});

        IO.println("\nPublic JWKS:");
        IO.println(publicJWKS.toJSONString());
    }
Enter fullscreen mode Exit fullscreen mode

At first glance, the Java code looks fine — structured, type-safe, and easy to follow.
But the real challenge comes when you try to run it.

⚙️ The Developer Reality

Now the main pain comes when we try to run this piece of code. When we try to compile this we will get bunch of error due to

Unlike Python, where you can just execute the script, running this Java snippet isn’t quite so straightforward.
You’ll quickly run into missing imports and dependency errors such as:

import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.jwk.gen.*;
import net.minidev.json.JSONObject;
import java.util.UUID
Enter fullscreen mode Exit fullscreen mode

To fix this, you’ll need to include external dependencies. For example, using Maven, you would add:

<dependency>
  <groupId>com.nimbusds</groupId>
  <artifactId>nimbus-jose-jwt</artifactId>
  <version>9.40</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Then compile and run:

mvn compile
mvn exec:java -Dexec.mainClass="com.example.App"
Enter fullscreen mode Exit fullscreen mode

And just like that, what was a one-liner execution in Python becomes a mini build process in Java.

🚀 The Modern Way — Run Java Like a Script Using JBang

JBang a brilliant tool that lets you run Java files just like Python scripts, with zero project setup or Maven configuration.

Install using sdkman

sdk install jbang
Enter fullscreen mode Exit fullscreen mode
import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.jwk.gen.*;
import net.minidev.json.JSONObject;
import java.util.UUID;

void main() {
        RSAKey rsaJWK = new RSAKeyGenerator(2048)
                .keyID(UUID.randomUUID().toString())
                .algorithm(com.nimbusds.jose.JWSAlgorithm.RS256)
                .keyUse(KeyUse.SIGNATURE)
                .generate();

        IO.println("Private Key (keep secret):");
        IO.println(rsaJWK.toJSONString());

        RSAKey rsaPublicJWK = rsaJWK.toPublicJWK();
        JSONObject publicJWKS = new JSONObject();
        publicJWKS.put("keys", new Object[]{rsaPublicJWK.toJSONObject()});

        IO.println("\nPublic JWKS:");
        IO.println(publicJWKS.toJSONString());
    }
}
Enter fullscreen mode Exit fullscreen mode

Save this file as GenerateJWK.java and run it directly — no pom.xml, no setup:

jbang GenerateJWK.java
Enter fullscreen mode Exit fullscreen mode

JBang will automatically:

  1. Download the required dependencies (nimbus-jose-jwt:9.40)
  2. Compile your code
  3. Run it in a single step

Just like Python or Node.js.

Top comments (0)