Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AudioSystem.mixerInfo returns 0 mixer (Java 1.3 Service compatibility) #61

Open
jpragey opened this issue May 23, 2014 · 28 comments
Open
Labels
Milestone

Comments

@jpragey
Copy link

jpragey commented May 23, 2014

When I run the following Ceylon code :

import java.lang { ObjectArray }
import javax.sound.sampled { AudioSystem, Mixer }
hared void run() {
    ObjectArray<Mixer.Info> mixers=AudioSystem.mixerInfo;
    print("Ceylon: ``mixers.size``");
}
module org.audiotest "1.0.0" {
    import java.base "7";
    import java.desktop "7";
}

I get 0 results; however when I run the following Java code (in the same ceylon project):

package org.audiotest;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Mixer;

public class AudioTest {

    public AudioTest() {}

    public static void main(String[] args) {
        Mixer.Info[] mixers = AudioSystem.getMixerInfo();
        System.out.println("Mixers: " + mixers.length);
    }
}

I get 5 results.

I investigated it with eclipse debugger; it ended up in sun.misc.Service$LazyIterator.hasNext() loading "META-INF/services/javax.sound.sampled.spi.MixerProvider" by CeylonModuleClassLoader.getResources(), which returned an empty enumeration.

In pure java it is loaded by sun.misc.Launcher.AppClassLoader.getResources() returns 2 values.
On my PC (linux 64 / openJDK 7)
META-INF/services/javax.sound.sampled.spi.MixerProvider is in /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/resources.jar.

So the PB is probably a more general Java 1.3 Service SPI and Ceylon class loading compatibility issue than a strictly java audio one.

Full project:
https://drive.google.com/file/d/0B09FzhUz_CgbMkhRenpWQXdfQ2c/edit?usp=sharing

@FroMage
Copy link
Member

FroMage commented May 23, 2014

@alesj: how can we make this jar visible to the JDK class loader? What's weird is that I was pretty sure that the JDK used the JDK class loader, so it should just be visible to itself.

@FroMage FroMage added the BUG label May 23, 2014
@FroMage FroMage added this to the 1.1 milestone May 23, 2014
@quintesse
Copy link
Member

I know that in JBoss Modules if you use their module.xml descriptor file you have to specifically import or export any services, by default it doesn't do any of that.

So even if the module can be loaded and the classes accessed you won't be able to read any of the service entries unless you import/export them. (The docs are very vague, I think "import" means available to the module itself, "export" means available to everyone).

I don't know how this affects the JDK packages though.

@AnandA777
Copy link

I know that it isn't quite the same situation, but I found a case where someone was trying to get a Java Sound service provider set up as a JBoss module:

https://community.jboss.org/thread/200423?tstart=0&_sscc=t

Does any of the info there help?

@alesj
Copy link
Member

alesj commented May 26, 2014

Afaik, we already handle services as they should be:

Imo, this here is just a case of proper visibility?

@quintesse
Copy link
Member

What do you mean by "proper visibility"?

@alesj
Copy link
Member

alesj commented May 26, 2014

What do you mean by "proper visibility"?

It depends on what the classloader where you wanna load the services "sees".

Since I'm saying, if all is done right, the services should be loaded; see the test.

@quintesse
Copy link
Member

Well yes, but in this case it's obvious something doesn't work, @jpragey does something very simple, that is supposed to work, using an ordinary Java class that outside of JBoss Modules works just fine. So something is wrong, right? It would be nice to figure out what exactly.

@alesj
Copy link
Member

alesj commented May 26, 2014

Try adding a test to the existing ServicesTest, which would mimic what @jpragey does.
And we can go from there.

quintesse added a commit that referenced this issue May 26, 2014
@quintesse
Copy link
Member

@alesj test added

@alesj
Copy link
Member

alesj commented May 26, 2014

@quintesse both cases return zero mixers ...

@quintesse
Copy link
Member

Do you have any audio mixers in your system? ;)
The Java version should return something non-zero, otherwise there isn't anything for you to test...

@quintesse
Copy link
Member

The test will now also check for file types, to see if that returns something on your system. For me the plain Java version of the AudioSystem returns 5 mixers and 3 file types while the Ceylon runtime versions returns 0 in both cases. As long as your system has working audio you should also get a non-zero result.
(PS: you should try some well-known Java app that has sound to see if sound is properly configured on your system for Java, especially on Linux or Mac it can be a problem with access rights)

@alesj
Copy link
Member

alesj commented May 27, 2014

@dmlloyd any idea here?

quintesse added a commit that referenced this issue May 27, 2014
@alesj
Copy link
Member

alesj commented May 27, 2014

If I only run ServicesTestCase::testAudioMixerServices, I get

Number of mixers/filetypes using plain Java = 7/3
Command line: -mp /Users/alesj/projects/ceylon/ceylon-runtime/../ceylon-dist/dist/repo:/Users/alesj/projects/ceylon/ceylon-runtime/build/dist/repo ceylon.runtime:1.1.0 +executable ceylon.modules.jboss.runtime.JBossRuntime -rep /var/folders/x0/hk__mkqd78z752spn913k8sr0000gn/T ceylon.audiotest/1.0.0
Number of mixers/filetypes using Ceylon runtime = 7/3
Everything OK

So it looks like previous ServicesTestCase::testLoadServices, changes things somehow ...

@quintesse
Copy link
Member

So it looks like previous ServicesTestCase::testLoadServices, changes things somehow

But that's in your (and @tombentley 's) case. In my case there's no difference when I run it one way or the other, in both cases I always get correct result in the plain Java version and always a failure in the JBoss Modules / Ceylon runtime version.

@FroMage
Copy link
Member

FroMage commented May 27, 2014

Note that JBoss Modules fucks up with some global JVM-scope services like for XML providers, which makes it very prone to errors when run in concurrent threads. Perhaps it does something else to other providers?

@FroMage
Copy link
Member

FroMage commented May 27, 2014

Concurrent threads as in two threads running each an instance of JBoss Modules (even in two separate class loaders).

@AnandA777
Copy link

OK, I did some more looking around, and found a closer case to this one that was solved. Someone was trying to use the Java Sound API in JBoss, and was not seeing any supported file formats on their machine. The solution was:

Darran is right, it requires to edit the modules/sun/jdk/main/modules.xml and add an entry for com.sun.media.

Moreover, copy the following files to modules/sun/jdk/main/service-loader-resources/META-INF/services/
javax.sound.sampled.spi.AudioFileReader
javax.sound.sampled.spi.AudioFileWriter
javax.sound.sampled.spi.FormatConversionProvider
javax.sound.sampled.spi.MixerProvider
These files can be found inside /jre/lib/resources.jar of JDK, under /META-INF/services/

Source: https://community.jboss.org/thread/197517

There is a "modules" folder in my Ceylon project, but by default, there is no "sun" subfolder there. I could create a modules/sun/jdk/main path, add an appropriate modules.xml including com.sun.media, and copy the four named SPI files to a META-INF/services subfolder. Would that work? If so, what should I use as a starting point for the modules.xml file? If not, is this something that will have to be fixed or worked around in Ceylon? Thanks!

@FroMage
Copy link
Member

FroMage commented Sep 25, 2014

Moving to 1.2, unfortunately.

@FroMage FroMage modified the milestones: 1.2, 1.1 Sep 25, 2014
@quintesse
Copy link
Member

Argh dammit :(

@AnandA777
Copy link

I did some further searching, and it looks like this JBoss Modules issue also affected WildFly, and that it was fixed in their latest release:

https://issues.jboss.org/browse/WFLY-768

I hope that this helps to fix the issue. Aside from that, if anyone can help with a workaround as per my previous post, please let me know.

@quintesse
Copy link
Member

That's nice! If only I had an idea how to apply it to our situation.
Add that same list (or at least the ones needed to fix this issue, but I guess they spent some time in getting to that list and it will probably apply to us as well) to the ceylon-runtime module.xml?
It would be worth a shot to see what happens.

@quintesse
Copy link
Member

@quintesse
Copy link
Member

I tried applying it to our runtime and even jboss modules but that doesn't help any, so I'm afraid this is something that needs to happen at a much lower level. But I really have no idea. I was hoping @alesj could have some insights.

@AnandA777
Copy link

I tried again with Ceylon 1.2 running under Java 8, and still get 0 mixers. Is there anything that I could try or provide in order to help identify the exact cause of this issue? I would really like to help get this fixed.

@jpragey
Copy link
Author

jpragey commented Dec 6, 2015

Well, with Ceylon 1.2.1 (github) I can get some mixers, by calling ceylon from Java with the Main API. That is, I have a sound.test.Run.java class:

package sound.test;
import com.redhat.ceylon.compiler.java.runtime.Main;
public class Run {
    public static void main(String[] args){
        Main.runModule("sound.test", "1.0.0", "sound.test.run_");
    }
}

and a Ceylon run function:

// sound.test.run.ceylon
import javax.sound.sampled {
    Mixer,
    AudioSystem
}
import java.lang {
    ObjectArray
}
shared void run() {
    ObjectArray<Mixer.Info> mixers = AudioSystem.mixerInfo;
    print("Mixers: ``mixers.size``" );
}

Module.ceylon:

native("jvm")
module sound.test "1.0.0" {
    import java.base "7";
    import java.desktop "7";
}

I run it with openJDK 1.7.0 64 bits (on Linux Mint) by:

java -cp `ceylon classpath sound.test/1.0.0` com.redhat.ceylon.compiler.java.runtime.Main sound.test/1.0.0 sound.test.run_

And it prints:

Mixers: 17

I failed running it on Eclipse (Run as/Java Application); I added a bunch of jars to the classpath, but it finally failed to find [sound.test-1.0.0.car]. Maybe it's an Eclipse plugin issue?

@AnandA777
Copy link

Thanks for looking into it! If it helps, I know that it is experimental, but after reading your post I just tried running my Ceylon code (similar to yours, but Java 8) in IntelliJ IDEA. It also finds 0 Mixers.

@FroMage
Copy link
Member

FroMage commented Dec 7, 2015

Guys, FTR, this issue has moved to eclipse-archived/ceylon#4856 you should comment there now. Thanks.

@ceylon ceylon locked and limited conversation to collaborators Dec 7, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants