Klaus Zimmermann's Corner

Fixing Gajim on the FreeBSD desktop

A few weeks ago, I noticed that Gajim, my favorite desktop application for Instant Messaging via XMPP, stopped working in FreeBSD. I couldn't quite tell if this was due to an update to Gajim itself or to the base FreeBSD system, but after a specific update, it simply would not open anymore. No core dump, no message, nothing, apparently.

This was a real pity because I am yet to find something that works so well for cross-device messaging as this application. I stuck with other alternatives like Profanity that serve the gap of encrypted messageing well, but not so much with sending and receiving files, so I was a little upset regarding the loss of functionality.

Reinstalling the package didn't work, and neither did issuing freebsd-update pulls. Last week, then, I decided to get my hands dirty and investigate further the issue and gladly did resolve it with a quick hack. I realize it wasn't the most elegant or correct solution but it did work well - everything was functional and the broader system was not affected - so I'm taking it for now. Here's what worked for me.

dbus at fault

Upon running gajim from the command-line, I noticed the following stack trace outlining the problem at hand:

...
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/gajim/application.py", line 233, in _startup
self.interface = Interface()
File "/usr/local/lib/python3.9/site-packages/gajim/gui_interface.py", line 2068, in __init__
music_track.enable()
File "/usr/local/lib/python3.9/site-packages/gajim/common/dbus/music_track.py", line 208, in enable
listener.start()
File "/usr/local/lib/python3.9/site-packages/gajim/common/dbus/music_track.py", line 61, in start
proxy = Gio.DBusProxy.new_for_bus_sync(
gi.repository.GLib.GError: g-file-error-quark: Cannot spawn a message bus
without a machine-id: Unable to load /var/local/lib/dbus/machine-id or 
/etc/machine-id: Failed to open file “/var/local/lib/dbus/machine-id”: 
No such file or directory (4)
05/31/2023 22:37:06 (W) gajim.gui.notification     
Notifications D-Bus not available: g-file-error-quark: Cannot spawn a
message bus without a machine-id: Unable to load /var/local/lib/dbus/machine-id 
or /etc/machine-id: Failed to open file “/var/local/lib/dbus/machine-id”: 
No such file or directory (4)

Python stack traces are not the clearest error messages around, especially if you're not the author of the program, but usually flow from the most generic part of the program until the most specific last - which is where the program actually crashed. Honing into the last bits of the message indicate that the problem lies with a dbus compatibility Python library used by Gajim that does the dbus-related abstraction and message-passing (required I think for things like notifications).

The problem is simple enough: the file machine-id presumably made available by dbus is not available in the usual locations that the Python library is used to searching. I don't know if this location difference stems from how the filesystem tree is laid out differently between Linux and FreeBSD (/usr/ vs /usr/local prefixes, etc), but this is what's holding back the entire application from loading.

Hack or fix?

If you're looking for an immediate solution that will work (as I did), look no further than this:

# ln -s /var/lib/dbus/machine-id /etc/machine-id

And that's it. The machine-id file is nothing but a text file containing some sort of hash (sha1 maybe?) that acts as the unique identifier of the machine. By making this link (we could even just copy it) at the expected location, the file is found, read and everything up the stack sort of magically works...

... Except that this feels like an ugly hack. Rightfully so, I think. And so I was left with the question of whether I should look for another way to fix this. A software patch to issue in git, maybe? After all, this is plaintext Python code which I know a thing or two about. So I picked up the ball and started looking up the stack trace to find where I could fix the error in the source.

And here's where it got hairy: turns out that the "bug" was not within Gajim's code, but rather one of the modules it imported that interacted with dbus. The module's code attempts to detect the machine-id file and breaks when it isn't found. Ok, stop. Do I really wanna go and try to rewrite the whole library instead? I don't think that's in the scope of my original intentions. Who knows if I'll break some other application by fixing something to work only with Gajim? That's too much risk for me, not a usual developer, to take.

So bottom line I remained with my silly-but-perfectly-working hack to make Gajim work and sort of stuck with it.

Conclusion

Gajim still continues to work well with FreeBSD despite the latest versions produce a hickup of sorts to start. The fix, as ugly as it looks, is all you need to make it work, and I'm surprised it doesn't come "pre-fixed" like this by default. Perhaps a better fix would be to mess a little bit with the post-install "hooks" scripts, which run right after the package contents are copied to the install locations, where the command above verbatim could be issued after the package in installed (and reversed when uninstalling).

This incident, and lack of response to it, highlighted for me a small detail on how the FreeBSD community doesn't put too much attention on things that belong on the desktop side of it, which is a real pity, given how well FreeBSD plays on the desktop. Oh well, I guess people still think it's only suited for servers. Perhaps I'll need to keep spreading the word a little bit more!

Or who knows, maybe this can be my first software patch to a public project ever!


Have you had trouble using Gajim on FreeBSD lately? How did you get around and fix it? Let me know in the Fediverse!


This post is number #43 of my #100DaysToOffload project.


Last updated on 05/31/23