Hi Karl, I'll look into the details you mention about cyclic dependencies. On the retrotranslator bundles, they are made available by specifying a dynamic-import which is added to the manifest during retrotranslation (so that our code/libraries can run on). Unfortunately, running unretrotranslated does not help.
Thanks a lot for your help, Dan. On 12 Nov 2013, at 09:51, Karl Pauls wrote: > Well, my guess would be that you are running into some form of a circular > class load issue. The point is that the class loader in java is > synchronized which my lead to deadlocks if you have a cycle in your class > loaders. This is a long standing issue with frameworks like OSGi which > allow for cycles in the dependencies. > > I don't know enough about your app to say for sure nor to help you with > this but look at the dependencies of your bundles and see whether they > create a cycle (i.e., Bundle A depends via some import on Bundle B which > depends via some import on Bundle C which depends via some import on Bundle > A or something similar). In your case, it might be even more complicated as > the retrotranslator seems to do some class loading magic by itself which > might be responsible for the issue - how do you make the > net.sf.retrotranslator.* > packages available to the bundles? > > regards, > > Karl > > > On Fri, Nov 8, 2013 at 10:44 PM, Daniel McGreal <[email protected]> wrote: > >> Hello Felix developer community, >> >> I am having an interesting (and critical) problem running my application >> with Felix in an embedded environment where an alternate JVM, JamVM is >> necessary. >> >> The deadlock is non-deterministic with the deadlocked stack traces >> blocking at odd places (though they might not seem odd to people used to >> messing with class loading - but a block on new XXX() to me is quite the >> novelty). An example of the relevant parts of the thread stack is in >> FelixJamVMDeadlockStackTrace.txt, attached. It shows a lock between: >> >> >> - >> - java.lang.ClassLoader.findLoadedClass(ClassLoader.java:580) looks >> like: >> >> protected final synchronized Class<?> findLoadedClass(String name) >> { >> checkInitialized(); >> return VMClassLoader.findLoadedClass(this, name); >> } >> >> where line 580 is checkInitialized() which throws an exception if >> isInitialized is false. >> >> - >> net.sf.retrotranslator.runtime.asm.ClassReader.readConst(ClassReader.java:1591) >> looks like: >> >> public Object readConst(final int item, final char[] buf) { >> int index = items[item]; >> switch (b[index - 1]) { >> case ClassWriter.INT: >> return new Integer(readInt(index)); >> case ClassWriter.FLOAT: >> return new Float(Float.intBitsToFloat(readInt(index))); >> case ClassWriter.LONG: >> return new Long(readLong(index)); >> case ClassWriter.DOUBLE: >> return newDouble(Double.longBitsToDouble(readLong(index))); >> case ClassWriter.CLASS: >> String s = readUTF8(index, buf); >> return Type.getType(s.charAt(0) == '[' ? s : "L" + s + >> ";"); >> // case ClassWriter.STR: >> default: >> return readUTF8(index, buf); >> } >> } >> where line 1591 is return new Integer(readInt(index)); >> >> - >> - >> - >> org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2038) >> is a big method, where line 2038 looks inconspicuously like: >> >> if (!hooks.isEmpty()) >> >> >> Gogo and Retrotranslator are red herrings, without them in the application >> the deadlock just happens somewhere else. >> >> I don't even vaguely understand how, but neither Eclipse nor Knopflerfish >> suffer from this problem. I would, however, much rather use Felix. >> >> Please let me know if there's any further information I can provide. >> >> Best, Dan. >> >> >> >> >> >> > > > -- > Karl Pauls > [email protected] > http://twitter.com/karlpauls > http://www.linkedin.com/in/karlpauls > https://profiles.google.com/karlpauls
