Allowing Java-C++ interaction

Tyler Mandry tmandry at gmail.com
Thu Mar 29 23:56:53 UTC 2012


Hi BogDan,

Sorry for the really long delay, life has been crazy here, but I think I
should have time to update my patch this weekend. In the meantime, did you
do any work on this? I just don't want to be doing something you've already
done.

Thanks,
Tyler

On Thu, Feb 2, 2012 at 6:41 AM, BogDan <bog_dan_ro at yahoo.com> wrote:

> Hi,
>
>   I'm sorry I think I don't really understand you ... :) Android qt plugin
> is already loaded (before you application is loaded) and it will contain a
> simple function which does what you already did it, so I still don't see
> where is the problem here !
>
>   The only problem I see, is that we have to enforce that the main
> function will be exported properly, otherwise the symbol will be stripped
> away and the plugin will not find main function anymore, I'm thinking to
> use the same technique as I'm doing now (create another function which just
> calls the main function).
>
> Also, if possible, I'd like to have backward compatibility with alpha3.
>
> So if you have time for this job, please update your patch and upload it
> to https://git.reviewboard.kde.org/dashboard/ .
>
> Cheers,
> BogDan.
>
> >
>
> >
> >Hi BogDan,
> >
> >Sounds good. If the plugin can do it that's great. The only problem I see
> is that you'll have to load it manually, then call main, after which Qt
> will load the plugin "again." (This should actually work, and Qt will just
> get a reference to the already-loaded .so from dlopen. That's exactly how
> my main() function gets a reference to the application's .so.) Let me know
> if I can be of any help.
> >
> >
> >Cheers
> >Tyler
> >
> >
> >
> >On Wed, Feb 1, 2012 at 12:10 PM, BogDan <bog_dan_ro at yahoo.com> wrote:
> >
> >Hi Tyler,
> >>
> >>
> >>Ok, I'll review again your patch (I'd like to get rid of the new
> library, IMHO the plugin can do this job) then I'll push it to alpha4
> branch !
> >>
> >>
> >>
> >>Thank you !
> >>
> >>Cheers,
> >>BogDan.
> >>
> >>>
> >>> Here's what I got back:
> >>>Subject: Re: Native libraries loaded by different class loaders
> >>>>From: Elliott Hughes <e... at google.com>
> >>>>To: android-ndk <android-ndk at googlegroups.com>
> >>>>
> >>>
> >>>if you're calling dlopen(3) and dlsym(3) yourself, it doesn't matter
> >>>>what dlopen(3) or dlclose(3) calls the runtime's JNI implementation
> >>>>has or hasn't made, and ClassLoaders are irrelevant.
> >>>
> >>>
> >>>His point about dlopen and dlsym is true - if the JVM didn't load the
> library, it would be loaded anyway by the call to dlopen in android-main.
> "ClassLoaders are irrelevant" is the answer we were looking for, though.
> Since this guy's e-mail is @google.com I'd say we're in the clear!
> >>>
> >>>On Sat, Jan 28, 2012 at 9:59 PM, Tyler Mandry <tmandry at gmail.com>
> wrote:
> >>>
> >>>Done! https://groups.google.com/forum/#!topic/android-ndk/Z8GDn8JuopI
> >>>>
> >>>>
> >>>>
> >>>>On Fri, Jan 27, 2012 at 2:42 AM, BogDan <bog_dan_ro at yahoo.com> wrote:
> >>>>
> >>>>Hi Tyler,
> >>>>>
> >>>>>
> >>>>>
> >>>>>>
> >>>>>>Hi BogDan,
> >>>>>>
> >>>>>>
> >>>>>>Good point. I assume you are referring to native libraries being
> able to access other native libraries loaded by different class loaders in
> Java?
> >>>>>
> >>>>>
> >>>>>Yes !
> >>>>>
> >>>>>
> >>>>>
> >>>>>> If so, we should ask about it, but I really don't think it would
> break. It's pretty low-level stuff that allows dynamically-linked code to
> be found, used, and reused within a process. So breaking this would mean
> changing the OS/kernel itself in a non-standards-compliant way (unlikely.)
> Or the JVM somehow splitting our single application/activity into more than
> one process, which is also unlikely and would contradict some of the
> documentation for Activity (thus breaking other apps.) If there are other
> ways it could break, I don't see them.
> >>>>>>
> >>>>>
> >>>>>I also have doubts they can do it, but doesn't hurt to ask :)
> >>>>>
> >>>>>
> >>>>>
> >>>>>>
> >>>>>>That said, it's always a good idea to ask. Let me know if we're
> thinking of the same thing or not. I'm willing to post to android-ndk, but
> you're welcome to do it instead.
> >>>>>>
> >>>>>
> >>>>>Please post the question (and share with us the link :) ).
> >>>>>
> >>>>>
> >>>>>
> >>>>>>
> >>>>>>Have a great day!
> >>>>>>Tyler
> >>>>>>
> >>>>>
> >>>>>Cheers,
> >>>>>BogDan.
> >>>>>
> >>>>>
> >>>>>
> >>>>>>
> >>>>>>On Thu, Jan 26, 2012 at 2:48 AM, BogDan <bog_dan_ro at yahoo.com>
> wrote:
> >>>>>>
> >>>>>>Hi Tyler,
> >>>>>>>
> >>>>>>>
> >>>>>>>  The big question is if Google can change android in order to hide
> the symbols if they are loaded by different classloaders ?
> >>>>>>>
> >>>>>>>If they can't do it, I think your solution is ok, but if it is
> possible to do it, then we risk to break everyones applications !
> >>>>>>>
> >>>>>>>
> >>>>>>>  Before we make a decision I think we should ask google if they
> are planning to change current behavior or not. Do you want to open a topic
> to android-ndk[1] or should I do ?
> >>>>>>>
> >>>>>>>
> >>>>>>>Cheers,
> >>>>>>>BogDan.
> >>>>>>>
> >>>>>>>
> >>>>>>>[1] http://groups.google.com/group/android-ndk
> >>>>>>>
> >>>>>>>
> >>>>>>>>________________________________
> >>>>>>>> From: Tyler Mandry <tmandry at gmail.com>
> >>>>>>>>To: necessitas-devel at kde.org
> >>>>>>>>Sent: Monday, January 23, 2012 7:40 AM
> >>>>>>>>Subject: Allowing Java-C++ interaction
> >>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>This accidentally didn't get sent to the list; forwarding. Sorry
> about that.
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>---------- Forwarded message ----------
> >>>>>>>>From: Tyler Mandry <tmandry at gmail.com>
> >>>>>>>>Date: Tue, Jan 17, 2012 at 12:19 AM
> >>>>>>>>Subject: Re: Allowing Java-C++ interaction
> >>>>>>>>To: BogDan <bog_dan_ro at yahoo.com>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>Hi BogDan,
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>That definitely could work. But it does add to the complexity, and
> possibly start-up time, of the app. An alternative solution would be:
> simply to load the bundled libs in the main classloader, UNLESS they are
> bundled Qt libs that are used by the .jar, in which case they are loaded in
> the child CL. This could be accomplished by separating these two kinds of
> libs into different categories, or even auto-detecting them by their names
> at runtime. What do you think?
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>(One thing I've found: native libs loaded in different
> classloaders can always talk to each other, since they're part of the same
> process. In other words, you could load core Qt libs in the child CL and
> QtWebKit in the parent CL and it will all work. I don't know if this is
> useful but thought it might be.)
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>Thanks,
> >>>>>>>>Tyler
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>On Mon, Jan 16, 2012 at 2:22 AM, BogDan <bog_dan_ro at yahoo.com>
> wrote:
> >>>>>>>>
> >>>>>>>>Hi Tyler,
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>   Thanks you for sharing this with us, it helped me to
> understand better what is the problem.
> >>>>>>>>>I also check your patch [1] but it doesn't seem to fix all the
> problems, bundle libs will have the same problem, so I tried to find
> another solution which hopefully will handle all this situations. The
> solution is create a separate package with your own java files, and this
> package to be loaded by the same class loaded which loads the plugin .jar
> files.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>Please let me know if this approach is ok for you.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>Cheers,
> >>>>>>>>>BogDan.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>[1] http://sourceforge.net/p/necessitas/tickets/140/
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>>________________________________
> >>>>>>>>>> From: Tyler Mandry <tmandry at gmail.com>
> >>>>>>>>>>To: BogDan <bog_dan_ro at yahoo.com>
> >>>>>>>>>>Sent: Friday, January 13, 2012 6:43 AM
> >>>>>>>>>>Subject: Re: Allowing Java-C++ interaction
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>Hi BogDan,
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>What currently happens is the native library is loaded in the
> child class loader (by the code in the .jar, in fact,) so application code
> (loaded by the parent class loader) can't see any native functions loaded
> by the native library. And no, I don't try to access anything in the .jar
> in my application.
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>I did make a simple testcase that fails before the patch and
> works after. Since the patch involves changing QtActivity.java, it's
> difficult to send a complete project and see the before and after. Instead,
> do the following:
> >>>>>>>>>>    1. Create a new Qt Quick Application project in Qt Creator,
> with an Android target
> >>>>>>>>>>    2. (i) Replace main.cpp with the attached main.cpp, and (ii)
> add in the Java source to the tree (copy the
> android/src/org/kde/necessitas/example folder in attached archive to
> android/src/org/kde/necessitas in the project)
> >>>>>>>>>>    3. Go to QtActivity.java and add (i) "import
> org.kde.necessitas.example.simpleapp.MyNative;" at the top, and (ii) the
> following at the END of loadApplication():
> >>>>>>>
> >>>>>>>>>>//dostuffafter loading
> >>>>>>>>>>MyNativenat=newMyNative();
> >>>>>>>>>>nat.doSomething();
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>[Modifying QtActivity.java is currently the only way I know to
> run your own Java code as the application loads.]
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>After that, run the project and you should see "No
> implementation found for native
> Lorg/kde/necessitas/example/simpleapp/MyNative;.doSomething ()V" along with
> an UnsatisfiedLinkError in the log.
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>Then point Qt Creator to a build of Qt with the patch and do the
> process again with that version of Qt. (**Of course you'll need to deploy
> and use local Qt libs!**) You should see "This is a native function, doing
> something!!" in the logs, and no crash.
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>I hope this is clear enough and that it sheds some light on what
> I'm trying to accomplish :). Let me know if anything is unclear.
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>Thanks for all your hard work!!
> >>>>>>>>>>Tyler
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>On Thu, Jan 12, 2012 at 8:46 AM, BogDan <bog_dan_ro at yahoo.com>
> wrote:
> >>>>>>>>>>
> >>>>>>>>>>Hi Tyler,
> >>>>>>>>>>>
> >>>>>>>>>>>    I reviewed my code and seems to be ok, when I create
> m_classLoader (check QtActivity.java) I pass its parent correctly, so, even
> if your library is loaded by a class which was loaded by m_classLoader and
> there your package is not visible, m_classLoader should search also into
> its parent for that class.
> >>>>>>>>>>>
> >>>>>>>>>>>    I hope your package don't try to access classes from .jar
> file, because those classes are private, and they should be used *ONLY* by
> platform plugin.
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>Would you please create a simple example which fails, it will
> help me to understand the problem better ?
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>Thank you !
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>Cheers,
> >>>>>>>>>>>BogDan.
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>+ CC: necessitas-devel
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>Hi BogDan,
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>No worries, I just didn't want it to be overlooked :)
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>In a nutshell, any (user) Java code the application had
> couldn't see the user's native JNI code, because their native library was
> loaded in a class loader that was different from the (primary) class loader
> that their Java code ran in. This upset a few people that have custom Java
> and JNI code, like me :). The only way to make calls between different
> class loaders is to use reflection, so instead I made a way for the
> application native library to be loaded in the primary class loader.
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>That was a mouthful, but I hope it helps. Let me know if you
> have further questions!
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>Thanks,
> >>>>>>>>>>>>Tyler
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>On Tue, Jan 10, 2012 at 1:49 PM, BogDan <bog_dan_ro at yahoo.com>
> wrote:
> >>>>>>>>>>>>
> >>>>>>>>>>>>Hi Tyler,
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>Please accept my apologize for slow reply.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>I need a few days to understand what is wrong with current
> design and to check your patch, then I'll come back with feedback !
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>Thank you very much for your patience !
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>Cheers,
> >>>>>>>>>>>>>BogDan.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>BogDan,
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>Do you think this patch can be included in the next alpha?
> If not, what needs to be done?
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>Thanks,
> >>>>>>>>>>>>>>Tyler
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>On Thu, Dec 29, 2011 at 12:48 AM, Tyler Mandry <
> tmandry at gmail.com> wrote:
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>Here is the patch (against alpha4 head 2469081) to make
> everything work. I've tested and it works. The basic approach is to compile
> qtmain_android.cpp into its own .so during Qt compilation, and load it in
> the application. It uses dynamic linker calls to find the main() function
> at runtime. So there is no awkward back-and-forth library loading needed
> after all.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>Backward compatibility: I made sure my changes to the JAR
> allowed it to still work with existing built applications as-is, and light
> testing confirms that it is. This required a few extra lines that are
> marked as such in case you want to remove them.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>I didn't touch Ministro, however, and I suspect that my
> addition to lib/rules.xml will cause new versions of Ministro to try to
> load libqtmain.so, which won't exist in old/current applications. I'll
> leave that issue for someone more familiar with Ministro to look at, if
> it's a concern.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>Finally, I mentioned creating a new category of
> user-defined bundled libs in case the user wants to use JNI with those
> libs, but did not implement that.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>I hope you like it and that it can be included in the next
> alpha. Let me know if you have any questions or comments :)
> >>>>>>>>>>>>>>>Tyler
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>On Sat, Dec 24, 2011 at 11:28 PM, Tyler Mandry <
> tmandry at gmail.com> wrote:
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>BogDan,
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>Merry Christmas again! When you have time:
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>Separating out qtmain_android.cpp into its own shared lib
> allows us to build it during the Qt build rather than with the application
> projects. (We have to remove the --no-undefined linker option, but it
> works.) My question is, where should that library go in the Qt install? It
> isn't technically a Qt plugin, so I don't know about putting it with
> plugins, and lib/ is all official Qt libs. It fits in best with jar/, but
> then the directory name doesn't make sense :). We could also make another
> directory, though it seems unnecessary. I'll probably stick it in jar/
> unless I hear from you.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>I've proved that this method works, and now I'm just
> working on integrating all the changes in code.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>Cheers,
> >>>>>>>>>>>>>>>>Tyler
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>On Fri, Dec 23, 2011 at 2:14 AM, Tyler Mandry <
> tmandry at gmail.com> wrote:
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>One thing I've encountered: If I'm not mistaken, people
> can/will use bundled libraries to bundle Qt libraries along with their
> application (to bypass Ministro.) Others will use bundled libs of their own
> for other purposes. We will want to load the Qt bundled libs inside the
> child class loader, so our JAR can talk to them, and the other bundled libs
> inside the main Java class loader, in case they want to interact with those
> native bundled libs via JNI. This will require us to make a new distinction
> on the type of bundled library.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>Other thoughts: I've been looking and it looks like this
> isn't a difficult change to make. It's very minimal in the way it changes
> how things are done right now. It does require a change to the JAR files to
> accomodate for that back-and-forth lib loading that I described. Anyway, I
> plan to implement all this tomorrow and see how it goes.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>On Thu, Dec 22, 2011 at 8:51 PM, Tyler Mandry <
> tmandry at gmail.com> wrote:
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>Hi all, and Merry Christmas.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>We were discussing the importance of allowing Java and
> C++ to interact for many people's apps in android-qt (thread: C++ and Java
> interaction in Alpha3.) With the new separation of the JAR files, and use
> of a different class loader for the app code, it has become very difficult
> to allow this. Traditional native interface classes can no longer see the
> native methods that are loaded by the separate class loader.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>I did some playing around, and I think I found a simple
> solution that works. If we separate out the code in qtmain_android.cpp into
> its own (very small!) shared library, and allow the user's application code
> to be in one library all by itself, we can load them in separate class
> loaders. While you can't do Java-Java or Java-native interaction easily
> across the class loader barrier, native-native interaction works fine since
> it's all the same process. Simply load the Qt library in the /child/ class
> loader, followed by the application code library in the /main/ class
> loader, followed by the qtmain_android code in the /child/ class loader.
> Then the user's Java code can see the user's C++ code and vice versa,
> because they are all loaded under the same class loader.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>I did a testcase of this (with libraries of my own, not
> Qt) and confirmed that it works in a simple case. If no one sees any
> problems with this let's implement it.
> >>>>>>>>>>>>>>>>>>--
> >>>>>>>>>>>>>>>>>>Tyler Mandry
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>--
> >>>>>>>>>>>>>>>>>Tyler Mandry
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>--
> >>>>>>>>>>>>>>>Tyler Mandry
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>--
> >>>>>>>>>>>>>>Tyler Mandry
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>--
> >>>>>>>>>>>>Tyler Mandry
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>--
> >>>>>>>>Tyler Mandry
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>--
> >>>>>>>>Tyler Mandry
> >>>>>>>>
> >>>>>>>>_______________________________________________
> >>>>>>>>Necessitas-devel mailing list
> >>>>>>>>Necessitas-devel at kde.org
> >>>>>>>>https://mail.kde.org/mailman/listinfo/necessitas-devel
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>--
> >>>>>>Tyler Mandry
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>>>
> >>>>
> >>>>--
> >>>>Tyler Mandry
> >>>>
> >>>
> >>>
> >>>
> >>>--
> >>>Tyler Mandry
> >>>
> >>>
> >>>
> >>
> >
> >
> >
> >--
> >Tyler Mandry
> >
> >
> >
>



-- 
Tyler Mandry
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/necessitas-devel/attachments/20120329/e4fb524c/attachment-0001.html>


More information about the Necessitas-devel mailing list