[prev in list] [next in list] [prev in thread] [next in thread] 

List:       rxtx
Subject:    Re: [Rxtx] resource management, do we need a new approach?
From:       Trent Jarvi <tjarvi () qbang ! org>
Date:       2012-06-09 20:51:45
Message-ID: alpine.LFD.2.00.1206091433090.23689 () rxtx ! qbang ! org
[Download RAW message or body]



On Sat, 9 Jun 2012, Dr. Douglas Lyon wrote:

> Hi All,
> Loading native methods from Jars is a typical approach
> for RXTX loads...but there are others, including running
> installers, beaming files over, etc.
>
> Beaming over files requires a network connection and known locations
> of files whose versions are stable. Lots of assumptions there.
>
> Jar file dependence for web start requires common updated
> certificate signing, updated jars, correct version of byte codes, etc.
>
> Even more assumptions!
>
> If there is reliance upon an environment variable; java.library.path,
> for example, you have a fruitful source of bugs in configuration.
>
> What to do?
>
> Here is a new twist on an old problem...convert the binary
> to UUEncoded strings and embed it in the source code...Oh, better
> hide your eyes, this code is a little Ugly...and in prototype...and
> not well tested...oh, and did I mention ugly?
>
> For example:
> public class NativeLibs {
>    static String librxtxSerialDotsoName = "librxtxSerial.so";
>    static String librxtxSerialDotso =
>
> "H4sIAAAAAAAAAO19DXRURdJoJwQJEJ2AqKgoI4KCQggR/wAlhAwQTWAMiaKiw5CZZAa
> SmXF+" +
>
> "IFGCwUncjEMEFRRdVFRUVnFFRRcVNCAKuqgRUXEXNbpRb0yUqFk3Km5eVXX
>
> ...65 lines later, you have UUEncoded your binary files for 32 bit ELF unix.
> Hmm. Binary files in strings...uhh, why do that? "I hear you ask..."...
>
> Now you can control what you load, when you load it and which version you 
> load.
> And loading can be FAST and well understood, even on platforms you
> don't control.
>
> Imagine you have a version that uses lock files and another that doesn't
> (yeah, that can happen!). Which one will you use? Now you can test
> both. Need to unload that native library to go try another?
> Instance a new class loader (sweet!).
> The key element here is that regression testing of multiple versions
> becomes just a little easier (but still not easy!).
>
> To encode such things, I use:
>  public static void writeLibrary() throws IOException {
>        ByteArrayOutputStream baos = new ByteArrayOutputStream();
>        ObjectOutputStream oos = new ObjectOutputStream(baos);
>        oos.writeObject(Base64.decodeToObject(librxtxSerialDotso));
>        oos.close();
>
> Futil.writeBytes(NativeLibraryManager.getNativeLibraryFile("rxtxSerial")
> , baos.toByteArray());
>    }
>
> I used a similar approach for icons, at:
> http://show.docjava.com/pub/document/jot/resource.pdf
>
> Stable code, no signing, no worries about network availability. You just need
> a larger set of class files...Base 64 code is not very compact....but Jar 
> compression
> should take care of that. Oh, and the binary for the 32 ELF, with UUEncoding
> came to about 65 lines, total. So it really was not that big anyways.
>
> So, I figure, the byte codes get loaded all at once...but perhaps it is pay 
> now
> or pay later. Anyways, I think my approach might have fewer configurations 
> issues,
> and therefore might be more reliable....in theory.
>

Hi Dr Lyon,

Interesting.  This does offer the possibility of making the process of 
finding a desired shared library more robust by eliminating the need to 
understand how rxtx is hunting for libraries on the file system.

Does the solution then write the library to a temporary directory and call 
System.load when the library is needed?  I can see how icons could avoid 
that step with byte streams but have not seen a like solution for loading 
native libraries into memory without first creating a file.

If I understand right, this solves the first half of the problematic code 
we are currently looking at which is along these lines:

 	/* libTmpFile ~= /tmp/rxtx-13254/librxtxSerial.so */

     	try {
             	libTmpOutputStream = new FileOutputStream(libTmpFile);
             	byte[] buffer = new byte[65536];
             	while (true) {
Change source ==>       int read = libInputStream.read(buffer);
                     	if (read > 0) {
Still ugly here ==>             libTmpOutputStream.write(buffer, 0, read);
                     	} else {
                             	break;
                     	}
             	}
     	} catch (Exception e) { }

...

 	System.load(libTmpFile.getAbsolutePath()); /* no work around */


--
Trent Jarvi
tjarvi@qbang.org
_______________________________________________
Rxtx mailing list
Rxtx@qbang.org
http://mailman.qbang.org/mailman/listinfo/rxtx
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic