Hi all,
A user was playing with the SPI-Fly stuff and hit an issue, which I
have trouble understanding how it should be fixed, maybe someone has
an idea here... It might be related to the interplay between the OSGi
weaving hook and ASM...
Here's the situation:
* They use some code that at some point uses
javax.sound.sampled.AudioSystem.getAudioFileReaders(). This code goes
through a few hoops and then ends up at sun.misc.Service.providers()
which is similar to java.util.ServiceLoader.load() in that it uses the
TCCL to read resources from META-INF/service (I think its a
sun-proprietary predecessor to ServiceLoader).
* Because in their code they use AudioSystem this is the piece that
can get woven to be surrounded by TCCL settings (by using the
SPI-Consumer: javax.sound.sampled.AudioSystem#getAudioInputStream and
SPI-Provider: javax.sound.sampled.AudioSystem headers).
* However, ASM complains:
java.lang.ClassNotFoundException: javax.sound.sampled.AudioInputStream
at org.objectweb.asm.ClassWriter.getCommonSuperClass(Unknown Source)
at org.objectweb.asm.ClassWriter.a(Unknown Source)
at org.objectweb.asm.Frame.a(Unknown Source)
at org.objectweb.asm.Frame.a(Unknown Source)
at org.objectweb.asm.MethodWriter.visitMaxs(Unknown Source)
at org.objectweb.asm.commons.LocalVariablesSorter.visitMaxs(Unknown
Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at
org.apache.aries.spifly.dynamic.ClientWeavingHook.weave(ClientWeavingHook.java:60)
The relevant snippet of weaving hook code [1] is this:
@Override
public void weave(WovenClass wovenClass) {
Bundle consumerBundle = wovenClass.getBundleWiring().getBundle();
Set<WeavingData> wd = activator.getWeavingData(consumerBundle);
if (wd != null) {
activator.log(LogService.LOG_DEBUG, "Weaving class " +
wovenClass.getClassName());
ClassReader cr = new ClassReader(wovenClass.getBytes());
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS |
ClassWriter.COMPUTE_FRAMES);
TCCLSetterVisitor tsv = new TCCLSetterVisitor(cw,
wovenClass.getClassName(), wd);
cr.accept(tsv, ClassReader.SKIP_FRAMES); // line 60
* The classloader associated with the BundleRevision does have
visibility to AudioInputStream, I did this while debugging in Eclipse:
Evaluate:
wovenClass.getBundleWiring().getClassLoader().loadClass("javax.sound.sampled.AudioSystem")
(java.lang.Class<T>) class javax.sound.sampled.AudioSystem
* The bundle being woven does import javax.sound.sampled
Anyone an idea what could be the issue here? Funny enough I can get
this to work in eclipse's 'dev' mode (a framework launched from within
eclipse), but I think that's because it seeminly implicitly imports
javax.* into all bundles... If I use Felix or Equinox standalone it
fails this way.
Any ideas?
Many thanks,
David
[1]
https://svn.apache.org/repos/asf/aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/main/java/org/apache/aries/spifly/dynamic/ClientWeavingHook.java