DEV Community

Cover image for I built a free Redis plugin for IntelliJ Community, here's what tripped me up
chenhao5721865
chenhao5721865

Posted on

I built a free Redis plugin for IntelliJ Community, here's what tripped me up

The official Redis tooling in IntelliJ is Ultimate-only, and I use Community. The third-party plugins on the Marketplace either cost money or fall over in exactly the situations I care about: SSH tunnels, non-UTF-8 data, Remote Development.

So I wrote my own. It's called Redis Navigator, it's on the JetBrains Marketplace now, and it's completely free. No paid tier, nothing locked.

Rather than another feature list, I want to write down the bugs that cost me the most time. Maybe it saves someone an evening.

1. localhost killed the SSH tunnel, and the error blamed Redis

Jedis kept throwing:

Unexpected end of stream

I spent way too long checking Redis config, firewalls, TLS. All fine. The actual problem: JSch passes the target host string to the SSH server to resolve. My Redis host was set to localhost, the Windows OpenSSH server resolved that to IPv6 ::1, and my Redis (Memurai) only listens on IPv4. So the tunnel came up and died immediately, and Jedis reported a dead connection in the least helpful way possible.

The fix is to resolve the host to a literal IP before forwarding:

String literal;
try {
    literal = InetAddress.getByName(host).getHostAddress();
} catch (UnknownHostException e) {
    literal = host; // jump host with its own internal DNS, pass through as-is
}
Enter fullscreen mode Exit fullscreen mode

If you're debugging tunnel issues: build the channel by hand with ssh -N -L, push a PING through with a raw socket, and only then test your actual client. Splitting the SSH layer from the Redis layer makes the whole thing obvious.

2. Editing a String removed its TTL

One of those Redis semantics things: bare SET clears the TTL. I knew this. I still shipped the bug and only caught it in testing.

jedis.set(key, value, SetParams.setParams().keepttl());
Enter fullscreen mode Exit fullscreen mode

3. Pattern search has to drain the SCAN cursor

SCAN is cursor-based and one page is just a partial result. If your pattern search stops after one page, you're silently missing keys. It needs to loop until the cursor wraps back to 0, with some cap in case a pattern goes wild (mine bails at 50k keys). Scroll pagination is only appropriate for plain * browsing.

Two Jedis 6 things that got me: Pipeline.sync() returns void, so batch results need syncAndReturnAll(). And sscan/hscan want the cursor as byte[] while ScanResult.getCursor() hands you back a String.

4. A mojibake bug that was actually a feature request

Testing with Chinese data, everything showed up as garbage. The plugin was fine. The data was fine, technically. I had loaded my test data through a GBK console, so the GBK bytes went straight into Redis and my UTF-8 decoding did exactly what it should: display nonsense.

Then it clicked: some companies really do have GBK-era data sitting in production Redis. So per-connection charset (UTF-8 / GBK / auto-detect) went from nice-to-have to core feature. GBK data displays correctly and editing in GBK mode round-trips without corrupting anything.

Practical takeaway: load Chinese test data through a socket or script, never through a console. The other takeaway is to look at your bugs and ask whether they're someone else's daily reality.

5. Split Mode testing, blocked by someone else's bug

Remote Development support matters to me, so I tested with runIdeSplitMode from the IntelliJ Platform Gradle Plugin. The client just hung on "Connecting to remote host..." forever.

Turned out the plugin had a bug with spaces in the project path: when the backend restarts itself, it goes through a native restarter that drops the Gradle-provided sandbox config, and the new process never starts. My project lives in C:\Project Exploration\.... Direct hit.

Workaround was dumb but effective: copy the source to a path without spaces. I filed an issue upstream and JetBrains fixed it within a week, relaunching the backend via exit code instead of the restarter. Once that ships in a release I can delete the workaround.

The good news is everything in the plugin works in the JetBrains Client: tool window, JSON preview, editing, SSH tunnels, all verified in Split Mode.

If this sounds useful, the plugin is here:

Redis Navigator on JetBrains Marketplace

Bugs and feature requests go to GitHub issues. It's early days, I read everything and I respond fast.

Top comments (0)