On 1/2/11 20:03, Bjorn Roche wrote:
On Dec 31, 2010, at 12:26 PM, Richard S. Hall wrote:
On 12/31/10 11:28, Bjorn Roche wrote:
On Dec 30, 2010, at 2:51 PM, Richard S. Hall wrote:
On 12/30/10 14:41, Bjorn Roche wrote:
On Dec 28, 2010, at 4:54 PM, Richard S. Hall wrote:
On 12/28/10 13:58, Bjorn Roche wrote:
On Dec 28, 2010, at 12:24 PM, Richard S. Hall wrote:
That's gotten me some distance. The app actually launches to a
point. I'm still having two problems, though:
A. My app won't load any JNI stuff no matter what I do.
B. Putting that aside, I get this error:
Caused by: java.lang.NoClassDefFoundError:
com/apple/eawt/ApplicationListener
I don't know about this either. There are some issues with Java
and the Mac Java GUI implementation, something about needing to
use the right thread or something. Maybe it is related...
Hmmm, well I'd love to know what that is exactly, otherwise I
may be SOL. In the meantime, I will try the "exploded bundle"
thing and see if that works any better.
Yeah, maybe someone else knows more.
-> richard
Okay, so I tried your suggestion of building using the exploded
bundle. It works about as well as the "assembly:" and "wrap:"
trick, and both techniques seem to have their pros and cons. I got
stuck at the same point: java.lang.NoClassDefFoundError:
com/apple/eawt/ApplicationListener
To belabor the point, here's the code that failed:
if (os == MAC_OS_X) {
try {
Class<?> osxAdapter =
ResourceUtil.getClass(app,"xowave.util.OSXAdapter");
Class<?>[] defArgs = { OSXApp.class };
Constructor<?> constructor =
osxAdapter.getConstructor(defArgs);
if (constructor != null) {
Object[] args = { app };
constructor.newInstance(args);
}
} catch (Exception e) {
...
}
Now xowave.util.OSXAdapter implements
com.apple.eawt.ApplicationListener, which is only available on mac
OS X, so if the class were loaded directly, it would cause
class-loading problems on non-OSX platforms, so I added the
dynamic loading code. (I don't recall if this is exactly the
approach recommended by apple, but something like it.)
And your bundle imports the "xowave.util" package?
xowave.util is part of the bundle.
Does the mentioned class have a direct dependency on
com.apple.eawt.ApplicationListener? If so, is the bundle importing
that package?
I was able to get around this by following Richard's hunch: I
simply by putting the above code in the swing thread with a call
to SwingUtilities.invokeLater().
This strikes me as a bug in OSGi because I should not need to be
in a particular thread to implement an interface no matter what
the interface is.
I don't know if this is the issue, but if it is, the way I
understood it, it is a limitation of the Mac implementation of AWT
or something.
It works fine outside of OSGi.
That's doesn't mean that it isn't a Mac implementation issue. I'm not
saying it is or it isn't, though. Here is one example:
http://www.eclipsezone.com/eclipse/forums/m92141277.html
I am still stuck loading native code, though. I added this to my
MANIFEST.MF:
Bundle-NativeCode: native/libXOengine-DOUBLE.jnilib ;
native/libXOengine-FLOAT.jnilib ; native/libquaqua.jnilib ;
processor=x86 ;
processor=ppc ;
osname=mac os x
where the paths are relative to my bundle. I have some indication
that this is correct because if I deliberately type change
something I get
Native library does not exist
or
No matching native libraries found.
but when my code calls
System.loadLibrary( "XOengine-FLOAT" );
I get
Caused by: java.lang.UnsatisfiedLinkError: no XOengine-FLOAT in
java.library.path
Not sure. It should work. If you can create a simple bundle that
fails, I can try it, since I work on a Mac. Send it to me privately.
If I can reproduce on a small scale, I will, thank you. In the
meantime, I just noticed I am getting this, apparently from felix:
ERROR: Unable to create library directory.
What's more, System.load() works, where System.loadLibrary fails.
Some googling suggested that the install name of the library might
be the issue, but I mucked with that without any luck.
Well, it should work. Let me know.
It's my understanding that java.library.path is not used -- at least
directly -- during normal Felix/OSGi operation, but I thought I'd see
what its value was right before calling System.loadLibrary to get a
hint. When I run my code outside of OSGi I get:
.:/Users/bjorn/Library/Java/Extensions:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
which seams reasonable. I use -Djava.library.path to set it to just
the path I care about with my native libs so that they will load, and
that's always worked.
Inside felix/OSGi, the same line of code gives:
:/usr/local/ImageMagick-6.3.9//lib:.:/Users/bjorn/Library/Java/Extensions:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
which seemed whack, at least the part before the what I get out of
OSGi. It turned out my .profile was setting that ImageMagick line,
and, moreover, it was totally bogus:
.profile:MAGICK_HOME="/usr/local/ImageMagick-6.3.9/" ; export MAGICK_HOME
arigato:~ bjorn$ grep MAGICK_HOME .*
.profile:MAGICK_HOME="/usr/local/ImageMagick-6.3.9/" ; export MAGICK_HOME
.profile:#MAGICK_HOME="/usr/local/" ; export MAGICK_HOME
.profile:PATH="$PATH:$MAGICK_HOME/bin:":~/bin: ; export PATH
.profile:DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:$MAGICK_HOME/lib" ;
export DYLD_LIBRARY_PATH
arigato:~ bjorn$ ls /usr/local/ImageMagick-6.3.9/
ls: /usr/local/ImageMagick-6.3.9/: No such file or directory
Once I removed that (I think this was from a failed gallery remote
install) and restarted my shell I got something reasonable out of
java.library.path, even inside OSGi:
.:/Users/bjorn/Library/Java/Extensions:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
Once that's fixed, I get a slightly different error when I run my app:
ERROR: Extracting native library. (java.io.FileNotFoundException:
./felix-cache/bundle3/version0.0/xowave-lib/0/native/libXOengine-FLOAT.jnilib
(No such file or directory))
java.io.FileNotFoundException:
./felix-cache/bundle3/version0.0/xowave-lib/0/native/libXOengine-FLOAT.jnilib
(No such file or directory)
java.io.FileNotFoundException:
./felix-cache/bundle3/version0.0/xowave-lib/0/native/libXOengine-FLOAT.jnilib
(No such file or directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
at java.io.FileOutputStream.<init>(FileOutputStream.java:131)
at
org.apache.felix.framework.util.SecureAction.getFileOutputStream(SecureAction.java:461)
at
org.apache.felix.framework.cache.BundleCache.copyStreamToFile(BundleCache.java:310)
at
org.apache.felix.framework.cache.DirectoryContent.getEntryAsNativeLibrary(DirectoryContent.java:266)
at
org.apache.felix.framework.ModuleImpl$ModuleClassLoader.findLibrary(ModuleImpl.java:2081)
After I did a little digging I found the directory tree it claimed to
be looking for (felix-cache/bundle3/version0.0/xowave-lib/0/native/),
but it wasn't in the current directory; it was in my home directory.
By deleting the caches directory and rerunning, I realized that felix
is building two caches every time I run it, one in my home dir and one
in the current dir. There seems to be some bug relating to this.
Setting the temporary dir explicitly to my home dir:
org.osgi.framework.storage=/Users/bjorn/felix-cache
works! Also works when I set the storage dir from the command line
rather than the conf file:
-Dorg.osgi.framework.storage=/tmp/$USER/felix-cache
Great, so I have a solution. Still, it seems there is a problem with
locating the cache dir (is it in the home dir or current dir?). Also,
it seems to me that even if a bogus path is added to
DYLD_LIBRARY_PATH, that shouldn't change anything.
If no cache directory is specified, the Felix framework will create a
"felix-cache" directory in the current directory (i.e., the directory
you are in when you launch the framework). So, if you are starting the
framework from different directories, you'll see it get created in
different places. I don't think there is any way a single execution of
the framework will create multiple copies of the cache.
Regarding the java.library.path, the framework doesn't look at this at
all. This should only impact the JVM. The only thing the framework does
is create a custom class loader that overrides findLibrary() and waits
for the JVM to call it when a class loaded by the class loader needs a
native library.
Other than that, I'm not sure what to tell you. Again, if you can get me
an example bundle and a set of steps to reproduce any issues you are
seeing, I'd gladly look into it.
-> richard
bjorn
-----------------------------
Bjorn Roche
http://www.xonami.com
Audio Collaboration
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]