On 1/3/11 9:51, Bjorn Roche wrote:
On Jan 2, 2011, at 10:58 PM, Richard S. Hall wrote:
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.
when I ran felix, it would create cache directories in both my home
and current directories. I verified this by deleting "felix-cache" in
both the current and home dir, running felix once, and locating these
directories again. It built the
felix-cache/bundle3/version0.0/xowave-lib/0/native/ tree in my home
directory, but then complained that it couldn't find it. It put
everything else in the current directory. The solution to this issue
seemed to be to specify the org.osgi.framework.storage variable from
the command line rather than the configuration file, but I'm not
really sure.
Maybe this is a bug in the code to support "exploded bundles". Can you
create a test case (framework configuration and/or bundle) that
demonstrates this? If so, open a bug an submit it.
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.
I'm not really sure what the issue here was -- I only used
java.library.path to discover what was going on and it may only have
been related incidentally. Perhaps the issue has to do with the
$DYLD_LIBRARY_PATH variable -- it must at least indirectly since
that's what I changed to get it working.
Maybe, but I'm not sure how it would impact the framework, since it
never consults it.
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.
I will see what I can do.
Thanks!
-> richard
bjorn
-----------------------------
Bjorn Roche
http://www.xonami.com
Audio Collaboration
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]