Skip to content

Instantly share code, notes, and snippets.

View headius's full-sized avatar

Charles Oliver Nutter headius

View GitHub Profile
@headius
headius / making_java_more_command_line_friendly.md
Last active January 15, 2026 22:46
Making `java` more command-line friendly

We had a good discussion while I was in the informal meetup today, and I'm putting together a summary of action items we might want to consider for outreach (more blog posts, more content on short-form video sites, refreshing old articles and projects). One of the ideas I had that I really want to dig into is that new developers aren't looking for their next "enterprise application" language. They want to run something small, quickly. Java is not known for being small or quick.

I wanted to try playing with the "small" hello world, since it was mentioned that other language fans still use this as a way to dunk on Java.

I believe the smallest we can get right now in 25 (as a readable one-liner without golfing) is:

void main() { IO.println("Hello!"); }
@headius
headius / stringio.diff
Created December 2, 2025 02:52
Removing ptr from StringIO, which is not compatible with dup'ing
diff --git a/ext/java/org/jruby/ext/stringio/StringIO.java b/ext/java/org/jruby/ext/stringio/StringIO.java
index f3ab1cf..9c58077 100644
--- a/ext/java/org/jruby/ext/stringio/StringIO.java
+++ b/ext/java/org/jruby/ext/stringio/StringIO.java
@@ -79,27 +79,17 @@ import static org.jruby.util.RubyStringBuilder.types;
@JRubyClass(name="StringIO")
@SuppressWarnings("serial")
public class StringIO extends RubyObject implements EncodingCapable, DataType {
- static class StringIOData {
- /**
// This code was generated by AI. It's completely wrong.
public static RubyFixnum newFixnum(Ruby runtime, long value) {
if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
return newFixnum(runtime, (byte) value);
} else if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
return newFixnum(runtime, (short) value);
} else if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
return newFixnum(runtime, (int) value);
}
@headius
headius / gist:15413f657dad8d83c474114f8f9cf26a
Created November 4, 2025 04:47
fast-ruby benchmarks comparing JRuby 10.0.3.0-head with CRuby 3.4.7
$ ruby -e 'files = Dir["code/**/*.rb"]; files.each_with_index {|file, i| puts "#{i+1}/#{files.size}: #{file}"; system "jruby #{file}"; system "/Users/headius/.rubies/ruby-3.4.7/bin/ruby --jit #{file}" }'
1/68: code/array/array-concat-vs-+.rb
jruby 10.0.3.0-SNAPSHOT (3.4.5) 2025-11-04 d74cb7a2e0 OpenJDK 64-Bit Server VM 21.0.8+9-LTS on 21.0.8+9-LTS +indy +jit [arm64-darwin]
Warming up --------------------------------------
Array#concat 289.000 i/100ms
Array#+ 1.000 i/100ms
Calculating -------------------------------------
Array#concat 3.037k (± 1.1%) i/s (329.29 μs/i) - 15.317k in 5.044432s
Array#+ 13.653 (± 0.0%) i/s (73.24 ms/i) - 69.000 in 5.059999s
@headius
headius / gist:a824c87293ac8f96bfa65f8f838da7cd
Created October 22, 2025 20:33
Single-jar deployment of Sidekiq running the plain-old-Ruby example
sidekiq $ export RAILS_VERSION=7.1
sidekiq $ bundle
...
Bundle complete! 21 Gemfile dependencies, 88 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
sidekiq $ warble
rm -f sidekiq.jar
Creating sidekiq.jar
sidekiq $ export JDK_JAVA_OPTIONS=-Djava.net.preferIPv4Stack=true
sidekiq $ java -jar sidekiq.jar -r ./examples/por.rb
@headius
headius / console.txt
Created October 17, 2025 18:02
Two steps to create a redistributable Ruby app in an executable jar
[] image_voodoo_demo $ jruby -Ilib exe/voodoo PXL_20250802_162259596.jpg
wrote demo files to /Users/headius/work/image_voodoo_demo/PXL_20250802_162259596/
[] image_voodoo_demo $ ls PXL_20250802_162259596
border.jpg cropped_thumb.jpg cropped.jpg reduced.jpg resized.jpg resized.png thumb.jpg
[] image_voodoo_demo $ rm -rf PXL_20250802_162259596
[] image_voodoo_demo $ gem install warbler
Fetching warbler-2.1.0.gem
Successfully installed warbler-2.1.0
Parsing documentation for warbler-2.1.0
Installing ri documentation for warbler-2.1.0
@headius
headius / gist:88d91118ef1487b4fbff357fecf06904
Created October 2, 2025 17:07
JDK25 failing to load JRuby AppCDS JSA
] jdk25 $ rm /Users/headius/work/jruby/lib/jruby-java25.jsa
[] jdk25 $ /Library/Java/JavaVirtualMachines/zulu-25.jdk/Contents/Home/bin/java @/Users/headius/work/jruby/bin/.jruby.java_opts @/Users/headius/work/jruby/bin/.jruby.module_opts -Xss2048k -Djffi.boot.library.path=/Users/headius/work/jruby/lib/jni -Djava.security.egd=file:/dev/urandom -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=/Users/headius/work/jruby/lib/jruby-java25.jsa --enable-native-access=org.jruby.dist --sun-misc-unsafe-memory-access=allow --module-path /Users/headius/work/jruby/lib/jruby.jar -classpath : -Djruby.home=/Users/headius/work/jruby -Djruby.lib=/Users/headius/work/jruby/lib -Djruby.script=jruby -Djruby.shell=/bin/sh -Xlog:aot,cds org.jruby.Main -e 1
[0.007s][info][cds] Specified shared archive file not found (/Users/headius/work/jruby/lib/jruby-java25.jsa)
[0.012s][info][cds] trying to map /Library/Java/JavaVirtualMachines/zulu-25.jdk/Contents/Home/lib/server/classes.jsa
[0.012s][info][cds] Opened shared archive file /Librar
@headius
headius / training.md
Last active September 20, 2025 15:52
pre-trained JRuby + AOT for gem list

This is an experiment to pre-train and AOT enough of JRuby to get startup time for "gem list" down to a reasonable speed. I've tried various combintions and so far this seems to be the best, but the timings are highly variable.

Step 1: Perform a gem list while dumping IR. This saves the compiled IR for all loaded files to disk, to skip parsing and compiling in future runs.

jruby --dev -Xir.writing -S gem list > /dev/null

Step 2: Train AOT by running the following script repeatedly with the given JRuby arguments. Requires a small JRuby patch because IR reading breaks for any script has not been written (like the training script).

@headius
headius / gist:cf18f247c1a66f36210b50fcb10304f0
Created May 7, 2025 15:38
JRuby 10 start up and get NMT dump
Native Memory Tracking:
(Omitting categories weighting less than 1KB)
Total: reserved=1341322KB, committed=143578KB
malloc: 30682KB #118112, peak=33492KB #117863
mmap: reserved=1310640KB, committed=112896KB
- Java Heap (reserved=57344KB, committed=32768KB)
(mmap: reserved=57344KB, committed=32768KB, at peak)
@headius
headius / gist:911b66eac8d0cb8ef7b9f2ff8d9f4133
Created March 20, 2025 22:11
Crash loading shared archive on 23+valhalla build
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGBUS (0xa) at pc=0x0000000103e8e604, pid=4379, tid=35331
#
# JRE version: OpenJDK Runtime Environment (23.0+1) (build 23-valhalla+1-90)
# Java VM: OpenJDK 64-Bit Server VM (23-valhalla+1-90, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-aarch64)
# Problematic frame:
# V [libjvm.dylib+0x9ce604] SystemDictionaryShared::ArchiveInfo::lookup_lambda_proxy_class(LambdaProxyClassKey*)+0x5c
#