BJ Hargrave wrote:
> Tim Ellison <[EMAIL PROTECTED]> wrote on 2006-01-04 12:00:34 PM:
>
>
>>BJ Hargrave wrote:
>>
>>>Native code loading is associated with both (a) the class loader and
>
> (b)
>
>>>the absolute file name. The class loader gets to map the requested lib
>
>
>>>name onto an absolute file name via a call made to
>>>ClassLoader.findLibrary.
>>
>>Cool, that's what I was thinking.
>>
>>
>>>The OSGi framework must process the
>>>Bundle-NativeCode header to make the selected libraries available at
>
> some
>
>>>bundle unique location so that if each bundle contains libfoo.so, the
>>>absolute path for each bundle's libfoo.so is unique.
>>
>>Not only path, but also filename I would assume, right?
>>On windows a call to LoadLibrary with \\foo\mylib.dll followed by a call
>>to LoadLibrary with \\bar\mylib.dll will simply result in reloading
>>\\foo\mylib.dll. So will the framework mange the filename too to allow
>>for multiple versions of my bundle's natives to be active concurrently?
>
> Well the typicall usage is System.loadLibrary("mylib"). The VM will then
> call ClassLoader.findLibrary("mylib"). The implementation of findLibrary
> will call System.mapLibraryName("mylib") which will return mylib.dll for
> Windows or libmylib.so for unix flavors, etc. The implementation will then
> take the mapped name and look for the native lib in the place where the
> framework impl stashed the native libs selected by the Bundle-NativeCode
> header.
>
> It will also attempt to find the unmapped name if the mapped name cannot
> be found to compensate for folks who did not properly name things :-)
Understood. My observation was that, AIUI, the stashed file basename
has to be different too, as described in the response to Richard.
>>>Furthermore, the VM only allows a native library at a given absolute
>
> path
>
>>>to be loaded only once. This is why the OSGi framework must make sure
>
> that
>
>>>bundles have unique locations for their native libs. It also means
>
> that
>
>>>the each revision of a bundle (for this discussion, when a bundle is
>>>updated you have a new revision) needs to place its native libs in a
>>>unique location. However, we are still left with some issues around
>>>refreshPackages which results in a new class loader for the bundle but
>
>
>>>does not change the absolute paths of the bundle native libs.
>>>
>>>For more details read section 3.9 (and 3.9.1 in particular) of the R4
>
> Core
>
>>>spec.
>>
>>I've read it, but it's not as clear as the explanation you just gave :-)
>>Thanks.
>>
>>As a bonus question: Is there any support for native to native calls?
>>Assume I have a bundle that only contains library files, with a manifest
>>to get the platform deploy right, versioning etc.. As I've now learnt,
>>the framework will put the right library into some unique location that
>>I'm not privy to; so I assume I can *only* load it via the framework
>>(System.loadLibrary()) by calling back into java :-( , and then I need
>>to get a handle to that library instance so I can GetProcAddress/dlsym a
>>function in that library, and of course there is no API way to get that
>>handle :-( . Is that right, am I out of luck for native->native calls
>>between bundles?
>
> There is no specific support within the framework, but you can deal with
> this from the Java code. Let me give a specific example using IBM DB2e (an
> embedded database). The db engine is a native lib ("db2e"). The JDBC code
> is another native lib containing JNI ("db2ejdbc"). When packaged in a
> bundle, the bundle needs to access the JNI code so it must do
> System.loadLibrary("db2ejdbc"). But the JNI native lib has native links to
> the db engine native code. To work with this, the bundle must first call
> System.loadLibrary("db2e") before calling System.loadLibrary("db2ejdbc").
> The VM will load the db engine into the process before the JNI lib so when
> the JNI lib needs to access the db engine code, it is already loaded. (I
> have no idea how this technique will respond under bundle updates/etc.
> since the reference from the JNI lib to the db engine is outside the
> naming influence of the java runtime.)
But in this example the "db2e" is not under version control, so multiple
concurrently active versions of the "db2ejdbc" bundle are required to
agree on a common db2e library.
Even if you put the db2e code into it's own bundle, you couldn't
differentiate between the two versions when making a C call from db2jdbc
to db2e (because you can't get a handle to the library version you want)
unless you rely upon the loadLibrary() call to open the library for you.
I think the moral to this story is that the bundle versioning bottoms
out at the loadLibrary() call, beyond that you should probably revert to
deploying the platform libraries outside the framework, and using the
platform's version control where it exists.
Regards,
Tim
--
Tim Ellison ([EMAIL PROTECTED])
IBM Java technology centre, UK.