Planetfall BWEND
Planetfall BWRELEND
HomeRELENDREF
HomeBDREF
SABDREF
Planetfall Planetfall SABD
It's To-Po!


Site Games Miscellaneous /
Dream Land Java :: Development Logs :: Linux Sound (ALSA) and Java

If you look around this great big Internets of ours, you can find endless stories of people complaining about the ill-suited combination of Java, Linux, and sound. I originally set out to fix just my applets, but I think I came up with a way to get ALSA to play nice with all Java I run -- and you can, too~!


Uncovering the Issue

I have done (or had done by others) testing on a plethora of platforms: Windows, Debian, Red Hat, Solaris? I never had a problem with anything until, on a job interview, I was told that one of my applets died shortly after starting. He was using Ubuntu, which I had known to work fine for another unwitting test player.

Over time, I stressed my Debian to the limit, trying to reproduce any sort of error that would only happen on a GNU/Linux OS and not the more common (for desktop use, anyway) Windows. I finally narrowed it down to a null pointer exception being thrown when a sound was supposed to play.

Lazy exception handling on my part, granted, but what was up with that sound? The audio was unable to open. And why did it only happen on some of my kernel configurations?


A Little Background

ALSA (Advanced Linux Sound Architecture) is the "new" sound system for the Linux kernel, and that simply means "the one which isn't deprecated currently." ALSA is the more featureful replacement for OSS (Open Sound System), which has fallen out of favor.

Except for Java's favors, it would seem.

Sound on Java hasn't been the same since ALSA took over. Sun even rolled out a new version of Java without addressing the current sound issue. It isn't even that difficult an issue, one would think. Instead of grabbing the entire hardware audio device, just take a line on the software mixer. Well, it must be difficult to someone, 'cause that bug is from 2005.


The issue that arises from Java attempting to use sound is Java becoming the only process allowed to use sound on a Linux system. Worse yet, whichever audio line it first opens becomes the only audio line allowed to be opened! Putting a stranglehold on the sound card even prevents Java from opening more sounds. When playing Kirbj with only basic ALSA support, you get the first sound buffered (typically the "hit" effect) and that's it.

How can this be overcome for open source types who want to have their Java and listen to it, too?


Sound Solutions

OSS Kernel Emulation: One may compile the Linux kernel for backwards-compatibility with the older sound system. (This is the reason, I suspect, why I was seeing various results with Java and Linux OSes.) Java will be able to open more than one audio line with this configuration option, but it will still lock out any other process from touching the audio device.

And if you already have some music playing, as I often do with my last.fm while programming? Wellsir, then no audio at all loads for your Java. It is all or nothing for Java going this route, which is still more than the one or nothing with plain ALSA.


OSS Software Emulation: This one takes a bit more effort, but the results are far superior. The alsa-oss package contains a wonderful little wrapper called aoss. Whatever you run through this script will receive an emulated OSS treatment on a system running ALSA, and much better than the kernel option, from my experience. Of course, my sole criteria is "Does other audio play when I'm using Java audio?"

The answer is yes.

Usage, however, is a bit more tricky. Normally, one would simply prepend an li'l somethin' on the command line like so:

$ aoss appletviewer com/realitysend/kirbj/gamepack/gooxmoo/kirby.html

Works like a charm!... for debugging. What command do you type to execute the applet plug-in? Oh, right, you don't! But somebody does, somewhere on the system. And a little digging shows that there isn't one simple answer to that question.

  • In the file ~/.java/deployment/deployment.properties, there is a value called deployment.javaws.jre.0.path which is set to the location of the java binary. Change that, and change how the plug-in is executed, right? Well, apparently not. At least on my Debian, this value resets every time you load a new applet.
  • There is supposed to be a global configuration in /etc/java or /etc/.java, but I don't have one. Guess I can't do that.
  • The Sun Plugin Control Panel (just type ControlPanel at the prompt) allows you to view all current plugins (Java tab, View button). You can even edit the paths to the binaries! But hit OK and go back, and everything is reset. Even if you sudo, too.
  • Under the Debian package alternatives system, one has update-java-alternatives to pick from Sun Java or Open JDK or whatever else is currently installed. Everything is stored under /usr/lib/jvm, and in that directory are .*.jinfo files for each alternative (in addition to directories containing all of their files). These .jinfo files contain the locations of all libraries and binaries. Just change the location on the line "jre java" and change your Java executable, right?
    $ sudo update-java-alternatives -s java-6-sun
    update-alternatives: error: alternative /usr/lib/jvm/java-6-sun/jre/bin/aoss-java for java not registered, not setting.
    Guess not. I don't want to create an entirely new alternative, either. Luckily, there is a less intrusive way that in some way seems way more intrusive.
  • The solution currently running on my system is to swap out my java executable for a script which wraps the actual executable through aoss. The biggest downfall to this hack is its poor compatibility with the packaging system. Of course, upgrading your Java would create a new directory anyway, which would require this process to be repeated, so it isn't too horrible.

So, in case, you are a lazy and half brain-dead mess like me but do not want to make the frequent mistakes along the way that I did ("Oh, right, the executable needs executable permissions!"), here is everything spelled out for you nice and simple:

  1. If you don't have aoss, get it. (And if you don't have Java, what are you even doing here?)
    $ sudo apt-get install alsa-oss
  2. Get the full paths of both executables to be used by your simple little script. It is important for the java executable that this be the fully dereferenced location.
    $ type -p aoss
    /usr/bin/aoss
    $ readlink -f `type -p java`
    /usr/lib/jvm/java-6-sun/jre/bin/java
    Your locations could differ from the ones above.
  3. Get your java out of the way, but make sure it stays someplace you won't lose track.
    $ sudo mv /usr/lib/jvm/java-6-sun/jre/bin/java{,.real}
    This simply renames java to java.real. Again, use the paths found on your machine.
  4. Now it is time to make your script where the java executable once lived.
    $ sudo vi /usr/lib/jvm/java-6-sun/jre/bin/java
    #!/bin/sh
    /usr/bin/aoss /usr/lib/jvm/java-6-sun/jre/bin/java.real $@
    Note that the java.real name was used; otherwise, you will call java from within java, creating an endless loop!
  5. Make your script executable. (That is, if you want anything to happen when you try viewing an applet.)
    $ sudo chmod +x /usr/lib/jvm/java-6-sun/jre/bin/java
  6. Go enjoy yourself some Linux-powered applet goodness, chock full of sound!


  7. Next Oldest Log: Recorded Sessions
    Previous Page: Recorded Sessions
    Back to the
    Dream Land Java Dev Logs
    This is the newest log
    This is the last page

Comment
Account Info
User Name:
Password:
Account Type:

No discussions exist yet for this. You can start one if you would like.

Copyright © 1999-2017