OSGi Karaf Scala UnsupportedAudioFileException

时间:2014-04-09 21:00:33

标签: scala maven audio osgi karaf

这是我在这里的第一篇文章。我目前正在使用Apache-Karaf 3.0.0上的Scala中的简单http音频servlet。我将它作为一个功能部署在一些捆绑包中,我使用maven项目构建了这些功能。我正在使用' javax.sound.sampled'用于获取音频的库,我使用' java.io.File'从AudioSystem加载文件。

    val file = new File("audioFile.wav")
    val audioStream = AudioSystem.getAudioInputStream(file)

这显然不是实际的代码,因为我已经删除了所有的小部分。但这就是它失败的地方,在getAudioInputStream'调用

当我将此代码部署到Karaf时,它失败了&UnsapportedAudioFileException'。该文件确实存在,并且可读,我已经验证了这一点。此外,我已确保此代码可以在以下运行。    - Scala 2.10.2,2.10.3    - Java 1.7.0_45(这与我的Karaf程序使用的JRE相同)    - SBT 0.12.4(使用不同的Scala版本)

唯一失败的地方是我将它部署到Karaf。我不知道Karaf是否已经删除了一些随机音频支持,或者发生了什么,因为这在通过SBT或使用Scala命令行进行部署时会起作用。我也考虑过替代图书馆,但无济于事。大多数其他解决方案似乎都是基于通过声音驱动器实际播放音频,这对我来说毫无用处。我需要实际的字节数据。

另外,请记住,只是发送文件也没用。另一个要求是我需要能够将多个音频文件合并到一个无缝音频流中。我已经完成了这个,我只需要将它移植到OSGi,由于某种原因我现在得到了这个错误。我不知道Karaf是否与它有关,或者我通过Maven项目构建它是否已经破坏了某些东西。我环顾四周,几乎没有发现问题可能出在哪里。

我使用的音频文件属于Waveform音频。 8,000个采样率,每个样本16位。我不认为这会有所作为,但我不是音频格式方面的专家。

我的pom.xml依赖项如下。我唯一使用的插件是Scala编译器,当然我的root pom.xml使用的是org.apache.felix maven-bundle-plugin。这里的魔法真的不多,但神秘感仍然存在。

    <dependency>
        <groupId>org.scala-lang</groupId>
        <artifactId>scala-library</artifactId>
        <version>2.10.3</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>

非常感谢任何线索,谢谢。

2 个答案:

答案 0 :(得分:3)

我认为AudioSystem还没有完全准备好OSGi。这就是我在Aries Spy Fly dcoumentation中发现的。 不知道你究竟要做些什么来使其发挥作用,但这可能会有所帮助。

https://aries.apache.org/modules/spi-fly.html

特例

SPI Fly可用于大多数使用TCCL模式获取实现的SPI提供者/查找系统。但是在某些情况下,需要一些特殊的治疗。当API本身与META-INF / services中的资源名称不匹配时,经常需要这种特殊处理,java.util.ServiceLoader就是这种情况,但SPI-Fly具有ServiceLoader的内置知识。下面列出了需要特殊处理的已知API:

javax.sound.sampled.AudioSystem:此类使用sun.misc.Service(通过com.sun.media.sound.JDK13Services),它是java.util.ServiceLoader的前身。 SPI Fly(尚未)中的sun.misc.Service没有特殊处理,但AudioSystem.getAudioInputStream()API可以通过在提供程序包中明确列出它来工作(包含相关的META-INF /服务资源):SPI-Provider:消费者方面的javax.sound.sampled.AudioSystem可以使用SPI-Consumer:javax.sound.sampled.AudioSystem#getAudioInputStream

答案 1 :(得分:1)

Christian的回答是正确的,但我想提供spifly文档页面的更新链接。具体做法是:

  

Java的java.util.ServiceLoader.load(),其他类似的方法如   sun.misc.Service.providers()以及其他静态查找器方法等   当FactoryFinder.find()方法试图找到'服务'   通过在META-INF / services中查找资源来实现   线程上下文ClassLoader可见的所有jar的目录   (TCCL)。

     

使用上述机制时存在许多问题   OSGi的:

     
      
  1. 线程上下文ClassLoader在OSGi上下文中一般没有定义。它可以并且必须由调用者设置,而OSGi则不能   通常会强制执行。
  2.   
  3. 捆绑包无法导入 - 打包META-INF /服务,因为可能很多捆绑包将包含此伪包和OSGi框架   只会将单个导出器绑定到给定包的导入器。
  4.   
  5. 实例化SPI提供程序通常需要通过导出这些类来访问内部实现类   实现bundle会破坏它的封装。
  6.   
  7. 即使导出了实现类,在使用者包中导入此类也会将其绑定到特定实现   提供的包装,违反了松散耦合的原则。
  8.   
  9. 捆绑包具有动态生命周期,这意味着更新或卸载捆绑包时提供的服务可能会消失。该   java.util.ServiceLoader API不提供通知机制   服务此类活动的消费者。
  10.         

    SPI Fly项目可以使用现有的代码   ServiceLoader.load()和OSGi下的类似机制。

请注意,截至2016-05-20,com.googlecode.soundlibs工件的新版本已上传到maven中央存储库。这些工件的新版本是适当的OSGi包。这将帮助每个需要在OSGi容器中使用Java Sound API的人

我创建了一个simple example project on github,演示了如何使用Java Sound API在OSGi容器中播放MP3文件。检查分支static-weavingdynamic-weaving以查看相应的解决方案。